2 # -*- coding: utf-8 -*-
4 # :Author: Günter Milde <milde@users.sourceforge.net>
5 # :Revision: $Revision$
7 # :Copyright: © 2010 Günter Milde.
8 # :License: Released under the terms of the `2-Clause BSD license`_, in short:
10 # Copying and distribution of this file, with or without modification,
11 # are permitted in any medium without royalty provided the copyright
12 # notice and this notice are preserved.
13 # This file is offered as-is, without any warranty.
15 # .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
18 XeLaTeX document tree Writer.
20 A variant of Docutils' standard 'latex2e' writer producing LaTeX output
21 suited for processing with the Unicode-aware TeX engines
25 __docformat__
= 'reStructuredText'
32 from docutils
import frontend
, nodes
, utils
, writers
, languages
33 from docutils
.writers
import latex2e
35 class Writer(latex2e
.Writer
):
36 """A writer for Unicode-aware LaTeX variants (XeTeX, LuaTeX)"""
38 supported
= ('lxtex', 'xetex','xelatex','luatex', 'lualatex')
39 """Formats this writer supports."""
41 default_template
= 'xelatex.tex'
42 default_preamble
= '\n'.join([
43 r
'% Linux Libertine (free, wide coverage, not only for Linux)',
44 r
'\setmainfont{Linux Libertine O}',
45 r
'\setsansfont{Linux Biolinum O}',
46 r
'\setmonofont[HyphenChar=None,Scale=MatchLowercase]{DejaVu Sans Mono}',
49 config_section
= 'xetex writer'
50 config_section_dependencies
= ('writers', 'latex2e writer')
52 settings_spec
= frontend
.filter_settings_spec(
53 latex2e
.Writer
.settings_spec
,
55 template
=('Template file. Default: "%s".' % default_template
,
56 ['--template'], {'default': default_template
, 'metavar': '<file>'}),
57 latex_preamble
=('Customization by LaTeX code in the preamble. '
58 'Default: select "Linux Libertine" fonts.',
60 {'default': default_preamble
}),
64 latex2e
.Writer
.__init
__(self
)
65 self
.settings_defaults
.update({'fontencoding': ''}) # use default (EU1 or EU2)
66 self
.translator_class
= XeLaTeXTranslator
69 class Babel(latex2e
.Babel
):
70 """Language specifics for XeTeX.
72 Use `polyglossia` instead of `babel` and adapt settings.
74 language_codes
= latex2e
.Babel
.language_codes
.copy()
75 # Additionally supported or differently named languages:
76 language_codes
.update({
77 # code Polyglossia-name comment
79 'de': 'german', # new spelling (de_1996)
80 'de-1901': 'ogerman', # old spelling
81 'dv': 'divehi', # Maldivian
83 'el-polyton': 'polygreek',
85 'grc': 'ancientgreek',
87 'sh-Cyrl': 'serbian', # Serbo-Croatian, Cyrillic script
88 'sh-Latn': 'croatian', # Serbo-Croatian, Latin script
90 'sr': 'serbian', # Cyrillic script (sr-Cyrl)
93 # zh-Latn: ??? # Chinese Pinyin
95 # normalize (downcase) keys
96 language_codes
= dict([(k
.lower(), v
) for (k
,v
) in language_codes
.items()])
98 # Languages without Polyglossia support:
99 for key
in ('af', # 'afrikaans',
100 'de-AT', # 'naustrian',
101 'de-AT-1901', # 'austrian',
102 'fr-CA', # 'canadien',
103 'grc-ibycus', # 'ibycus', (Greek Ibycus encoding)
104 'sr-Latn', # 'serbian script=latin'
106 del(language_codes
[key
.lower()])
108 def __init__(self
, language_code
, reporter
):
109 self
.language_code
= language_code
110 self
.reporter
= reporter
111 self
.language
= self
.language_name(language_code
)
112 self
.otherlanguages
= {}
113 self
.warn_msg
= 'Language "%s" not supported by XeTeX (polyglossia).'
115 self
.quotes
= ('"', '"')
116 # language dependent configuration:
117 # double quotes are "active" in some languages (e.g. German).
118 self
.literal_double_quote
= u
'"' # TODO: use \textquotedbl
121 setup
= [r
'\usepackage{polyglossia}',
122 r
'\setdefaultlanguage{%s}' % self
.language
]
123 if self
.otherlanguages
:
124 setup
.append(r
'\setotherlanguages{%s}' %
125 ','.join(sorted(self
.otherlanguages
.keys())))
126 return '\n'.join(setup
)
129 class XeLaTeXTranslator(latex2e
.LaTeXTranslator
):
131 def __init__(self
, document
):
132 self
.is_xetex
= True # typeset with XeTeX or LuaTeX engine
133 latex2e
.LaTeXTranslator
.__init
__(self
, document
, Babel
)
134 if self
.latex_encoding
== 'utf8':
135 self
.requirements
.pop('_inputenc', None)
137 self
.requirements
['_inputenc'] = (r
'\XeTeXinputencoding %s '
138 % self
.latex_encoding
)