Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/specialchars.py: 30%
75 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
5"""Helper code to get user special characters specific for given language."""
7import unicodedata
9from django.conf import settings
10from django.utils.translation import gettext, gettext_lazy
12# Names of hardcoded characters
13CHAR_NAMES = {
14 "\t": gettext_lazy("Insert tab character"),
15 "\n": gettext_lazy("Insert new line"),
16 "…": gettext_lazy("Insert horizontal ellipsis"),
17 "\u00ad": gettext_lazy("Insert a soft hyphen"),
18 "\u00a0": gettext_lazy("Insert a non-breaking space"),
19}
20DISPLAY_CHARS = {"\t": "↹", "\n": "↵", "\u00ad": "﹙-﹚"}
23HYPHEN_LANGS = {
24 "af",
25 "am",
26 "ar",
27 "ast",
28 "az",
29 "bg",
30 "bs",
31 "ca",
32 "cs",
33 "cy",
34 "da",
35 "de",
36 "dsb",
37 "dz",
38 "ee",
39 "el",
40 "en",
41 "eo",
42 "es",
43 "fa",
44 "fi",
45 "fr",
46 "fy",
47 "gd",
48 "gl",
49 "gu",
50 "he",
51 "hr",
52 "hsb",
53 "id",
54 "is",
55 "ja",
56 "ka",
57 "kk",
58 "kn",
59 "ko",
60 "ksh",
61 "ky",
62 "lb",
63 "lkt",
64 "lt",
65 "lv",
66 "mk",
67 "mn",
68 "mr",
69 "nl",
70 "os",
71 "pa",
72 "pl",
73 "pt",
74 "ro",
75 "ru",
76 "sk",
77 "sr",
78 "sv",
79 "ta",
80 "th",
81 "to",
82 "tr",
83 "uz",
84 "vi",
85 "vo",
86 "yi",
87 "zh",
88}
90EN_DASH_LANGS = {
91 "af",
92 "am",
93 "ar",
94 "ast",
95 "az",
96 "bg",
97 "bs",
98 "ca",
99 "cs",
100 "cy",
101 "da",
102 "de",
103 "dsb",
104 "dz",
105 "ee",
106 "el",
107 "en",
108 "eo",
109 "es",
110 "fi",
111 "fr",
112 "fy",
113 "gd",
114 "gl",
115 "gu",
116 "he",
117 "hr",
118 "hsb",
119 "hu",
120 "id",
121 "is",
122 "ka",
123 "kk",
124 "kn",
125 "ksh",
126 "ky",
127 "lb",
128 "lkt",
129 "lt",
130 "lv",
131 "mk",
132 "mn",
133 "mr",
134 "nb",
135 "nl",
136 "os",
137 "pa",
138 "pl",
139 "pt",
140 "ro",
141 "ru",
142 "sk",
143 "sr",
144 "sv",
145 "ta",
146 "th",
147 "to",
148 "tr",
149 "uk",
150 "uz",
151 "vi",
152 "vo",
153 "yi",
154 "zh",
155}
157EM_DASH_LANGS = {
158 "af",
159 "ar",
160 "ast",
161 "az",
162 "bg",
163 "bs",
164 "ca",
165 "cy",
166 "de",
167 "dsb",
168 "dz",
169 "ee",
170 "el",
171 "en",
172 "eo",
173 "es",
174 "fr",
175 "fy",
176 "gd",
177 "gl",
178 "gu",
179 "he",
180 "hr",
181 "hsb",
182 "id",
183 "is",
184 "it",
185 "ja",
186 "ka",
187 "kk",
188 "kn",
189 "ko",
190 "ksh",
191 "ky",
192 "lb",
193 "lkt",
194 "lt",
195 "lv",
196 "mk",
197 "mn",
198 "mr",
199 "nl",
200 "os",
201 "pa",
202 "pl",
203 "pt",
204 "ro",
205 "ru",
206 "sv",
207 "ta",
208 "th",
209 "to",
210 "tr",
211 "uz",
212 "vi",
213 "vo",
214 "yi",
215 "zh",
216}
218EXTRA_CHARS = {
219 "brx": ("।", "॥"),
220 "he": ("־", "״", "׳"),
221}
223# Additional characters for RTL languages
224RTL_CHARS = (8204, 8205, 8206, 8207, 8234, 8235, 8236, 8237, 8238)
227def get_quote(code, data, name):
228 """Return special char for quote."""
229 if code in data:
230 return name, data[code], data[code]
231 return name, data["ALL"], data["ALL"]
234def get_display_char(char):
235 name = short = char
236 if unicodedata.category(char)[0] in {"C", "Z"}: 236 ↛ 248line 236 didn't jump to line 248 because the condition on line 236 was always true
237 # Various control and space characters
238 try:
239 name = unicodedata.name(char)
240 short = "".join(
241 x[0] for x in name.replace("-TO-", " ").replace("-", " ").split()
242 )
243 except ValueError:
244 # Char now known to unicode data
245 # This mostly happens for control characters < 0x20
246 name = short = char.encode("unicode_escape").decode("ascii")
247 # Use display short name if available
248 short = DISPLAY_CHARS.get(char, short)
249 return name, short
252def format_char(char):
253 """Return verbose description of a character."""
254 name, short = get_display_char(char)
255 if char in CHAR_NAMES: 255 ↛ 256line 255 didn't jump to line 256 because the condition on line 255 was never true
256 return CHAR_NAMES[char], short, char
258 return gettext("Insert character {0}").format(name), short, char
261def get_special_chars(language, additional="", source=""):
262 """Return list of special characters."""
263 for char in settings.SPECIAL_CHARS:
264 yield format_char(char)
265 code = language.code.replace("_", "-").split("-")[0]
267 if code in EXTRA_CHARS:
268 for char in EXTRA_CHARS[code]:
269 yield format_char(char)
271 yield get_quote(code, MAIN_OPEN, gettext("Main opening quote"))
272 yield get_quote(code, MAIN_CLOSE, gettext("Main closing quote"))
273 yield get_quote(code, ALT_OPEN, gettext("Alternative opening quote"))
274 yield get_quote(code, ALT_CLOSE, gettext("Alternative closing quote"))
276 if code in HYPHEN_LANGS:
277 yield format_char("\u00ad")
278 yield gettext("Hyphen"), "‐", "‐"
280 if code in EN_DASH_LANGS:
281 yield gettext("En dash"), "–", "–"
283 if code in EM_DASH_LANGS:
284 yield gettext("Em dash"), "—", "—"
286 for char in additional:
287 name, short = get_display_char(char)
288 yield gettext("User configured character: {}").format(name), short, char
290 rtl = language.direction == "rtl"
291 for char in set(source):
292 try:
293 name = unicodedata.name(char)
294 except ValueError:
295 continue
296 if "ARROW" in name:
297 if rtl and "LEFT" in name:
298 try:
299 char = unicodedata.lookup(name.replace("LEFT", "RIGHT"))
300 except KeyError:
301 continue
302 yield format_char(char)
303 elif rtl and "RIGHT" in name:
304 try:
305 char = unicodedata.lookup(name.replace("RIGHT", "LEFT"))
306 except KeyError:
307 continue
308 yield format_char(char)
309 else:
310 yield format_char(char)
313RTL_CHARS_DATA = [format_char(chr(c)) for c in RTL_CHARS]
315# Quotes data, generated using scripts/generate-specialchars.py
316ALT_OPEN = {
317 "ALL": "‘",
318 "af": "‘",
319 "agq": "‚",
320 "ak": "‘",
321 "am": "‹",
322 "ar": "‘",
323 "as": "‘",
324 "asa": "‘",
325 "ast": "“",
326 "az": "‹",
327 "bas": "„",
328 "be": "‹",
329 "bem": "‘",
330 "bez": "‘",
331 "bg": "‚",
332 "bm": "“",
333 "bn": "‘",
334 "bo": "‘",
335 "br": "‹",
336 "brx": "‘",
337 "bs": "‘",
338 "ca": "“",
339 "cgg": "‘",
340 "chr": "‘",
341 "cs": "‚",
342 "cy": "‘",
343 "da": "›",
344 "de": "‚",
345 "dsb": "‚",
346 "dua": "‘",
347 "dyo": "“",
348 "ee": "‘",
349 "el": "“",
350 "en": "‘",
351 "eo": "‘",
352 "es": "“",
353 "et": "‚",
354 "eu": "‹",
355 "ewo": "“",
356 "fa": "‹",
357 "ff": "‚",
358 "fi": "’",
359 "fil": "‘",
360 "fo": "‘",
361 "fr": "‹",
362 "fur": "“",
363 "ga": "‘",
364 "gl": "‘",
365 "gsw": "‹",
366 "gu": "‘",
367 "gv": "‘",
368 "ha": "‘",
369 "haw": "‘",
370 "he": "‚",
371 "hi": "‘",
372 "hr": "‚",
373 "hsb": "‚",
374 "hu": "»",
375 "hy": "‘",
376 "ia": "“",
377 "id": "‘",
378 "ig": "‘",
379 "ii": "‘",
380 "is": "‚",
381 "it": "“",
382 "ja": "『",
383 "jgo": "‹",
384 "jmc": "‘",
385 "ka": "‚",
386 "kab": "“",
387 "kam": "‘",
388 "kde": "‘",
389 "kea": "‘",
390 "ki": "‘",
391 "kk": "‘",
392 "kkj": "‹",
393 "kl": "‘",
394 "km": "‘",
395 "kn": "‘",
396 "ko": "‘",
397 "kok": "‘",
398 "ksb": "‘",
399 "ksh": "‚",
400 "kw": "‘",
401 "ky": "„",
402 "lag": "’",
403 "lb": "‚",
404 "lg": "‘",
405 "ln": "‘",
406 "lt": "‚",
407 "lu": "‘",
408 "luo": "‘",
409 "luy": "‚",
410 "lv": "„",
411 "mas": "‘",
412 "mfe": "‘",
413 "mg": "“",
414 "mk": "‚",
415 "ml": "‘",
416 "mr": "‘",
417 "ms": "‘",
418 "mt": "‘",
419 "mua": "“",
420 "my": "‘",
421 "naq": "‘",
422 "nb_NO": "‘",
423 "nd": "‘",
424 "ne": "‘",
425 "nl": "‘",
426 "nmg": "«",
427 "nn": "‘",
428 "nnh": "“",
429 "nr": "“",
430 "nso": "“",
431 "nyn": "‘",
432 "om": "‘",
433 "or": "‘",
434 "os": "„",
435 "pa": "‘",
436 "pl": "«",
437 "ps": "‘",
438 "pt": "‘",
439 "rm": "‹",
440 "rn": "’",
441 "ro": "«",
442 "rof": "‘",
443 "ru": "„",
444 "rw": "‘",
445 "rwk": "‘",
446 "saq": "‘",
447 "se": "’",
448 "seh": "‘",
449 "ses": "‘",
450 "sg": "“",
451 "shi": "„",
452 "si": "‘",
453 "sk": "‚",
454 "sl": "‚",
455 "sn": "’",
456 "so": "‘",
457 "sq": "‚",
458 "sr": "‚",
459 "sr_Cyrl": "‘",
460 "sr_Latn": "‚",
461 "ss": "“",
462 "sv": "’",
463 "sw": "‘",
464 "ta": "‘",
465 "te": "‘",
466 "teo": "‘",
467 "th": "‘",
468 "ti": "‘",
469 "tn": "“",
470 "to": "‘",
471 "tr": "‘",
472 "ts": "“",
473 "tzm": "‘",
474 "ug": "›",
475 "uk": "„",
476 "ur": "‘",
477 "uz": "‘",
478 "uz_Latn": "‘",
479 "vai": "‘",
480 "ve": "“",
481 "vi": "‘",
482 "vo": "‘",
483 "vun": "‘",
484 "wae": "‹",
485 "xog": "‘",
486 "yav": "«",
487 "yi": "'",
488 "yo": "‘",
489 "zgh": "„",
490 "zh": "『",
491 "zh_Hans": "‘",
492 "zh_Hant": "『",
493 "zu": "‘",
494}
495ALT_CLOSE = {
496 "ALL": "’",
497 "af": "’",
498 "ak": "’",
499 "am": "›",
500 "ar": "’",
501 "as": "’",
502 "asa": "’",
503 "ast": "”",
504 "az": "›",
505 "bas": "“",
506 "be": "›",
507 "bem": "’",
508 "bez": "’",
509 "bg": "‘",
510 "bm": "”",
511 "bn": "’",
512 "bo": "’",
513 "br": "›",
514 "brx": "’",
515 "bs": "’",
516 "ca": "”",
517 "cgg": "’",
518 "chr": "’",
519 "cs": "‘",
520 "cy": "’",
521 "da": "‹",
522 "de": "‘",
523 "dsb": "‘",
524 "dua": "’",
525 "dyo": "”",
526 "ee": "’",
527 "el": "”",
528 "en": "’",
529 "eo": "’",
530 "es": "”",
531 "et": "‘",
532 "eu": "›",
533 "ewo": "”",
534 "fa": "›",
535 "ff": "’",
536 "fi": "’",
537 "fil": "’",
538 "fo": "’",
539 "fr": "›",
540 "fur": "”",
541 "ga": "’",
542 "gl": "’",
543 "gsw": "›",
544 "gu": "’",
545 "gv": "’",
546 "ha": "’",
547 "haw": "’",
548 "he": "’",
549 "hi": "’",
550 "hr": "‘",
551 "hsb": "‘",
552 "hu": "«",
553 "hy": "’",
554 "ia": "”",
555 "id": "’",
556 "ig": "’",
557 "ii": "’",
558 "is": "‘",
559 "it": "”",
560 "ja": "』",
561 "jgo": "›",
562 "jmc": "’",
563 "ka": "‘",
564 "kab": "”",
565 "kam": "’",
566 "kde": "’",
567 "kea": "’",
568 "ki": "’",
569 "kk": "’",
570 "kkj": "›",
571 "kl": "’",
572 "km": "’",
573 "kn": "’",
574 "ko": "’",
575 "kok": "’",
576 "ksb": "’",
577 "ksh": "‘",
578 "kw": "’",
579 "ky": "“",
580 "lag": "’",
581 "lb": "‘",
582 "lg": "’",
583 "ln": "’",
584 "lt": "‘",
585 "lu": "’",
586 "luo": "’",
587 "luy": "‘",
588 "lv": "“",
589 "mas": "’",
590 "mfe": "’",
591 "mg": "”",
592 "mk": "‘",
593 "ml": "’",
594 "mr": "’",
595 "ms": "’",
596 "mt": "’",
597 "mua": "”",
598 "my": "’",
599 "naq": "’",
600 "nb_NO": "’",
601 "nd": "’",
602 "ne": "’",
603 "nl": "’",
604 "nmg": "»",
605 "nn": "’",
606 "nnh": "”",
607 "nr": "”",
608 "nso": "”",
609 "nyn": "’",
610 "om": "’",
611 "or": "’",
612 "os": "“",
613 "pa": "’",
614 "pl": "»",
615 "ps": "’",
616 "pt": "’",
617 "rm": "›",
618 "rn": "’",
619 "ro": "»",
620 "rof": "’",
621 "ru": "“",
622 "rw": "’",
623 "rwk": "’",
624 "saq": "’",
625 "seh": "’",
626 "ses": "’",
627 "sg": "”",
628 "shi": "”",
629 "si": "’",
630 "sk": "‘",
631 "sl": "‘",
632 "sn": "’",
633 "so": "’",
634 "sq": "‘",
635 "sr": "‘",
636 "sr_Cyrl": "’",
637 "sr_Latn": "‘",
638 "ss": "”",
639 "sv": "’",
640 "sw": "’",
641 "ta": "’",
642 "te": "’",
643 "teo": "’",
644 "th": "’",
645 "ti": "’",
646 "tn": "”",
647 "to": "’",
648 "tr": "’",
649 "ts": "”",
650 "tzm": "’",
651 "ug": "‹",
652 "uk": "“",
653 "ur": "’",
654 "uz": "’",
655 "uz_Latn": "’",
656 "vai": "’",
657 "ve": "”",
658 "vi": "’",
659 "vo": "’",
660 "vun": "’",
661 "wae": "›",
662 "xog": "’",
663 "yav": "»",
664 "yi": "'",
665 "yo": "’",
666 "zgh": "”",
667 "zh": "』",
668 "zh_Hans": "’",
669 "zh_Hant": "』",
670 "zu": "’",
671}
672MAIN_OPEN = {
673 "ALL": "“",
674 "af": "“",
675 "agq": "„",
676 "ak": "“",
677 "am": "«",
678 "ar": "“",
679 "as": "“",
680 "asa": "“",
681 "ast": "«",
682 "az": "«",
683 "bas": "«",
684 "be": "«",
685 "bem": "“",
686 "bez": "“",
687 "bg": "„",
688 "bm": "«",
689 "bn": "“",
690 "bo": "“",
691 "br": "«",
692 "brx": "“",
693 "bs": "“",
694 "ca": "«",
695 "cgg": "“",
696 "chr": "“",
697 "cs": "„",
698 "cy": "“",
699 "da": "»",
700 "de": "„",
701 "dsb": "„",
702 "dua": "«",
703 "dyo": "«",
704 "ee": "“",
705 "el": "«",
706 "en": "“",
707 "eo": "“",
708 "es": "«",
709 "et": "„",
710 "eu": "«",
711 "ewo": "«",
712 "fa": "«",
713 "ff": "„",
714 "fi": "”",
715 "fil": "“",
716 "fo": "“",
717 "fr": "«",
718 "fur": "‘",
719 "ga": "“",
720 "gl": "“",
721 "gsw": "«",
722 "gu": "“",
723 "gv": "“",
724 "ha": "“",
725 "haw": "“",
726 "he": "„",
727 "hi": "“",
728 "hr": "„",
729 "hsb": "„",
730 "hu": "„",
731 "hy": "“",
732 "ia": "‘",
733 "id": "“",
734 "ig": "“",
735 "ii": "“",
736 "is": "„",
737 "it": "«",
738 "ja": "「",
739 "jgo": "«",
740 "jmc": "“",
741 "ka": "„",
742 "kab": "«",
743 "kam": "“",
744 "kde": "“",
745 "kea": "“",
746 "ki": "“",
747 "kk": "“",
748 "kkj": "«",
749 "kl": "“",
750 "km": "“",
751 "kn": "“",
752 "ko": "“",
753 "kok": "“",
754 "ksb": "“",
755 "ksf": "«",
756 "ksh": "„",
757 "kw": "“",
758 "ky": "«",
759 "lag": "”",
760 "lb": "„",
761 "lg": "“",
762 "ln": "“",
763 "lt": "„",
764 "lu": "“",
765 "luo": "“",
766 "luy": "„",
767 "lv": "«",
768 "mas": "“",
769 "mfe": "“",
770 "mg": "«",
771 "mk": "„",
772 "ml": "“",
773 "mr": "“",
774 "ms": "“",
775 "mt": "“",
776 "mua": "«",
777 "my": "“",
778 "naq": "“",
779 "nb": "«",
780 "nb_NO": "«",
781 "nd": "“",
782 "ne": "“",
783 "nl": "“",
784 "nmg": "„",
785 "nn": "«",
786 "nnh": "«",
787 "nr": "‘",
788 "nso": "‘",
789 "nyn": "“",
790 "om": "“",
791 "or": "“",
792 "os": "«",
793 "pa": "“",
794 "pl": "„",
795 "ps": "“",
796 "pt": "“",
797 "rm": "«",
798 "rn": "”",
799 "ro": "„",
800 "rof": "“",
801 "ru": "«",
802 "rw": "«",
803 "rwk": "“",
804 "saq": "“",
805 "se": "”",
806 "seh": "“",
807 "ses": "“",
808 "sg": "«",
809 "shi": "«",
810 "si": "“",
811 "sk": "„",
812 "sl": "„",
813 "sn": "”",
814 "so": "“",
815 "sq": "„",
816 "sr": "„",
817 "sr_Cyrl": "“",
818 "sr_Latn": "„",
819 "ss": "‘",
820 "sv": "”",
821 "sw": "“",
822 "ta": "“",
823 "te": "“",
824 "teo": "“",
825 "th": "“",
826 "ti": "“",
827 "tn": "‘",
828 "to": "“",
829 "tr": "“",
830 "ts": "‘",
831 "tzm": "“",
832 "ug": "»",
833 "uk": "«",
834 "ur": "“",
835 "uz": "“",
836 "uz_Latn": "“",
837 "vai": "“",
838 "ve": "‘",
839 "vi": "“",
840 "vo": "“",
841 "vun": "“",
842 "wae": "«",
843 "xog": "“",
844 "yav": "«",
845 "yi": '"',
846 "yo": "“",
847 "zgh": "«",
848 "zh": "「",
849 "zh_Hans": "“",
850 "zh_Hant": "「",
851 "zu": "“",
852}
853MAIN_CLOSE = {
854 "ALL": "”",
855 "af": "”",
856 "ak": "”",
857 "am": "»",
858 "ar": "”",
859 "as": "”",
860 "asa": "”",
861 "ast": "»",
862 "az": "»",
863 "bas": "»",
864 "be": "»",
865 "bem": "”",
866 "bez": "”",
867 "bg": "“",
868 "bm": "»",
869 "bn": "”",
870 "bo": "”",
871 "br": "»",
872 "brx": "”",
873 "bs": "”",
874 "ca": "»",
875 "cgg": "”",
876 "chr": "”",
877 "cs": "“",
878 "cy": "”",
879 "da": "«",
880 "de": "“",
881 "dsb": "“",
882 "dua": "»",
883 "dyo": "»",
884 "ee": "”",
885 "el": "»",
886 "en": "”",
887 "eo": "”",
888 "es": "»",
889 "et": "“",
890 "eu": "»",
891 "ewo": "»",
892 "fa": "»",
893 "ff": "”",
894 "fi": "”",
895 "fil": "”",
896 "fo": "”",
897 "fr": "»",
898 "fur": "’",
899 "ga": "”",
900 "gl": "”",
901 "gsw": "»",
902 "gu": "”",
903 "gv": "”",
904 "ha": "”",
905 "haw": "”",
906 "he": "”",
907 "hi": "”",
908 "hr": "“",
909 "hsb": "“",
910 "hu": "”",
911 "hy": "”",
912 "ia": "’",
913 "id": "”",
914 "ig": "”",
915 "ii": "”",
916 "is": "“",
917 "it": "»",
918 "ja": "」",
919 "jgo": "»",
920 "jmc": "”",
921 "ka": "“",
922 "kab": "»",
923 "kam": "”",
924 "kde": "”",
925 "kea": "”",
926 "ki": "”",
927 "kk": "”",
928 "kkj": "»",
929 "kl": "”",
930 "km": "”",
931 "kn": "”",
932 "ko": "”",
933 "kok": "”",
934 "ksb": "”",
935 "ksf": "»",
936 "ksh": "“",
937 "kw": "”",
938 "ky": "»",
939 "lag": "”",
940 "lb": "“",
941 "lg": "”",
942 "ln": "”",
943 "lt": "“",
944 "lu": "”",
945 "luo": "”",
946 "luy": "“",
947 "lv": "»",
948 "mas": "”",
949 "mfe": "”",
950 "mg": "»",
951 "mk": "“",
952 "ml": "”",
953 "mr": "”",
954 "ms": "”",
955 "mt": "”",
956 "mua": "»",
957 "my": "”",
958 "naq": "”",
959 "nb": "»",
960 "nb_NO": "»",
961 "nd": "”",
962 "ne": "”",
963 "nl": "”",
964 "nn": "»",
965 "nnh": "»",
966 "nr": "’",
967 "nso": "’",
968 "nyn": "”",
969 "om": "”",
970 "or": "”",
971 "os": "»",
972 "pa": "”",
973 "pl": "”",
974 "ps": "”",
975 "pt": "”",
976 "rm": "»",
977 "rn": "”",
978 "ro": "”",
979 "rof": "”",
980 "ru": "»",
981 "rw": "»",
982 "rwk": "”",
983 "saq": "”",
984 "seh": "”",
985 "ses": "”",
986 "sg": "»",
987 "shi": "»",
988 "si": "”",
989 "sk": "“",
990 "sl": "“",
991 "sn": "”",
992 "so": "”",
993 "sq": "“",
994 "sr": "“",
995 "sr_Cyrl": "”",
996 "sr_Latn": "“",
997 "ss": "’",
998 "sv": "”",
999 "sw": "”",
1000 "ta": "”",
1001 "te": "”",
1002 "teo": "”",
1003 "th": "”",
1004 "ti": "”",
1005 "tn": "’",
1006 "to": "”",
1007 "tr": "”",
1008 "ts": "’",
1009 "tzm": "”",
1010 "ug": "«",
1011 "uk": "»",
1012 "ur": "”",
1013 "uz": "”",
1014 "uz_Latn": "”",
1015 "vai": "”",
1016 "ve": "’",
1017 "vi": "”",
1018 "vo": "”",
1019 "vun": "”",
1020 "wae": "»",
1021 "xog": "”",
1022 "yav": "»",
1023 "yi": '"',
1024 "yo": "”",
1025 "zgh": "»",
1026 "zh": "」",
1027 "zh_Hans": "”",
1028 "zh_Hant": "」",
1029 "zu": "”",
1030}