mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
refactor: LaTeX: Use raw strings for LaTeX macros
This commit is contained in:
@@ -164,15 +164,15 @@ class Table:
|
||||
return self.colspec
|
||||
elif self.colwidths and 'colwidths-given' in self.classes:
|
||||
total = sum(self.colwidths)
|
||||
colspecs = ['\\X{%d}{%d}' % (width, total) for width in self.colwidths]
|
||||
colspecs = [r'\X{%d}{%d}' % (width, total) for width in self.colwidths]
|
||||
return '{|%s|}' % '|'.join(colspecs) + CR
|
||||
elif self.has_problematic:
|
||||
return '{|*{%d}{\\X{1}{%d}|}}' % (self.colcount, self.colcount) + CR
|
||||
return r'{|*{%d}{\X{1}{%d}|}}' % (self.colcount, self.colcount) + CR
|
||||
elif self.get_table_type() == 'tabulary':
|
||||
# sphinx.sty sets T to be J by default.
|
||||
return '{|' + ('T|' * self.colcount) + '}' + CR
|
||||
elif self.has_oldproblematic:
|
||||
return '{|*{%d}{\\X{1}{%d}|}}' % (self.colcount, self.colcount) + CR
|
||||
return r'{|*{%d}{\X{1}{%d}|}}' % (self.colcount, self.colcount) + CR
|
||||
else:
|
||||
return '{|' + ('l|' * self.colcount) + '}' + CR
|
||||
|
||||
@@ -253,19 +253,19 @@ def rstdim_to_latexdim(width_str: str, scale: int = 100) -> str:
|
||||
if scale == 100:
|
||||
float(amount) # validate amount is float
|
||||
if unit in ('', "px"):
|
||||
res = "%s\\sphinxpxdimen" % amount
|
||||
res = r"%s\sphinxpxdimen" % amount
|
||||
elif unit == 'pt':
|
||||
res = '%sbp' % amount # convert to 'bp'
|
||||
elif unit == "%":
|
||||
res = "%.3f\\linewidth" % (float(amount) / 100.0)
|
||||
res = r"%.3f\linewidth" % (float(amount) / 100.0)
|
||||
else:
|
||||
amount_float = float(amount) * scale / 100.0
|
||||
if unit in ('', "px"):
|
||||
res = "%.5f\\sphinxpxdimen" % amount_float
|
||||
res = r"%.5f\sphinxpxdimen" % amount_float
|
||||
elif unit == 'pt':
|
||||
res = '%.5fbp' % amount_float
|
||||
elif unit == "%":
|
||||
res = "%.5f\\linewidth" % (amount_float / 100.0)
|
||||
res = r"%.5f\linewidth" % (amount_float / 100.0)
|
||||
else:
|
||||
res = "%.5f%s" % (amount_float, unit)
|
||||
return res
|
||||
@@ -373,9 +373,9 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if (self.config.language not in {None, 'en', 'ja'} and
|
||||
'fncychap' not in self.config.latex_elements):
|
||||
# use Sonny style if any language specified (except English)
|
||||
self.elements['fncychap'] = ('\\usepackage[Sonny]{fncychap}' + CR +
|
||||
'\\ChNameVar{\\Large\\normalfont\\sffamily}' + CR +
|
||||
'\\ChTitleVar{\\Large\\normalfont\\sffamily}')
|
||||
self.elements['fncychap'] = (r'\usepackage[Sonny]{fncychap}' + CR +
|
||||
r'\ChNameVar{\Large\normalfont\sffamily}' + CR +
|
||||
r'\ChTitleVar{\Large\normalfont\sffamily}')
|
||||
|
||||
self.babel = self.builder.babel
|
||||
if self.config.language and not self.babel.is_supported_language():
|
||||
@@ -400,19 +400,19 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
logger.warning(__('too large :maxdepth:, ignored.'))
|
||||
tocdepth = len(LATEXSECTIONNAMES) - 2
|
||||
|
||||
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
|
||||
self.elements['tocdepth'] = r'\setcounter{tocdepth}{%d}' % tocdepth
|
||||
minsecnumdepth = max(minsecnumdepth, tocdepth)
|
||||
|
||||
if self.config.numfig and (self.config.numfig_secnum_depth > 0):
|
||||
minsecnumdepth = max(minsecnumdepth, self.numfig_secnum_depth - 1)
|
||||
|
||||
if minsecnumdepth > self.secnumdepth:
|
||||
self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\
|
||||
self.elements['secnumdepth'] = r'\setcounter{secnumdepth}{%d}' %\
|
||||
minsecnumdepth
|
||||
|
||||
contentsname = document.get('contentsname')
|
||||
if contentsname:
|
||||
self.elements['contentsname'] = self.babel_renewcommand('\\contentsname',
|
||||
self.elements['contentsname'] = self.babel_renewcommand(r'\contentsname',
|
||||
contentsname)
|
||||
|
||||
if self.elements['maxlistdepth']:
|
||||
@@ -420,8 +420,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if sphinxpkgoptions:
|
||||
self.elements['sphinxpkgoptions'] = '[,%s]' % ','.join(sphinxpkgoptions)
|
||||
if self.elements['sphinxsetup']:
|
||||
self.elements['sphinxsetup'] = ('\\sphinxsetup{%s}' %
|
||||
self.elements['sphinxsetup'])
|
||||
self.elements['sphinxsetup'] = (r'\sphinxsetup{%s}' % self.elements['sphinxsetup'])
|
||||
if self.elements['extraclassoptions']:
|
||||
self.elements['classoptions'] += ',' + \
|
||||
self.elements['extraclassoptions']
|
||||
@@ -466,8 +465,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def hypertarget(self, id: str, withdoc: bool = True, anchor: bool = True) -> str:
|
||||
if withdoc:
|
||||
id = self.curfilestack[-1] + ':' + id
|
||||
return ('\\phantomsection' if anchor else '') + \
|
||||
'\\label{%s}' % self.idescape(id)
|
||||
return (r'\phantomsection' if anchor else '') + r'\label{%s}' % self.idescape(id)
|
||||
|
||||
def hypertarget_to(self, node: Element, anchor: bool = False) -> str:
|
||||
labels = ''.join(self.hypertarget(node_id, anchor=False) for node_id in node['ids'])
|
||||
@@ -477,48 +475,48 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
return labels
|
||||
|
||||
def hyperlink(self, id: str) -> str:
|
||||
return '{\\hyperref[%s]{' % self.idescape(id)
|
||||
return r'{\hyperref[%s]{' % self.idescape(id)
|
||||
|
||||
def hyperpageref(self, id: str) -> str:
|
||||
return '\\autopageref*{%s}' % self.idescape(id)
|
||||
return r'\autopageref*{%s}' % self.idescape(id)
|
||||
|
||||
def escape(self, s: str) -> str:
|
||||
return texescape.escape(s, self.config.latex_engine)
|
||||
|
||||
def idescape(self, id: str) -> str:
|
||||
return '\\detokenize{%s}' % str(id).translate(tex_replace_map).\
|
||||
return r'\detokenize{%s}' % str(id).translate(tex_replace_map).\
|
||||
encode('ascii', 'backslashreplace').decode('ascii').\
|
||||
replace('\\', '_')
|
||||
|
||||
def babel_renewcommand(self, command: str, definition: str) -> str:
|
||||
if self.elements['multilingual']:
|
||||
prefix = '\\addto\\captions%s{' % self.babel.get_language()
|
||||
prefix = r'\addto\captions%s{' % self.babel.get_language()
|
||||
suffix = '}'
|
||||
else: # babel is disabled (mainly for Japanese environment)
|
||||
prefix = ''
|
||||
suffix = ''
|
||||
|
||||
return '%s\\renewcommand{%s}{%s}%s' % (prefix, command, definition, suffix) + CR
|
||||
return r'%s\renewcommand{%s}{%s}%s' % (prefix, command, definition, suffix) + CR
|
||||
|
||||
def generate_indices(self) -> str:
|
||||
def generate(content: List[Tuple[str, List[IndexEntry]]], collapsed: bool) -> None:
|
||||
ret.append('\\begin{sphinxtheindex}' + CR)
|
||||
ret.append('\\let\\bigletter\\sphinxstyleindexlettergroup' + CR)
|
||||
ret.append(r'\begin{sphinxtheindex}' + CR)
|
||||
ret.append(r'\let\bigletter\sphinxstyleindexlettergroup' + CR)
|
||||
for i, (letter, entries) in enumerate(content):
|
||||
if i > 0:
|
||||
ret.append('\\indexspace' + CR)
|
||||
ret.append('\\bigletter{%s}' % self.escape(letter) + CR)
|
||||
ret.append(r'\indexspace' + CR)
|
||||
ret.append(r'\bigletter{%s}' % self.escape(letter) + CR)
|
||||
for entry in entries:
|
||||
if not entry[3]:
|
||||
continue
|
||||
ret.append('\\item\\relax\\sphinxstyleindexentry{%s}' %
|
||||
ret.append(r'\item\relax\sphinxstyleindexentry{%s}' %
|
||||
self.encode(entry[0]))
|
||||
if entry[4]:
|
||||
# add "extra" info
|
||||
ret.append('\\sphinxstyleindexextra{%s}' % self.encode(entry[4]))
|
||||
ret.append('\\sphinxstyleindexpageref{%s:%s}' %
|
||||
ret.append(r'\sphinxstyleindexextra{%s}' % self.encode(entry[4]))
|
||||
ret.append(r'\sphinxstyleindexpageref{%s:%s}' %
|
||||
(entry[2], self.idescape(entry[3])) + CR)
|
||||
ret.append('\\end{sphinxtheindex}' + CR)
|
||||
ret.append(r'\end{sphinxtheindex}' + CR)
|
||||
|
||||
ret = []
|
||||
# latex_domain_indices can be False/True or a list of index names
|
||||
@@ -534,7 +532,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.builder.docnames)
|
||||
if not content:
|
||||
continue
|
||||
ret.append('\\renewcommand{\\indexname}{%s}' % indexcls.localname + CR)
|
||||
ret.append(r'\renewcommand{\indexname}{%s}' % indexcls.localname + CR)
|
||||
generate(content, collapsed)
|
||||
|
||||
return ''.join(ret)
|
||||
@@ -564,7 +562,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.first_document = 0
|
||||
elif self.first_document == 0:
|
||||
# ... and all others are the appendices
|
||||
self.body.append(CR + '\\appendix' + CR)
|
||||
self.body.append(CR + r'\appendix' + CR)
|
||||
self.first_document = -1
|
||||
if 'docname' in node:
|
||||
self.body.append(self.hypertarget(':doc'))
|
||||
@@ -597,11 +595,11 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def visit_topic(self, node: Element) -> None:
|
||||
self.in_minipage = 1
|
||||
self.body.append(CR + '\\begin{sphinxShadowBox}' + CR)
|
||||
self.body.append(CR + r'\begin{sphinxShadowBox}' + CR)
|
||||
|
||||
def depart_topic(self, node: Element) -> None:
|
||||
self.in_minipage = 0
|
||||
self.body.append('\\end{sphinxShadowBox}' + CR)
|
||||
self.body.append(r'\end{sphinxShadowBox}' + CR)
|
||||
visit_sidebar = visit_topic
|
||||
depart_sidebar = depart_topic
|
||||
|
||||
@@ -613,20 +611,20 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def visit_productionlist(self, node: Element) -> None:
|
||||
self.body.append(BLANKLINE)
|
||||
self.body.append('\\begin{productionlist}' + CR)
|
||||
self.body.append(r'\begin{productionlist}' + CR)
|
||||
self.in_production_list = 1
|
||||
|
||||
def depart_productionlist(self, node: Element) -> None:
|
||||
self.body.append('\\end{productionlist}' + BLANKLINE)
|
||||
self.body.append(r'\end{productionlist}' + BLANKLINE)
|
||||
self.in_production_list = 0
|
||||
|
||||
def visit_production(self, node: Element) -> None:
|
||||
if node['tokenname']:
|
||||
tn = node['tokenname']
|
||||
self.body.append(self.hypertarget('grammar-token-' + tn))
|
||||
self.body.append('\\production{%s}{' % self.encode(tn))
|
||||
self.body.append(r'\production{%s}{' % self.encode(tn))
|
||||
else:
|
||||
self.body.append('\\productioncont{')
|
||||
self.body.append(r'\productioncont{')
|
||||
|
||||
def depart_production(self, node: Element) -> None:
|
||||
self.body.append('}' + CR)
|
||||
@@ -681,7 +679,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
logger.warning(__('encountered title node not in section, topic, table, '
|
||||
'admonition or sidebar'),
|
||||
location=node)
|
||||
self.body.append('\\sphinxstyleothertitle{')
|
||||
self.body.append(r'\sphinxstyleothertitle{')
|
||||
self.context.append('}' + CR)
|
||||
self.in_title = 1
|
||||
|
||||
@@ -694,7 +692,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def visit_subtitle(self, node: Element) -> None:
|
||||
if isinstance(node.parent, nodes.sidebar):
|
||||
self.body.append('\\sphinxstylesidebarsubtitle{')
|
||||
self.body.append(r'\sphinxstylesidebarsubtitle{')
|
||||
self.context.append('}' + CR)
|
||||
else:
|
||||
self.context.append('')
|
||||
@@ -705,18 +703,18 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def visit_desc(self, node: Element) -> None:
|
||||
if self.config.latex_show_urls == 'footnote':
|
||||
self.body.append(BLANKLINE)
|
||||
self.body.append('\\begin{savenotes}\\begin{fulllineitems}' + CR)
|
||||
self.body.append(r'\begin{savenotes}\begin{fulllineitems}' + CR)
|
||||
else:
|
||||
self.body.append(BLANKLINE)
|
||||
self.body.append('\\begin{fulllineitems}' + CR)
|
||||
self.body.append(r'\begin{fulllineitems}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_desc(self, node: Element) -> None:
|
||||
if self.config.latex_show_urls == 'footnote':
|
||||
self.body.append(CR + '\\end{fulllineitems}\\end{savenotes}' + BLANKLINE)
|
||||
self.body.append(CR + r'\end{fulllineitems}\end{savenotes}' + BLANKLINE)
|
||||
else:
|
||||
self.body.append(CR + '\\end{fulllineitems}' + BLANKLINE)
|
||||
self.body.append(CR + r'\end{fulllineitems}' + BLANKLINE)
|
||||
|
||||
def _visit_signature_line(self, node: Element) -> None:
|
||||
for child in node:
|
||||
@@ -739,14 +737,14 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self._visit_signature_line(node)
|
||||
else:
|
||||
self.body.append('%' + CR)
|
||||
self.body.append('\\pysigstartmultiline' + CR)
|
||||
self.body.append(r'\pysigstartmultiline' + CR)
|
||||
|
||||
def depart_desc_signature(self, node: Element) -> None:
|
||||
if not node.get('is_multiline'):
|
||||
self._depart_signature_line(node)
|
||||
else:
|
||||
self.body.append('%' + CR)
|
||||
self.body.append('\\pysigstopmultiline')
|
||||
self.body.append(r'\pysigstopmultiline')
|
||||
|
||||
def visit_desc_signature_line(self, node: Element) -> None:
|
||||
self._visit_signature_line(node)
|
||||
@@ -825,8 +823,8 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def visit_seealso(self, node: Element) -> None:
|
||||
self.body.append(BLANKLINE)
|
||||
self.body.append('\\sphinxstrong{%s:}' % admonitionlabels['seealso'] + CR)
|
||||
self.body.append('\\nopagebreak' + BLANKLINE)
|
||||
self.body.append(r'\sphinxstrong{%s:}' % admonitionlabels['seealso'] + CR)
|
||||
self.body.append(r'\nopagebreak' + BLANKLINE)
|
||||
|
||||
def depart_seealso(self, node: Element) -> None:
|
||||
self.body.append(BLANKLINE)
|
||||
@@ -834,7 +832,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def visit_rubric(self, node: Element) -> None:
|
||||
if len(node) == 1 and node.astext() in ('Footnotes', _('Footnotes')):
|
||||
raise nodes.SkipNode
|
||||
self.body.append('\\subsubsection*{')
|
||||
self.body.append(r'\subsubsection*{')
|
||||
self.context.append('}' + CR)
|
||||
self.in_title = 1
|
||||
|
||||
@@ -846,23 +844,23 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.in_footnote += 1
|
||||
label = cast(nodes.label, node[0])
|
||||
if 'auto' not in node:
|
||||
self.body.append('\\sphinxstepexplicit ')
|
||||
self.body.append(r'\sphinxstepexplicit ')
|
||||
if self.in_parsed_literal:
|
||||
self.body.append('\\begin{footnote}[%s]' % label.astext())
|
||||
self.body.append(r'\begin{footnote}[%s]' % label.astext())
|
||||
else:
|
||||
self.body.append('%' + CR)
|
||||
self.body.append('\\begin{footnote}[%s]' % label.astext())
|
||||
self.body.append(r'\begin{footnote}[%s]' % label.astext())
|
||||
if 'auto' not in node:
|
||||
self.body.append('\\phantomsection'
|
||||
'\\label{\\thesphinxscope.%s}%%' % label.astext() + CR)
|
||||
self.body.append('\\sphinxAtStartFootnote' + CR)
|
||||
self.body.append(r'\phantomsection'
|
||||
r'\label{\thesphinxscope.%s}%%' % label.astext() + CR)
|
||||
self.body.append(r'\sphinxAtStartFootnote' + CR)
|
||||
|
||||
def depart_footnote(self, node: Element) -> None:
|
||||
if self.in_parsed_literal:
|
||||
self.body.append('\\end{footnote}')
|
||||
self.body.append(r'\end{footnote}')
|
||||
else:
|
||||
self.body.append('%' + CR)
|
||||
self.body.append('\\end{footnote}')
|
||||
self.body.append(r'\end{footnote}')
|
||||
self.in_footnote -= 1
|
||||
|
||||
def visit_label(self, node: Element) -> None:
|
||||
@@ -950,25 +948,24 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.body.append('&')
|
||||
if cell.width == 1:
|
||||
# insert suitable strut for equalizing row heights in given multirow
|
||||
self.body.append('\\sphinxtablestrut{%d}' % cell.cell_id)
|
||||
self.body.append(r'\sphinxtablestrut{%d}' % cell.cell_id)
|
||||
else: # use \multicolumn for wide multirow cell
|
||||
self.body.append('\\multicolumn{%d}{|l|}'
|
||||
'{\\sphinxtablestrut{%d}}' %
|
||||
self.body.append(r'\multicolumn{%d}{|l|}\sphinxtablestrut{%d}}' %
|
||||
(cell.width, cell.cell_id))
|
||||
|
||||
def depart_row(self, node: Element) -> None:
|
||||
self.body.append('\\\\' + CR)
|
||||
self.body.append(r'\\' + CR)
|
||||
cells = [self.table.cell(self.table.row, i) for i in range(self.table.colcount)]
|
||||
underlined = [cell.row + cell.height == self.table.row + 1 for cell in cells]
|
||||
if all(underlined):
|
||||
self.body.append('\\hline')
|
||||
self.body.append(r'\hline')
|
||||
else:
|
||||
i = 0
|
||||
underlined.extend([False]) # sentinel
|
||||
while i < len(underlined):
|
||||
if underlined[i] is True:
|
||||
j = underlined[i:].index(False)
|
||||
self.body.append('\\cline{%d-%d}' % (i + 1, i + j))
|
||||
self.body.append(r'\cline{%d-%d}' % (i + 1, i + j))
|
||||
i += j
|
||||
i += 1
|
||||
self.table.row += 1
|
||||
@@ -982,22 +979,22 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if cell.width > 1:
|
||||
if self.config.latex_use_latex_multicolumn:
|
||||
if self.table.col == 0:
|
||||
self.body.append('\\multicolumn{%d}{|l|}{%%' % cell.width + CR)
|
||||
self.body.append(r'\multicolumn{%d}{|l|}{%%' % cell.width + CR)
|
||||
else:
|
||||
self.body.append('\\multicolumn{%d}{l|}{%%' % cell.width + CR)
|
||||
self.body.append(r'\multicolumn{%d}{l|}{%%' % cell.width + CR)
|
||||
context = '}%' + CR
|
||||
else:
|
||||
self.body.append('\\sphinxstartmulticolumn{%d}%%' % cell.width + CR)
|
||||
context = '\\sphinxstopmulticolumn' + CR
|
||||
self.body.append(r'\sphinxstartmulticolumn{%d}%%' % cell.width + CR)
|
||||
context = r'\sphinxstopmulticolumn' + CR
|
||||
if cell.height > 1:
|
||||
# \sphinxmultirow 2nd arg "cell_id" will serve as id for LaTeX macros as well
|
||||
self.body.append('\\sphinxmultirow{%d}{%d}{%%' % (cell.height, cell.cell_id) + CR)
|
||||
self.body.append(r'\sphinxmultirow{%d}{%d}{%%' % (cell.height, cell.cell_id) + CR)
|
||||
context = '}%' + CR + context
|
||||
if cell.width > 1 or cell.height > 1:
|
||||
self.body.append('\\begin{varwidth}[t]{\\sphinxcolwidth{%d}{%d}}'
|
||||
self.body.append(r'\begin{varwidth}[t]{\sphinxcolwidth{%d}{%d}}'
|
||||
% (cell.width, self.table.colcount) + CR)
|
||||
context = ('\\par' + CR + '\\vskip-\\baselineskip'
|
||||
'\\vbox{\\hbox{\\strut}}\\end{varwidth}%' + CR + context)
|
||||
context = (r'\par' + CR + r'\vskip-\baselineskip'
|
||||
r'\vbox{\hbox{\strut}}\end{varwidth}%' + CR + context)
|
||||
self.needs_linetrimming = 1
|
||||
if len(node.traverse(nodes.paragraph)) >= 2:
|
||||
self.table.has_oldproblematic = True
|
||||
@@ -1005,7 +1002,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if len(node) == 1 and isinstance(node[0], nodes.paragraph) and node.astext() == '':
|
||||
pass
|
||||
else:
|
||||
self.body.append('\\sphinxstyletheadfamily ')
|
||||
self.body.append(r'\sphinxstyletheadfamily ')
|
||||
if self.needs_linetrimming:
|
||||
self.pushbody([])
|
||||
self.context.append(context)
|
||||
@@ -1036,11 +1033,10 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if nextcell.width == 1:
|
||||
# insert suitable strut for equalizing row heights in multirow
|
||||
# they also serve to clear colour panels which would hide the text
|
||||
self.body.append('\\sphinxtablestrut{%d}' % nextcell.cell_id)
|
||||
self.body.append(r'\sphinxtablestrut{%d}' % nextcell.cell_id)
|
||||
else:
|
||||
# use \multicolumn for wide multirow cell
|
||||
self.body.append('\\multicolumn{%d}{l|}'
|
||||
'{\\sphinxtablestrut{%d}}' %
|
||||
self.body.append(r'\multicolumn{%d}{l|}{\sphinxtablestrut{%d}}' %
|
||||
(nextcell.width, nextcell.cell_id))
|
||||
|
||||
def visit_acks(self, node: Element) -> None:
|
||||
@@ -1055,13 +1051,13 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def visit_bullet_list(self, node: Element) -> None:
|
||||
if not self.compact_list:
|
||||
self.body.append('\\begin{itemize}' + CR)
|
||||
self.body.append(r'\begin{itemize}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_bullet_list(self, node: Element) -> None:
|
||||
if not self.compact_list:
|
||||
self.body.append('\\end{itemize}' + CR)
|
||||
self.body.append(r'\end{itemize}' + CR)
|
||||
|
||||
def visit_enumerated_list(self, node: Element) -> None:
|
||||
def get_enumtype(node: Element) -> str:
|
||||
@@ -1086,16 +1082,16 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
prefix = node.get('prefix', '')
|
||||
suffix = node.get('suffix', '.')
|
||||
|
||||
self.body.append('\\begin{enumerate}' + CR)
|
||||
self.body.append('\\sphinxsetlistlabels{%s}{%s}{%s}{%s}{%s}%%' %
|
||||
self.body.append(r'\begin{enumerate}' + CR)
|
||||
self.body.append(r'\sphinxsetlistlabels{%s}{%s}{%s}{%s}{%s}%%' %
|
||||
(style, enum, enumnext, prefix, suffix) + CR)
|
||||
if 'start' in node:
|
||||
self.body.append('\\setcounter{%s}{%d}' % (enum, node['start'] - 1) + CR)
|
||||
self.body.append(r'\setcounter{%s}{%d}' % (enum, node['start'] - 1) + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_enumerated_list(self, node: Element) -> None:
|
||||
self.body.append('\\end{enumerate}' + CR)
|
||||
self.body.append(r'\end{enumerate}' + CR)
|
||||
|
||||
def visit_list_item(self, node: Element) -> None:
|
||||
# Append "{}" in case the next character is "[", which would break
|
||||
@@ -1106,12 +1102,12 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.body.append(CR)
|
||||
|
||||
def visit_definition_list(self, node: Element) -> None:
|
||||
self.body.append('\\begin{description}' + CR)
|
||||
self.body.append(r'\begin{description}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_definition_list(self, node: Element) -> None:
|
||||
self.body.append('\\end{description}' + CR)
|
||||
self.body.append(r'\end{description}' + CR)
|
||||
|
||||
def visit_definition_list_item(self, node: Element) -> None:
|
||||
pass
|
||||
@@ -1123,11 +1119,11 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.in_term += 1
|
||||
ctx = ''
|
||||
if node.get('ids'):
|
||||
ctx = '\\phantomsection'
|
||||
ctx = r'\phantomsection'
|
||||
for node_id in node['ids']:
|
||||
ctx += self.hypertarget(node_id, anchor=False)
|
||||
ctx += '}] \\leavevmode'
|
||||
self.body.append('\\item[{')
|
||||
ctx += r'}] \leavevmode'
|
||||
self.body.append(r'\item[{')
|
||||
self.context.append(ctx)
|
||||
|
||||
def depart_term(self, node: Element) -> None:
|
||||
@@ -1147,12 +1143,12 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.body.append(CR)
|
||||
|
||||
def visit_field_list(self, node: Element) -> None:
|
||||
self.body.append('\\begin{quote}\\begin{description}' + CR)
|
||||
self.body.append(r'\begin{quote}\begin{description}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_field_list(self, node: Element) -> None:
|
||||
self.body.append('\\end{description}\\end{quote}' + CR)
|
||||
self.body.append(r'\end{description}\end{quote}' + CR)
|
||||
|
||||
def visit_field(self, node: Element) -> None:
|
||||
pass
|
||||
@@ -1172,7 +1168,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
not isinstance(node.parent[index - 1], nodes.paragraph) and
|
||||
not isinstance(node.parent[index - 1], nodes.compound)):
|
||||
# insert blank line, if the paragraph follows a non-paragraph node in a compound
|
||||
self.body.append('\\noindent' + CR)
|
||||
self.body.append(r'\noindent' + CR)
|
||||
elif index == 1 and isinstance(node.parent, (nodes.footnote, footnotetext)):
|
||||
# don't insert blank line, if the paragraph is second child of a footnote
|
||||
# (first one is label node)
|
||||
@@ -1181,33 +1177,33 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
# the \sphinxAtStartPar is to allow hyphenation of first word of
|
||||
# a paragraph in narrow contexts such as in a table cell
|
||||
# added as two items (cf. line trimming in depart_entry())
|
||||
self.body.extend([CR, '\\sphinxAtStartPar' + CR])
|
||||
self.body.extend([CR, r'\sphinxAtStartPar' + CR])
|
||||
|
||||
def depart_paragraph(self, node: Element) -> None:
|
||||
self.body.append(CR)
|
||||
|
||||
def visit_centered(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\begin{center}')
|
||||
self.body.append(CR + r'\begin{center}')
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_centered(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\end{center}')
|
||||
self.body.append(CR + r'\end{center}')
|
||||
|
||||
def visit_hlist(self, node: Element) -> None:
|
||||
self.compact_list += 1
|
||||
ncolumns = node['ncolumns']
|
||||
if self.compact_list > 1:
|
||||
self.body.append('\\setlength{\\multicolsep}{0pt}' + CR)
|
||||
self.body.append('\\begin{multicols}{' + ncolumns + '}\\raggedright' + CR)
|
||||
self.body.append('\\begin{itemize}\\setlength{\\itemsep}{0pt}'
|
||||
'\\setlength{\\parskip}{0pt}' + CR)
|
||||
self.body.append(r'\setlength{\multicolsep}{0pt}' + CR)
|
||||
self.body.append(r'\begin{multicols}{' + ncolumns + '}\raggedright' + CR)
|
||||
self.body.append(r'\begin{itemize}\setlength{\itemsep}{0pt}'
|
||||
r'\setlength{\parskip}{0pt}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_hlist(self, node: Element) -> None:
|
||||
self.compact_list -= 1
|
||||
self.body.append('\\end{itemize}\\raggedcolumns\\end{multicols}' + CR)
|
||||
self.body.append(r'\end{itemize}\raggedcolumns\end{multicols}' + CR)
|
||||
|
||||
def visit_hlistcol(self, node: Element) -> None:
|
||||
pass
|
||||
@@ -1217,7 +1213,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
# some testing with long items showed that columns may be too uneven.
|
||||
# And in case only of short items, the automatic column breaks should
|
||||
# match the ones pre-computed by the hlist() directive.
|
||||
# self.body.append('\\columnbreak\n')
|
||||
# self.body.append(r'\columnbreak\n')
|
||||
pass
|
||||
|
||||
def latex_image_length(self, width_str: str, scale: int = 100) -> str:
|
||||
@@ -1265,14 +1261,14 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
align_prepost = {
|
||||
# By default latex aligns the top of an image.
|
||||
(1, 'top'): ('', ''),
|
||||
(1, 'middle'): ('\\raisebox{-0.5\\height}{', '}'),
|
||||
(1, 'bottom'): ('\\raisebox{-\\height}{', '}'),
|
||||
(0, 'center'): ('{\\hspace*{\\fill}', '\\hspace*{\\fill}}'),
|
||||
(1, 'middle'): (r'\raisebox{-0.5\height}{', '}'),
|
||||
(1, 'bottom'): (r'\raisebox{-\height}{', '}'),
|
||||
(0, 'center'): (r'{\hspace*{\fill}', r'\hspace*{\fill}}'),
|
||||
# These 2 don't exactly do the right thing. The image should
|
||||
# be floated alongside the paragraph. See
|
||||
# https://www.w3.org/TR/html4/struct/objects.html#adef-align-IMG
|
||||
(0, 'left'): ('{', '\\hspace*{\\fill}}'),
|
||||
(0, 'right'): ('{\\hspace*{\\fill}', '}'),
|
||||
(0, 'left'): ('{', r'\hspace*{\fill}}'),
|
||||
(0, 'right'): (r'{\hspace*{\fill}', '}'),
|
||||
}
|
||||
try:
|
||||
pre.append(align_prepost[is_inline, node['align']][0])
|
||||
@@ -1280,10 +1276,10 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
except KeyError:
|
||||
pass
|
||||
if self.in_parsed_literal:
|
||||
pre.append('{\\sphinxunactivateextrasandspace ')
|
||||
pre.append(r'{\sphinxunactivateextrasandspace ')
|
||||
post.append('}')
|
||||
if not is_inline and not has_hyperlink:
|
||||
pre.append(CR + '\\noindent')
|
||||
pre.append(CR + r'\noindent')
|
||||
post.append(CR)
|
||||
pre.reverse()
|
||||
if node['uri'] in self.builder.images:
|
||||
@@ -1304,10 +1300,10 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if self.in_title and base:
|
||||
# Lowercase tokens forcely because some fncychap themes capitalize
|
||||
# the options of \sphinxincludegraphics unexpectly (ex. WIDTH=...).
|
||||
self.body.append('\\lowercase{\\sphinxincludegraphics%s}{{%s}%s}' %
|
||||
self.body.append(r'\lowercase{\sphinxincludegraphics%s}{{%s}%s}' %
|
||||
(options, base, ext))
|
||||
else:
|
||||
self.body.append('\\sphinxincludegraphics%s{{%s}%s}' %
|
||||
self.body.append(r'\sphinxincludegraphics%s{{%s}%s}' %
|
||||
(options, base, ext))
|
||||
self.body.extend(post)
|
||||
|
||||
@@ -1323,14 +1319,14 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if 'width' in node:
|
||||
length = self.latex_image_length(node['width'])
|
||||
if length:
|
||||
self.body.append('\\begin{sphinxfigure-in-table}[%s]' % length + CR)
|
||||
self.body.append('\\centering' + CR)
|
||||
self.body.append(r'\begin{sphinxfigure-in-table}[%s]' % length + CR)
|
||||
self.body.append(r'\centering' + CR)
|
||||
else:
|
||||
self.body.append('\\begin{sphinxfigure-in-table}' + CR)
|
||||
self.body.append('\\centering' + CR)
|
||||
self.body.append(r'\begin{sphinxfigure-in-table}' + CR)
|
||||
self.body.append(r'\centering' + CR)
|
||||
if any(isinstance(child, nodes.caption) for child in node):
|
||||
self.body.append('\\capstart')
|
||||
self.context.append('\\end{sphinxfigure-in-table}\\relax' + CR)
|
||||
self.body.append(r'\capstart')
|
||||
self.context.append(r'\end{sphinxfigure-in-table}\relax' + CR)
|
||||
elif node.get('align', '') in ('left', 'right'):
|
||||
length = None
|
||||
if 'width' in node:
|
||||
@@ -1339,19 +1335,19 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
length = self.latex_image_length(node[0]['width'])
|
||||
self.body.append(BLANKLINE) # Insert a blank line to prevent infinite loop
|
||||
# https://github.com/sphinx-doc/sphinx/issues/7059
|
||||
self.body.append('\\begin{wrapfigure}{%s}{%s}' %
|
||||
self.body.append(r'\begin{wrapfigure}{%s}{%s}' %
|
||||
('r' if node['align'] == 'right' else 'l', length or '0pt') + CR)
|
||||
self.body.append('\\centering')
|
||||
self.context.append('\\end{wrapfigure}' + CR)
|
||||
self.body.append(r'\centering')
|
||||
self.context.append(r'\end{wrapfigure}' + CR)
|
||||
elif self.in_minipage:
|
||||
self.body.append(CR + '\\begin{center}')
|
||||
self.context.append('\\end{center}' + CR)
|
||||
self.body.append(CR + r'\begin{center}')
|
||||
self.context.append(r'\end{center}' + CR)
|
||||
else:
|
||||
self.body.append(CR + '\\begin{figure}[%s]' % align + CR)
|
||||
self.body.append('\\centering' + CR)
|
||||
self.body.append(CR + r'\begin{figure}[%s]' % align + CR)
|
||||
self.body.append(r'\centering' + CR)
|
||||
if any(isinstance(child, nodes.caption) for child in node):
|
||||
self.body.append('\\capstart' + CR)
|
||||
self.context.append('\\end{figure}' + CR)
|
||||
self.body.append(r'\capstart' + CR)
|
||||
self.context.append(r'\end{figure}' + CR)
|
||||
|
||||
def depart_figure(self, node: Element) -> None:
|
||||
self.body.append(self.context.pop())
|
||||
@@ -1359,13 +1355,13 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def visit_caption(self, node: Element) -> None:
|
||||
self.in_caption += 1
|
||||
if isinstance(node.parent, captioned_literal_block):
|
||||
self.body.append('\\sphinxSetupCaptionForVerbatim{')
|
||||
self.body.append(r'\sphinxSetupCaptionForVerbatim{')
|
||||
elif self.in_minipage and isinstance(node.parent, nodes.figure):
|
||||
self.body.append('\\captionof{figure}{')
|
||||
self.body.append(r'\captionof{figure}{')
|
||||
elif self.table and node.parent.tagname == 'figure':
|
||||
self.body.append('\\sphinxfigcaption{')
|
||||
self.body.append(r'\sphinxfigcaption{')
|
||||
else:
|
||||
self.body.append('\\caption{')
|
||||
self.body.append(r'\caption{')
|
||||
|
||||
def depart_caption(self, node: Element) -> None:
|
||||
self.body.append('}')
|
||||
@@ -1375,27 +1371,27 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.in_caption -= 1
|
||||
|
||||
def visit_legend(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\begin{sphinxlegend}')
|
||||
self.body.append(CR + r'\begin{sphinxlegend}')
|
||||
|
||||
def depart_legend(self, node: Element) -> None:
|
||||
self.body.append('\\end{sphinxlegend}' + CR)
|
||||
self.body.append(r'\end{sphinxlegend}' + CR)
|
||||
|
||||
def visit_admonition(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\begin{sphinxadmonition}{note}')
|
||||
self.body.append(CR + r'\begin{sphinxadmonition}{note}')
|
||||
self.no_latex_floats += 1
|
||||
|
||||
def depart_admonition(self, node: Element) -> None:
|
||||
self.body.append('\\end{sphinxadmonition}' + CR)
|
||||
self.body.append(r'\end{sphinxadmonition}' + CR)
|
||||
self.no_latex_floats -= 1
|
||||
|
||||
def _visit_named_admonition(self, node: Element) -> None:
|
||||
label = admonitionlabels[node.tagname]
|
||||
self.body.append(CR + '\\begin{sphinxadmonition}{%s}{%s:}' %
|
||||
self.body.append(CR + r'\begin{sphinxadmonition}{%s}{%s:}' %
|
||||
(node.tagname, label))
|
||||
self.no_latex_floats += 1
|
||||
|
||||
def _depart_named_admonition(self, node: Element) -> None:
|
||||
self.body.append('\\end{sphinxadmonition}' + CR)
|
||||
self.body.append(r'\end{sphinxadmonition}' + CR)
|
||||
self.no_latex_floats -= 1
|
||||
|
||||
visit_attention = _visit_named_admonition
|
||||
@@ -1473,11 +1469,11 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
pass
|
||||
|
||||
def visit_attribution(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\begin{flushright}' + CR)
|
||||
self.body.append(CR + r'\begin{flushright}' + CR)
|
||||
self.body.append('---')
|
||||
|
||||
def depart_attribution(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\end{flushright}' + CR)
|
||||
self.body.append(CR + r'\end{flushright}' + CR)
|
||||
|
||||
def visit_index(self, node: Element) -> None:
|
||||
def escape(value: str) -> str:
|
||||
@@ -1495,7 +1491,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if match:
|
||||
return match.expand(r'\\spxentry{\1}\\spxextra{\2}')
|
||||
else:
|
||||
return '\\spxentry{%s}' % string
|
||||
return r'\spxentry{%s}' % string
|
||||
|
||||
if not node.get('inline', True):
|
||||
self.body.append(CR)
|
||||
@@ -1542,7 +1538,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
except ValueError as err:
|
||||
logger.warning(str(err))
|
||||
if not node.get('inline', True):
|
||||
self.body.append('\\ignorespaces ')
|
||||
self.body.append(r'\ignorespaces ')
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_raw(self, node: Element) -> None:
|
||||
@@ -1602,12 +1598,12 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
else:
|
||||
if len(node) == 1 and uri == node[0]:
|
||||
if node.get('nolinkurl'):
|
||||
self.body.append('\\sphinxnolinkurl{%s}' % self.encode_uri(uri))
|
||||
self.body.append(r'\sphinxnolinkurl{%s}' % self.encode_uri(uri))
|
||||
else:
|
||||
self.body.append('\\sphinxurl{%s}' % self.encode_uri(uri))
|
||||
self.body.append(r'\sphinxurl{%s}' % self.encode_uri(uri))
|
||||
raise nodes.SkipNode
|
||||
else:
|
||||
self.body.append('\\sphinxhref{%s}{' % self.encode_uri(uri))
|
||||
self.body.append(r'\sphinxhref{%s}{' % self.encode_uri(uri))
|
||||
self.context.append('}')
|
||||
|
||||
def depart_reference(self, node: Element) -> None:
|
||||
@@ -1621,16 +1617,16 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
else:
|
||||
id = node.get('refuri', '')[1:].replace('#', ':')
|
||||
|
||||
title = self.escape(node.get('title', '%s')).replace('\\%s', '%s')
|
||||
if '\\{name\\}' in title or '\\{number\\}' in title:
|
||||
title = self.escape(node.get('title', '%s')).replace(r'\%s', '%s')
|
||||
if r'\{name\}' in title or r'\{number\}' in title:
|
||||
# new style format (cf. "Fig.%{number}")
|
||||
title = title.replace('\\{name\\}', '{name}').replace('\\{number\\}', '{number}')
|
||||
text = escape_abbr(title).format(name='\\nameref{%s}' % self.idescape(id),
|
||||
number='\\ref{%s}' % self.idescape(id))
|
||||
title = title.replace(r'\{name\}', '{name}').replace(r'\{number\}', '{number}')
|
||||
text = escape_abbr(title).format(name=r'\nameref{%s}' % self.idescape(id),
|
||||
number=r'\ref{%s}' % self.idescape(id))
|
||||
else:
|
||||
# old style format (cf. "Fig.%{number}")
|
||||
text = escape_abbr(title) % ('\\ref{%s}' % self.idescape(id))
|
||||
hyperref = '\\hyperref[%s]{%s}' % (self.idescape(id), text)
|
||||
text = escape_abbr(title) % (r'\ref{%s}' % self.idescape(id))
|
||||
hyperref = r'\hyperref[%s]{%s}' % (self.idescape(id), text)
|
||||
self.body.append(hyperref)
|
||||
|
||||
raise nodes.SkipNode
|
||||
@@ -1704,15 +1700,15 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
# adjust max width of citation labels not to break the layout
|
||||
longest_label = longest_label[:MAX_CITATION_LABEL_LENGTH]
|
||||
|
||||
self.body.append(CR + '\\begin{sphinxthebibliography}{%s}' %
|
||||
self.body.append(CR + r'\begin{sphinxthebibliography}{%s}' %
|
||||
self.encode(longest_label) + CR)
|
||||
|
||||
def depart_thebibliography(self, node: Element) -> None:
|
||||
self.body.append('\\end{sphinxthebibliography}' + CR)
|
||||
self.body.append(r'\end{sphinxthebibliography}' + CR)
|
||||
|
||||
def visit_citation(self, node: Element) -> None:
|
||||
label = cast(nodes.label, node[0])
|
||||
self.body.append('\\bibitem[%s]{%s:%s}' % (self.encode(label.astext()),
|
||||
self.body.append(r'\bibitem[%s]{%s:%s}' % (self.encode(label.astext()),
|
||||
node['docname'], node['ids'][0]))
|
||||
|
||||
def depart_citation(self, node: Element) -> None:
|
||||
@@ -1722,7 +1718,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if self.in_title:
|
||||
pass
|
||||
else:
|
||||
self.body.append('\\sphinxcite{%s:%s}' % (node['docname'], node['refname']))
|
||||
self.body.append(r'\sphinxcite{%s:%s}' % (node['docname'], node['refname']))
|
||||
raise nodes.SkipNode
|
||||
|
||||
def depart_citation_reference(self, node: Element) -> None:
|
||||
@@ -1743,7 +1739,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_footnotemark(self, node: Element) -> None:
|
||||
self.body.append('\\sphinxfootnotemark[')
|
||||
self.body.append(r'\sphinxfootnotemark[')
|
||||
|
||||
def depart_footnotemark(self, node: Element) -> None:
|
||||
self.body.append(']')
|
||||
@@ -1751,15 +1747,15 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def visit_footnotetext(self, node: Element) -> None:
|
||||
label = cast(nodes.label, node[0])
|
||||
self.body.append('%' + CR)
|
||||
self.body.append('\\begin{footnotetext}[%s]'
|
||||
'\\phantomsection\\label{\\thesphinxscope.%s}%%'
|
||||
self.body.append(r'\begin{footnotetext}[%s]'
|
||||
r'\phantomsection\label{\thesphinxscope.%s}%%'
|
||||
% (label.astext(), label.astext()) + CR)
|
||||
self.body.append('\\sphinxAtStartFootnote' + CR)
|
||||
self.body.append(r'\sphinxAtStartFootnote' + CR)
|
||||
|
||||
def depart_footnotetext(self, node: Element) -> None:
|
||||
# the \ignorespaces in particular for after table header use
|
||||
self.body.append('%' + CR)
|
||||
self.body.append('\\end{footnotetext}\\ignorespaces ')
|
||||
self.body.append(r'\end{footnotetext}\ignorespaces ')
|
||||
|
||||
def visit_captioned_literal_block(self, node: Element) -> None:
|
||||
pass
|
||||
@@ -1771,13 +1767,13 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if node.rawsource != node.astext():
|
||||
# most probably a parsed-literal block -- don't highlight
|
||||
self.in_parsed_literal += 1
|
||||
self.body.append('\\begin{sphinxalltt}' + CR)
|
||||
self.body.append(r'\begin{sphinxalltt}' + CR)
|
||||
else:
|
||||
labels = self.hypertarget_to(node)
|
||||
if isinstance(node.parent, captioned_literal_block):
|
||||
labels += self.hypertarget_to(node.parent)
|
||||
if labels and not self.in_footnote:
|
||||
self.body.append(CR + '\\def\\sphinxLiteralBlockLabel{' + labels + '}')
|
||||
self.body.append(CR + r'\def\sphinxLiteralBlockLabel{' + labels + '}')
|
||||
|
||||
lang = node.get('language', 'default')
|
||||
linenos = node.get('linenos', False)
|
||||
@@ -1790,57 +1786,57 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
location=node, **highlight_args
|
||||
)
|
||||
if self.in_footnote:
|
||||
self.body.append(CR + '\\sphinxSetupCodeBlockInFootnote')
|
||||
hlcode = hlcode.replace('\\begin{Verbatim}',
|
||||
'\\begin{sphinxVerbatim}')
|
||||
self.body.append(CR + r'\sphinxSetupCodeBlockInFootnote')
|
||||
hlcode = hlcode.replace(r'\begin{Verbatim}',
|
||||
r'\begin{sphinxVerbatim}')
|
||||
# if in table raise verbatim flag to avoid "tabulary" environment
|
||||
# and opt for sphinxVerbatimintable to handle caption & long lines
|
||||
elif self.table:
|
||||
self.table.has_problematic = True
|
||||
self.table.has_verbatim = True
|
||||
hlcode = hlcode.replace('\\begin{Verbatim}',
|
||||
'\\begin{sphinxVerbatimintable}')
|
||||
hlcode = hlcode.replace(r'\begin{Verbatim}',
|
||||
r'\begin{sphinxVerbatimintable}')
|
||||
else:
|
||||
hlcode = hlcode.replace('\\begin{Verbatim}',
|
||||
'\\begin{sphinxVerbatim}')
|
||||
hlcode = hlcode.replace(r'\begin{Verbatim}',
|
||||
r'\begin{sphinxVerbatim}')
|
||||
# get consistent trailer
|
||||
hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
|
||||
if self.table and not self.in_footnote:
|
||||
hlcode += '\\end{sphinxVerbatimintable}'
|
||||
hlcode += r'\end{sphinxVerbatimintable}'
|
||||
else:
|
||||
hlcode += '\\end{sphinxVerbatim}'
|
||||
hlcode += r'\end{sphinxVerbatim}'
|
||||
|
||||
hllines = str(highlight_args.get('hl_lines', []))[1:-1]
|
||||
if hllines:
|
||||
self.body.append(CR + '\\fvset{hllines={, %s,}}%%' % hllines)
|
||||
self.body.append(CR + r'\fvset{hllines={, %s,}}%%' % hllines)
|
||||
self.body.append(CR + hlcode + CR)
|
||||
if hllines:
|
||||
self.body.append('\\sphinxresetverbatimhllines' + CR)
|
||||
self.body.append(r'\sphinxresetverbatimhllines' + CR)
|
||||
raise nodes.SkipNode
|
||||
|
||||
def depart_literal_block(self, node: Element) -> None:
|
||||
self.body.append(CR + '\\end{sphinxalltt}' + CR)
|
||||
self.body.append(CR + r'\end{sphinxalltt}' + CR)
|
||||
self.in_parsed_literal -= 1
|
||||
visit_doctest_block = visit_literal_block
|
||||
depart_doctest_block = depart_literal_block
|
||||
|
||||
def visit_line(self, node: Element) -> None:
|
||||
self.body.append('\\item[] ')
|
||||
self.body.append(r'\item[] ')
|
||||
|
||||
def depart_line(self, node: Element) -> None:
|
||||
self.body.append(CR)
|
||||
|
||||
def visit_line_block(self, node: Element) -> None:
|
||||
if isinstance(node.parent, nodes.line_block):
|
||||
self.body.append('\\item[]' + CR)
|
||||
self.body.append('\\begin{DUlineblock}{\\DUlineblockindent}' + CR)
|
||||
self.body.append(r'\item[]' + CR)
|
||||
self.body.append(r'\begin{DUlineblock}{\DUlineblockindent}' + CR)
|
||||
else:
|
||||
self.body.append(CR + '\\begin{DUlineblock}{0em}' + CR)
|
||||
self.body.append(CR + r'\begin{DUlineblock}{0em}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_line_block(self, node: Element) -> None:
|
||||
self.body.append('\\end{DUlineblock}' + CR)
|
||||
self.body.append(r'\end{DUlineblock}' + CR)
|
||||
|
||||
def visit_block_quote(self, node: Element) -> None:
|
||||
# If the block quote contains a single object and that object
|
||||
@@ -1853,7 +1849,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
isinstance(child, nodes.enumerated_list):
|
||||
done = 1
|
||||
if not done:
|
||||
self.body.append('\\begin{quote}' + CR)
|
||||
self.body.append(r'\begin{quote}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
@@ -1865,7 +1861,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
isinstance(child, nodes.enumerated_list):
|
||||
done = 1
|
||||
if not done:
|
||||
self.body.append('\\end{quote}' + CR)
|
||||
self.body.append(r'\end{quote}' + CR)
|
||||
|
||||
# option node handling copied from docutils' latex writer
|
||||
|
||||
@@ -1886,7 +1882,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
pass
|
||||
|
||||
def visit_option_group(self, node: Element) -> None:
|
||||
self.body.append('\\item [')
|
||||
self.body.append(r'\item [')
|
||||
# flag for first option
|
||||
self.context.append(0)
|
||||
|
||||
@@ -1895,12 +1891,12 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
self.body.append('] ')
|
||||
|
||||
def visit_option_list(self, node: Element) -> None:
|
||||
self.body.append('\\begin{optionlist}{3cm}' + CR)
|
||||
self.body.append(r'\begin{optionlist}{3cm}' + CR)
|
||||
if self.table:
|
||||
self.table.has_problematic = True
|
||||
|
||||
def depart_option_list(self, node: Element) -> None:
|
||||
self.body.append('\\end{optionlist}' + CR)
|
||||
self.body.append(r'\end{optionlist}' + CR)
|
||||
|
||||
def visit_option_list_item(self, node: Element) -> None:
|
||||
pass
|
||||
@@ -1920,13 +1916,13 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
pass
|
||||
|
||||
def visit_superscript(self, node: Element) -> None:
|
||||
self.body.append('$^{\\text{')
|
||||
self.body.append(r'$^{\text{')
|
||||
|
||||
def depart_superscript(self, node: Element) -> None:
|
||||
self.body.append('}}$')
|
||||
|
||||
def visit_subscript(self, node: Element) -> None:
|
||||
self.body.append('$_{\\text{')
|
||||
self.body.append(r'$_{\text{')
|
||||
|
||||
def depart_subscript(self, node: Element) -> None:
|
||||
self.body.append('}}$')
|
||||
@@ -1993,7 +1989,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if self.literal_whitespace:
|
||||
# Insert a blank before the newline, to avoid
|
||||
# ! LaTeX Error: There's no line here to end.
|
||||
text = text.replace(CR, '~\\\\' + CR).replace(' ', '~')
|
||||
text = text.replace(CR, r'~\\' + CR).replace(' ', '~')
|
||||
return text
|
||||
|
||||
def encode_uri(self, text: str) -> str:
|
||||
@@ -2001,9 +1997,9 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
# this must be checked against hyperref package exact dealings
|
||||
# mainly, %, #, {, } and \ need escaping via a \ escape
|
||||
# in \href, the tilde is allowed and must be represented literally
|
||||
return self.encode(text).replace('\\textasciitilde{}', '~').\
|
||||
replace('\\sphinxhyphen{}', '-').\
|
||||
replace('\\textquotesingle{}', "'")
|
||||
return self.encode(text).replace(r'\textasciitilde{}', '~').\
|
||||
replace(r'\sphinxhyphen{}', '-').\
|
||||
replace(r'\textquotesingle{}', "'")
|
||||
|
||||
def visit_Text(self, node: Text) -> None:
|
||||
text = self.encode(node.astext())
|
||||
|
||||
Reference in New Issue
Block a user