大约六年前,我们在 Scribus 邮件列表中收到一个问题,有人想知道是否有自动方法将打字机引号转换为印刷体引号。如果您不知道这意味着什么,印刷体引号(例如,“ 和 ”)有时被称为弯引号,而不是打字机上的不正确版本(即 ")。键盘上的引号可以很好地用作英尺或英寸,或分钟和秒的缩写,但在大多数情况下,您真的希望在文本中使用弯引号。(编者注:Opensource.com 的风格是在可能的情况下使用直引号。)
尽管大多数文字处理器都会自动将打字机引号替换为印刷体引号,但 Scribus 没有内置此功能。这对我来说似乎是一个有趣的脚本编写挑战,所以我接受了它。这促成了一个脚本,一个 引号转换 Wiki 页面,最终该脚本(名为 Autoquote)被认为足够有用,可以包含在 Scribus 软件包中。(在本文底部找到 Autoquote 的当前版本。)从那时起,我们对一个名为 Autoquote2 的版本进行了增强,该版本也包含在 Scribus 中。这个版本有一个用于法语对话框的选项,并努力在引号和文本之间添加空格(就像法语中那样)。
这个想法很简单,一般来说,如果这些符号之一跟在空格后面,或者在段落的开头,并且后面跟着某种字符,那么它应该是左引号,而大多数情况下,右引号后面跟着一个空格,或者在段落的末尾。但是,您会遇到诸如缩略词之类的词,例如 “aren’t”,以及 “’嵌套’ 引号” 呢?(例如,LibreOffice 在处理嵌套引号时会出错,但 Autoquote 可以正确处理。)最后,印刷体引号在所有语言中都不相同。法语和俄语使用尖引号 («»),其他语言则以不同的方式放置引号——在某些情况下,这些是不同的字形(例如 ˛’ 或 „“)。实际上,变体之多令人惊叹。
您在脚本的早期看到的是,您需要告诉脚本您正在使用的语言
lang = scribus.valueDialog("Choose by language or country", 'Language: af, be, ch, cs, de, en, es, et, fi, fr,\n hu, is, lt, mk, nl, pl, ru, se, sk, sl, sq and uk\n are current choices','en')
之后是一个长长的赋值列表,例如
if (lang == 'en'):
lead_double = u"\u201c"
follow_double = u"\u201d"
lead_single = u"\u2018"
follow_single = u"\u2019"
elif (lang == 'de'):
lead_double = u"\u201e"
follow_double = u"\u201c"
lead_single = u"\u2019"
follow_single = u"\u201a"
elif (lang == 'fr'):
lead_double = u"\u00ab"
follow_double = u"\u00bb"
lead_single = u"\u2018"
follow_single = u"\u2019"
这会为前导或后继引号的替换分配正确的 Unicode 字符。 之后,脚本就可以开始工作了,它通过解析所选文本框的整个文本来完成,解析意味着逐字符分析文本。 另一个复杂之处在于,当您查看 Scribus 文档时,您看不到许多字符。 您实际上看不到回车符,但它在那里。 此外,还有用于更改字符或段落样式的控制字符,您不希望在此过程中搞乱它们。 就任何引号分配方案而言,您必须忽略这些字符,但您需要保持它们不变。 如果您使用 Python 命令 len 检查这些字符,您会发现它们的长度为 0,这就是我们找到它们的方式。
如果还不清楚,那么脚本所做的就是逐字符分解文本框的内容,然后根据需要更改打字机单引号和双引号,重建框架的内容。 在 Wiki 页面上,您可以看到这种逻辑是如何发挥作用的。
脚本中有一个缺陷,我还没有弄清楚其中的逻辑——即在单词开头有缩略形式的情况(例如,‘twas)。 即使在 LibreOffice 中,这也显示为左单引号,但应该像 ’twas 这样是右单引号。
这就是 Autoquote 脚本的由来。 我后来意识到,这种文本框解析过程也可以用于其他情况,我将在我的下一篇 Python 和 Scribus 文章中讨论。
Autoquote.py 脚本
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Autoquote.py - changes typewriter quotes to typographic quotes
# © 2010.08.28 Gregory Pittman
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
"""
USAGE
You must have a document open, and a text frame selected.
There will be a valueDialog asking for your language for the quotes,
the default is 'en', but change the default to suit your needs.
Detected errors shut down the script with an appropriate message.
"""
import scribus
if scribus.haveDoc() > 0:
c = 0
lang = scribus.valueDialog("Choose by language or country", 'Language: af, be, ch, cs, de, en, es, et, fi, fr,\n hu, is, lt, mk, nl, pl, ru, se, sk, sl, sq and uk\n are current choices','en')
if (lang == 'en'):
lead_double = u"\u201c"
follow_double = u"\u201d"
lead_single = u"\u2018"
follow_single = u"\u2019"
elif (lang == 'de'):
lead_double = u"\u201e"
follow_double = u"\u201c"
lead_single = u"\u2019"
follow_single = u"\u201a"
elif (lang == 'fr'):
lead_double = u"\u00ab"
follow_double = u"\u00bb"
lead_single = u"\u2018"
follow_single = u"\u2019" # am hoping this will cover contractions like je t'aime
elif (lang == 'pl'):
lead_double = u"\u201e"
follow_double = u"\u201d"
lead_single = u"\u201a"
follow_single = u"\u2019"
elif ((lang == 'se') or (lang == 'fi')):
lead_double = u"\u201d"
follow_double = u"\u201d"
lead_single = u"\u2019"
follow_single = u"\u2019"
elif (lang == 'af'):
lead_double = u"\u201c"
follow_double = u"\u201d"
lead_single = u"\u2018"
follow_single = u"\u2019"
elif (lang == 'sq'):
lead_double = u"\u201e"
follow_double = u"\u201c"
lead_single = u"\u2018"
follow_single = u"\u2019"
elif ((lang == 'be') or (lang == 'ch') or (lang == 'uk') or (lang == 'ru')):
lead_double = u"\u00ab"
follow_double = u"\u00bb"
lead_single = u"\u2039"
follow_single = u"\u203a"
elif (lang == 'uk'):
lead_double = u"\u00ab"
follow_double = u"\u00bb"
lead_single = u"\u2039"
follow_single = u"\u203a"
elif (lang == 'es'):
lead_double = u"\u00ab"
follow_double = u"\u00bb"
lead_single = u"\u2018"
follow_single = u"\u2019"
elif ((lang == 'lt') or (lang == 'is') or (lang == 'sk') or (lang == 'sl') or (lang == 'cs') or (lang == 'et')):
lead_double = u"\u201e"
follow_double = u"\u201c"
lead_single = u"\u201a"
follow_single = u"\u2018"
elif (lang == 'mk'):
lead_double = u"\u201e"
follow_double = u"\u201c"
lead_single = u"\u2019"
follow_single = u"\u2018"
elif ((lang == 'hu') or (lang == 'nl')):
lead_double = u"\u201e"
follow_double = u"\u201d"
lead_single = u"\u00bb"
follow_single = u"\u00ab"
else:
scribus.messageBox('Language Error', 'You need to choose an available language', scribus.ICON_WARNING, scribus.BUTTON_OK)
sys.exit(2)
else:
scribus.messageBox('Usage Error', 'You need a Document open', scribus.ICON_WARNING, scribus.BUTTON_OK)
sys.exit(2)
if scribus.selectionCount() == 0:
scribus.messageBox('Scribus - Usage Error',
"There is no object selected.\nPlease select a text frame and try again.",
scribus.ICON_WARNING, scribus.BUTTON_OK)
sys.exit(2)
if scribus.selectionCount() > 1:
scribus.messageBox('Scribus - Usage Error',
"You have more than one object selected.\nPlease select one text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
sys.exit(2)
textbox = scribus.getSelectedObject()
pageitems = scribus.getPageItems()
boxcount = 1
for item in pageitems:
if (item[0] == textbox):
if (item[1] != 4):
scribus.messageBox('Scribus - Usage Error', "This is not a textframe. Try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
sys.exit(2)
contents = scribus.getTextLength(textbox)
while c <= (contents -1):
if ((c + 1) > contents - 1):
nextchar = ' '
else:
scribus.selectText(c+1, 1, textbox)
nextchar = scribus.getText(textbox)
scribus.selectText(c, 1, textbox)
char = scribus.getText(textbox)
if (len(char) != 1):
c += 1
continue
if ((ord(char) == 34) and (c == 0)):
scribus.deleteText(textbox)
scribus.insertText(lead_double, c, textbox)
elif (ord(char) == 34):
if ((prevchar == '.') or (prevchar == ',') or (prevchar == '?') or (prevchar == '!')):
scribus.deleteText(textbox)
scribus.insertText(follow_double, c, textbox)
elif ((ord(prevchar) == 39) and ((nextchar != ' ') and (nextchar != ',') and (nextchar != '.'))):
scribus.deleteText(textbox)
scribus.insertText(lead_double, c, textbox)
elif ((nextchar == '.') or (nextchar == ',')):
scribus.deleteText(textbox)
scribus.insertText(follow_double, c, textbox)
elif ((prevchar == ' ') or ((nextchar != ' ') and (ord(nextchar) != 39))):
scribus.deleteText(textbox)
scribus.insertText(lead_double, c, textbox)
else:
scribus.deleteText(textbox)
scribus.insertText(follow_double, c, textbox)
if ((ord(char) == 39) and (c == 0)):
scribus.deleteText(textbox)
scribus.insertText(lead_single, c, textbox)
elif (ord(char) == 39):
if ((prevchar == '.') or (prevchar == ',') or (prevchar == '?') or (prevchar == '!')):
scribus.deleteText(textbox)
scribus.insertText(follow_single, c, textbox)
elif ((ord(prevchar) == 34) and ((nextchar != ' ') and (nextchar != ',') and (nextchar != '.'))):
scribus.deleteText(textbox)
scribus.insertText(lead_single, c, textbox)
elif ((prevchar != ' ') and (ord(prevchar) != 34) and (nextchar != ' ')):
scribus.deleteText(textbox)
scribus.insertText(follow_single, c, textbox)
elif ((prevchar == ' ') or ((nextchar != ' ') and (ord(nextchar) != 34))):
scribus.deleteText(textbox)
scribus.insertText(lead_single, c, textbox)
else:
scribus.deleteText(textbox)
scribus.insertText(follow_single, c, textbox)
c += 1
prevchar = char
scribus.setRedraw(1)
scribus.docChanged(1)
endmessage = 'Successfully ran script\n Last character read was '+str(char) # Change this message to your liking
scribus.messageBox("Finished", endmessage, icon=scribus.ICON_NONE, button1=scribus.BUTTON_OK)
评论已关闭。