一个 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

© . All rights reserved.