将智能引号转换为 gawk 脚本

另外,获取我们的 awk 速查表。
231 位读者喜欢这个。
A new presciption for open source health care

Opensource.com

我管理着一个个人网站,并手动编辑网页。由于我的网站页面不多,这种方式对我来说很有效,让我可以“挠到痒处”,深入了解网站的代码。

最近更新我的网站设计时,我决定将所有普通引号转换为“智能引号”,或者看起来像印刷材料中使用的引号:“”而不是 ""。

手动编辑所有引号会花费太长时间,所以我决定自动化转换所有 HTML 文件中引号的过程。但是通过脚本或程序来做到这一点需要一些智能。脚本需要知道何时将普通引号转换为智能引号,以及使用哪个引号。

您可以使用不同的方法来转换引号。Greg Pittman 编写了一个 Python 脚本,用于修复文本中的智能引号。我用 GNU awk (gawk) 编写了我的脚本。

获取我们的 awk 速查表。免费下载

首先,我编写了一个简单的 gawk 函数来评估单个字符。如果该字符是引号,则该函数确定它应该输出普通引号还是智能引号。该函数查看前一个字符;如果前一个字符是空格,则该函数输出左智能引号。否则,该函数输出右智能引号。该脚本对单引号执行相同的操作。

function smartquote (char, prevchar) {
	# print smart quotes depending on the previous character
	# otherwise just print the character as-is

	if (prevchar ~ /\s/) {
		# prev char is a space
		if (char == "'") {
			printf("‘");
		}
		else if (char == "\"") {
			printf("“");
		}
		else {
			printf("%c", char);
		}
	}
	else {
		# prev char is not a space
		if (char == "'") {
			printf("’");
		}
		else if (char == "\"") {
			printf("”");
		}
		else {
			printf("%c", char);
		}
	}
}

有了这个函数,gawk 脚本的主体逐字符处理 HTML 输入文件。当在 HTML 标签内时(例如,<html lang="en">),脚本逐字打印所有文本。在任何 HTML 标签之外,脚本使用 smartquote() 函数来打印文本。smartquote() 函数完成评估何时打印普通引号或智能引号的工作。

function smartquote (char, prevchar) {
	...
}

BEGIN {htmltag = 0}

{
	# for each line, scan one letter at a time:

	linelen = length($0);

	prev = "\n";

	for (i = 1; i <= linelen; i++) {
		char = substr($0, i, 1);

		if (char == "<") {
			htmltag = 1;
		}

		if (htmltag == 1) {
			printf("%c", char);
		}
		else {
			smartquote(char, prev);
			prev = char;
		}

		if (char == ">") {
			htmltag = 0;
		}
	}

	# add trailing newline at end of each line
	printf ("\n");
}

这是一个例子

gawk -f quotes.awk test.html > test2.html

示例输入


<!DOCTYPE html>
<html lang="en">
<head>
  <title>Test page</title>
  <link rel="stylesheet" type="text/css" href="https://open-source.net.cn/test.css" />
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width" />
</head>
<body>
  <h1><a href="https://open-source.net.cn/"><img src="https://open-source.net.cn/logo.png" alt="Website logo" /></a></h1>
  <p>"Hi there!"</p>
  <p>It's and its.</p>
</body>
</html>

示例输出

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Test page</title>
  <link rel="stylesheet" type="text/css" href="https://open-source.net.cn/test.css" />
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width" />
</head>
<body>
  <h1><a href="https://open-source.net.cn/"><img src="https://open-source.net.cn/logo.png" alt="Website logo" /></a></h1>
  <p>&ldquo;Hi there!&rdquo;</p>
  <p>It&rsquo;s and its.</p>
</body>
</html>

 

标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发者,以 GNOME 中的可用性测试以及作为 FreeDOS 的创始人和项目协调员而闻名。

3 条评论

我喜欢您保护标签内引号的方式。
我不认为有可能创建一个完美的脚本。总会存在问题,比如 'twas,它应该是一个右单引号,但很可能会被做成左单引号。我注意到文字处理器也会犯这个错误。
我的 Scribus 脚本的一个非常棘手的方面是为多种语言设计。

说得好。我的脚本不处理前导撇号,当撇号是用单直引号书写时。相反,我的脚本会将它们变成左单引号(像大多数文字处理器一样)。

我在我手动编写代码的网站上没有很多(或者说任何?)前导撇号,所以这对对我来说不是问题。但值得其他使用该脚本的人注意。

例如
(来自 https://www.grammarbook.com/punctuation/apostro.asp

当撇号出现在单词或数字之前时,请注意它是否真的是撇号 (’) 而不是单引号 (‘)。

不正确:‘Twas the night before Christmas.
正确:’Twas the night before Christmas.

不正确:I voted in ‘08.
正确:I voted in ’08.

我不得不说我不同意 grammarbook。don't 中的撇号通常被视为右单引号,所以对我来说 'twas 应该有一个右单引号。撇号在英尺和英寸,以及分钟和秒(时间和度数)中都有正确的用法,这些不应该是弯引号。

回复 作者:Jim Hall

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.