One of my favourite tiny details in this website is my non-breaking spaces. I have code that looks for phrases like “5 cm”, “New York”, or “Objective‑C”, and inserts a non-breaking space/hyphen so they’ll never be split across multiple lines.
This is the sort of typographical nicety that would be handled by a professional typesetter if I was writing a printed book with a fixed layout, but that’s not how websites work. My website is viewed at lots of different sizes, and browsers choose where to insert line breaks. I add these non-breaking characters so browsers know to avoid awkward line breaks.
Previously I was only applying this detail to body text, but today I implemented something similar for <code> elements.
I used a lot of inline code snippets in my last post, and while reviewing it I noticed that several of those snippets had unhelpful line breaks. For example, (?-u:…) was split into (?- and u:…), while the flag --multiline was split with - on one line and -multiline on the other. These line breaks make the post harder to read, with no benefit.
I can understand why they happened – browsers look for characters where they can break lines, and in English that includes hyphens. It’s usually fine to split hyphenated words over multiple lines, but it’s annoying when that happens in code.
I could fix this by replacing the hyphen in my <code> with a non-breaking hyphen, but people copy/paste code snippets and that might change the meaning.
Instead, I wrote a check that looks for <code> elements which are short and contain a line-breaking character, then adds the nowrap CSS class.
import re
def add_nowrap(match: re.Match[str]) -> str:
"""
Add the `nowrap` class to a `<code>` element if it contains line
breaking characters.
"""
contents = match.group("contents")
if "-" in contents or " " in contents:
return f"<code class=\"nowrap\">{contents}</code>"
return match.group(0)
text: str
# Add the `nowrap` class to <code> snippets which are short and
# contain line-breaking characters.
#
# The limit of 15 characters is arbitrary. In longer code snippets,
# wrapping is preferable to avoid leaving excessive whitespace on
# the previous line.
text = re.sub(r"<code>(?P<contents>[^<]{1,15})</code>", add_nowrap, text)This is paired with a CSS rule that uses the text-wrap property to tell browsers not to wrap across lines:
code.nowrap {
text-wrap: nowrap;
}This wasn’t necessary, but I think it makes the site slightly nicer.
` 元素自动换行的文章。评论区主要围绕使用正则表达式解析 HTML 是否恰当展开了辩论。 虽然多位用户重申了编程界关于“正则表达式不适合解析 HTML”的经典名言,但也有人认为在特定情境下——尤其是开发者能够控制文档结构时——它依然是一种可行但并不完美的“最后手段”。一些参与者提出了更稳健的替代方案,例如使用专门的解析库(如 BeautifulSoup)或专用工具(如 `hxpipe`)。 讨论还涉及了文章目标的实际实现方式。评论者质疑作者为什么不在生成 HTML 时直接应用不换行样式或类注释,而非试图事后通过程序对代码进行处理。正如这类讨论中常见的,话题最后以对臭名昭著的“Zalgo”文本解析梗的幽默引用作为结语。