1
1
#!/usr/bin/env python
2
2
# -*- coding: utf-8 -*-
3
# File: quotes.py - changes typewriter quotes to typographic quotes
3
# File: spacenquotes.py - changes typewriter quotes to typographic quotes with option to add spaces
4
4
# © 2010.08.28 Gregory Pittman
5
# © 2013.10.07 Enhancements by Jean-Luc Girard
5
6
# This program is free software; you can redistribute it and/or modify
6
7
# it under the terms of the GNU General Public License as published by
7
8
# the Free Software Foundation; either version 2 of the License, or
8
9
# (at your option) any later version.
12
Original script is quotes.py or autoquotes.py
14
The algorythm has been slightly changed for determining
15
whether a quote is opening or closing
16
+ it provides the choice for the type of space to add :
17
none or non breaking or thin or non breaking thin
18
+ spaces are only aded when not allready there...
19
+ a french version of the dialogs is included
21
choice to change the spaces for allready existing correct doublequotes
22
if 'none' is choosen, then existing spaces inside double quotes are deleted
23
+ take into account allready existing doublequotes for the correct choice open / close of next dquote
24
+ warning if some open/close unconsistency is detected
25
for example in « texte " suite »
28
- it only acts on the currently selected frame
29
(todo : acting on more than one selected frame,
30
or on whole chain of linked text frame would be nice).
31
- Spaces are not added outside of the quotes.
32
(that could be a job for another more general typographic tool)
35
download file, save it with 'quotenspace.py' name
12
39
You must have a document open, and a text frame selected.
13
There will be a valueDialog asking for your language for the quotes,
14
the default is 'en', but change the default to suit your needs.
40
Run script from scribus menu (Script > Run script...)
41
There will be a dialog asking for the language for the quotes,
15
42
Detected errors shut down the script with an appropriate message.
43
A dialog then asks what is your choice as for spaces.
44
Follow indications and answer 0, 1, 2 or 3
45
Another dialog asks wether you want the script to manage
46
existing correct doublequotes.
20
if scribus.haveDoc() > 0:
22
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')
24
lead_double = u"\u201c"
25
follow_double = u"\u201d"
26
lead_single = u"\u2018"
27
follow_single = u"\u2019"
29
lead_double = u"\u201e"
30
follow_double = u"\u201c"
31
lead_single = u"\u2019"
32
follow_single = u"\u201a"
34
lead_double = u"\u00ab"
35
follow_double = u"\u00bb"
36
lead_single = u"\u2018"
37
follow_single = u"\u2019" # am hoping this will cover contractions like je t'aime
39
lead_double = u"\u201e"
40
follow_double = u"\u201d"
41
lead_single = u"\u201a"
42
follow_single = u"\u2019"
43
elif ((lang == 'se') or (lang == 'fi')):
44
lead_double = u"\u201d"
45
follow_double = u"\u201d"
46
lead_single = u"\u2019"
47
follow_single = u"\u2019"
49
lead_double = u"\u201c"
50
follow_double = u"\u201d"
51
lead_single = u"\u2018"
52
follow_single = u"\u2019"
54
lead_double = u"\u201e"
55
follow_double = u"\u201c"
56
lead_single = u"\u2018"
57
follow_single = u"\u2019"
58
elif ((lang == 'be') or (lang == 'ch') or (lang == 'uk') or (lang == 'ru')):
59
lead_double = u"\u00ab"
60
follow_double = u"\u00bb"
61
lead_single = u"\u2039"
62
follow_single = u"\u203a"
64
lead_double = u"\u00ab"
65
follow_double = u"\u00bb"
66
lead_single = u"\u2039"
67
follow_single = u"\u203a"
69
lead_double = u"\u00ab"
70
follow_double = u"\u00bb"
71
follow_double = u"\u201d"
72
lead_single = u"\u2018"
73
elif ((lang == 'lt') or (lang == 'mk') or (lang == 'is') or (lang == 'sk') or (lang == 'sl') or (lang == 'cs') or (lang == 'et')):
74
lead_double = u"\u201e"
75
follow_double = u"\u201c"
76
lead_single = u"\u2019"
77
follow_single = u"\u201a"
78
elif ((lang == 'hu') or (lang == 'nl')):
79
lead_double = u"\u201e"
80
follow_double = u"\u201d"
81
lead_single = u"\u00bb"
82
follow_single = u"\u00ab"
84
scribus.messageBox('Language Error', 'You need to choose an available language', icon=0, button1=1)
52
non_breaking_space = u"\u00a0"
53
non_breaking_thin_space = u"\u202f"
54
thin_space = u"\u2009"
57
return (text == ' ') or (text == non_breaking_space) or (text == non_breaking_thin_space) or (text == thin_space)
59
if scribus.haveDoc() <= 0:
60
scribus.messageBox('Error - (fr) Erreur', 'You need a Document open\n(fr) Ouvrez un document avant de lancer le script', scribus.ICON_WARNING, scribus.BUTTON_OK)
63
lang = scribus.valueDialog("Language", 'Choose language or country\n(fr) Choisissez la langue du texte ou le pays :\naf, be, ch, cs, de, en, es, et, fi, fr,\n hu, is, lt, mk, nl, pl, ru, se, sk, sl, sq and uk', 'fr')
65
ouvrant_double = u"\u201c" #lead_double
66
fermant_double = u"\u201d" #follow_double
67
lead_single = u"\u2018"
68
follow_single = u"\u2019"
70
ouvrant_double = u"\u201e"
71
fermant_double = u"\u201c"
72
lead_single = u"\u2019"
73
follow_single = u"\u201a"
75
ouvrant_double = u"\u00ab" # « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
76
fermant_double = u"\u00bb" # » LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
77
lead_single = u"\u2018" # RIGHT SINGLE QUOTATION MARK
78
follow_single = u"\u2019" # LEFT SINGLE QUOTATION MARK
80
ouvrant_double = u"\u201e"
81
fermant_double = u"\u201d"
82
lead_single = u"\u201a"
83
follow_single = u"\u2019"
84
elif ((lang == 'se') or (lang == 'fi')):
85
ouvrant_double = u"\u201d"
86
fermant_double = u"\u201d"
87
lead_single = u"\u2019"
88
follow_single = u"\u2019"
90
ouvrant_double = u"\u201c"
91
fermant_double = u"\u201d"
92
lead_single = u"\u2018"
93
follow_single = u"\u2019"
95
ouvrant_double = u"\u201e"
96
fermant_double = u"\u201c"
97
lead_single = u"\u2018"
98
follow_single = u"\u2019"
99
elif ((lang == 'be') or (lang == 'ch') or (lang == 'uk') or (lang == 'ru')):
100
ouvrant_double = u"\u00ab"
101
fermant_double = u"\u00bb"
102
lead_single = u"\u2039"
103
follow_single = u"\u203a"
105
ouvrant_double = u"\u00ab"
106
fermant_double = u"\u00bb"
107
lead_single = u"\u2039"
108
follow_single = u"\u203a"
110
ouvrant_double = u"\u00ab"
111
fermant_double = u"\u00bb"
112
fermant_double = u"\u201d"
113
lead_single = u"\u2018"
114
elif ((lang == 'lt') or (lang == 'mk') or (lang == 'is') or (lang == 'sk') or (lang == 'sl') or (lang == 'cs') or (lang == 'et')):
115
ouvrant_double = u"\u201e"
116
fermant_double = u"\u201c"
117
lead_single = u"\u2019"
118
follow_single = u"\u201a"
119
elif ((lang == 'hu') or (lang == 'nl')):
120
ouvrant_double = u"\u201e"
121
fermant_double = u"\u201d"
122
lead_single = u"\u00bb"
123
follow_single = u"\u00ab"
88
scribus.messageBox('Usage Error', 'You need a Document open', icon=0, button1=1)
125
scribus.messageBox('Language Error', 'You need to choose an available language', icon=0, button1=1)
91
128
if scribus.selectionCount() == 0:
92
scribus.messageBox('Scribus - Usage Error',
93
"There is no object selected.\nPlease select a text frame and try again.",
94
scribus.ICON_WARNING, scribus.BUTTON_OK)
130
scribus.messageBox('Scribus - Erreur',
131
"Aucun objet n'est sélectionné.\nSélectionnez un cadre de texte et recommencez.",
132
scribus.ICON_WARNING, scribus.BUTTON_OK)
134
scribus.messageBox('Scribus - Usage Error',
135
"There is no object selected.\nPlease select a text frame and try again.",
136
scribus.ICON_WARNING, scribus.BUTTON_OK)
96
139
if scribus.selectionCount() > 1:
97
scribus.messageBox('Scribus - Usage Error',
98
"You have more than one object selected.\nPlease select one text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
141
scribus.messageBox('Scribus - Erreur',
142
"Désolé, ce script ne peut pas fonctionner lorsque plusieurs objets sont sélectionnés.\nVeuillez sélectionner un seul cadre de texte, puis recommencez.",
143
scribus.ICON_WARNING, scribus.BUTTON_OK)
145
scribus.messageBox('Scribus - Usage Error',
146
"You have more than one object selected.\nPlease select one text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
150
typeespace = scribus.valueDialog("Type d'espace",
151
"Selon les polices de caractère utilisées, choisissez le type d'espace ajouté avec les doubles guillemets français, lorsqu'il n'y en a pas déjà un.\n0 : aucun espace ajouté ; 1 : insécable ; 2 : insécable fine ; 3 : fine",
154
typeespace = scribus.valueDialog("Space inside quotes",
155
"Choose whether to add space inside double quotes.\n0: never add a space; 1: non breaking; 2: non breaking thin; 3: thin",
158
if (typeespace == '3'):
159
spacenquotes = thin_space
161
elif (typeespace == '2'):
162
spacenquotes = non_breaking_thin_space
164
elif (typeespace == '0'):
168
spacenquotes = non_breaking_space
171
if ((1==1) or (spacenquotes != '')):
173
replace_existing = scribus.valueDialog("Agir sur l'existant ?",
174
"Voulez vous aussi appliquer ce traitement sur les double-guillemets français déjà en place ? Oui: O ; Non : N ",
177
replace_existing = scribus.valueDialog("What about existing quotes?",
178
"Should the script apply your spaces choice ALSO on already existing quotes?\nYes: Y ; No: N",
181
if ((replace_existing=='y') or (replace_existing=='Y') or (replace_existing=='o') or (replace_existing=='O')):
100
186
textbox = scribus.getSelectedObject()
101
pageitems = scribus.getPageItems()
103
for item in pageitems:
189
for item in scribus.getPageItems():
104
190
if (item[0] == textbox):
105
191
if (item[1] != 4):
106
scribus.messageBox('Scribus - Usage Error', "This is not a textframe. Try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
193
scribus.messageBox('Scribus - Erreur',
194
"L'objet sélectionné n'est pas un cadre de texte.\nVeuillez sélectionner un cadre de texte, puis recommencez.",
195
scribus.ICON_WARNING, scribus.BUTTON_OK)
197
scribus.messageBox('Scribus - Usage Error', "This is not a textframe. Try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
108
contents = scribus.getTextLength(textbox)
109
while c <= (contents -1):
110
if ((c + 1) > contents - 1):
201
textlen = scribus.getTextLength(textbox)
207
while c <= (textlen -1):
208
# si on est à la fin, il faut tricher pour le dernier caractère
209
if ((c + 1) > textlen - 1):
113
214
scribus.selectText(c+1, 1, textbox)
114
215
nextchar = scribus.getText(textbox)
115
217
scribus.selectText(c, 1, textbox)
116
218
char = scribus.getText(textbox)
120
if ((ord(char) == 34) and (c == 0)):
121
scribus.deleteText(textbox)
122
scribus.insertText(lead_double, c, textbox)
123
elif (ord(char) == 34):
124
if ((prevchar == '.') or (prevchar == ',') or (prevchar == '?') or (prevchar == '!')):
125
scribus.deleteText(textbox)
126
scribus.insertText(follow_double, c, textbox)
127
elif ((ord(prevchar) == 39) and ((nextchar != ' ') and (nextchar != ',') and (nextchar != '.'))):
128
scribus.deleteText(textbox)
129
scribus.insertText(lead_double, c, textbox)
130
elif ((nextchar == '.') or (nextchar == ',')):
131
scribus.deleteText(textbox)
132
scribus.insertText(follow_double, c, textbox)
134
elif ((prevchar == ' ') or ((nextchar != ' ') and (ord(nextchar) != 39))):
135
scribus.deleteText(textbox)
136
scribus.insertText(lead_double, c, textbox)
220
# scribus.messageBox("ce qui est", "position:"+str(c) +'\nchar'+char+'\nPrec:'+prevchar+'\nsuiv:'+nextchar,
221
# scribus.ICON_WARNING, scribus.BUTTON_OK)
223
if (char==ouvrant_double):
224
if (lastchange=='open'):
226
scribus.messageBox("Oups !", 'Incohérence dans les enchainements de guillemets ouvrant et fermant. Une guillement fermante manque avant la position '+str(c) +'\nOn continue quand même',
227
scribus.ICON_WARNING, scribus.BUTTON_OK)
229
scribus.messageBox("Oops!", 'The text is inconsistent. Closing double quotes missing before position '+str(c),
230
scribus.ICON_WARNING, scribus.BUTTON_OK)
232
if ((replace_existing == 1) and (nextchar != spacenquotes) and (alafin==0)):
233
if (est_espace(nextchar)):
234
scribus.selectText(c+1, 1, textbox)
235
scribus.deleteText(textbox)
236
scribus.insertText(spacenquotes, c+1, textbox)
237
nbchange = nbchange+1
239
elif (char==fermant_double):
240
if (lastchange=='close'):
242
scribus.messageBox("Oups !", 'Incohérence dans les enchainements de guillemets ouvrant et fermant. Une guillemet ouvrante manque avant la position '+str(c) +'\nOn continue quand même',
243
scribus.ICON_WARNING, scribus.BUTTON_OK)
245
scribus.messageBox("Oops!", 'The text is inconsistent. Opening double quotes missing before position '+str(c),
246
scribus.ICON_WARNING, scribus.BUTTON_OK)
248
if ((replace_existing == 1) and (prevchar != spacenquotes) and (c > 1)):
249
if (est_espace(prevchar)):
250
scribus.selectText(c-1, 1, textbox)
251
scribus.deleteText(textbox)
253
scribus.insertText(spacenquotes, c, textbox)
254
nbchange = nbchange+1
257
elif (len(char) != 1): #en utf8 certains caractères ont len 2, par ex les espaces spéciaux qu'on teste au dessus
258
rien="rien" # et ça ferait planter ord()
260
elif (char == '"'): # autrement dit : ord (char)==34
261
#si on trouve une double guillemet droit " en premier caractère du texte, c'est un ouvrant !
263
scribus.deleteText(textbox)
264
if (not est_espace(nextchar)):
265
scribus.insertText(spacenquotes, 0, textbox)
266
scribus.insertText(ouvrant_double, 0, textbox)
268
elif ((prevchar == '.') or (prevchar == ',') or (prevchar == '?') or (prevchar == '!')):
269
# lets close after the end of a sentence
270
scribus.deleteText(textbox)
271
scribus.insertText(fermant_double, c, textbox)
272
scribus.insertText(spacenquotes, c, textbox)
275
# 39 = ' straight apostrophe
276
elif ((ord(prevchar) == 39) and ((nextchar != ' ') and (nextchar != ',') and (nextchar != ';') and (nextchar != '.'))):
277
scribus.deleteText(textbox)
278
if (not est_espace(nextchar)):
279
scribus.insertText(spacenquotes, c, textbox)
280
scribus.insertText(ouvrant_double, c, textbox)
282
elif ((nextchar == '.') or (nextchar == ',') or (nextchar == ';')):
283
scribus.deleteText(textbox)
284
scribus.insertText(fermant_double, c, textbox)
285
if (not est_espace(prevchar)):
286
scribus.insertText(spacenquotes, c, textbox)
289
elif (lastchange!='open'):
290
scribus.deleteText(textbox)
291
if (not est_espace(nextchar)):
292
scribus.insertText(spacenquotes, c, textbox)
293
scribus.insertText(ouvrant_double, c, textbox)
138
296
scribus.deleteText(textbox)
139
scribus.insertText(follow_double, c, textbox)
141
if ((ord(char) == 39) and (c == 0)):
297
scribus.insertText(fermant_double, c, textbox)
298
if (not est_espace(prevchar)):
299
scribus.insertText(spacenquotes, c, textbox)
302
nbchange = nbchange+1
304
elif ((ord(char) == 39) and (c == 0)):
142
305
scribus.deleteText(textbox)
143
306
scribus.insertText(lead_single, c, textbox)
307
nbchange = nbchange+1
144
308
elif (ord(char) == 39):
145
309
if ((prevchar == '.') or (prevchar == ',') or (prevchar == '?') or (prevchar == '!')):
146
310
scribus.deleteText(textbox)