Skip to content

Instantly share code, notes, and snippets.

@tobydriscoll
Created August 4, 2021 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobydriscoll/b5049a7e4e74bde0bfa69ad8ac98ee87 to your computer and use it in GitHub Desktop.
Save tobydriscoll/b5049a7e4e74bde0bfa69ad8ac98ee87 to your computer and use it in GitHub Desktop.
Hacking sphinx for jupyterbook-latex
from sphinx.writers.latex import LaTeXTranslator
from docutils import nodes, writers
from docutils.nodes import Element, Node, Text
from sphinx.builders.latex.nodes import captioned_literal_block
CR = '\n'
class MyTranslator(LaTeXTranslator):
def visit_literal_block(self, node: Element) -> None:
if node.rawsource != node.astext():
# most probably a parsed-literal block -- don't highlight
self.in_parsed_literal += 1
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 + r'\def\sphinxLiteralBlockLabel{' + labels + '}')
lang = node.get('language', 'default')
linenos = node.get('linenos', False)
highlight_args = node.get('highlight_args', {})
highlight_args['force'] = node.get('force', False)
opts = self.config.highlight_options.get(lang, {})
hlcode = self.highlighter.highlight_block(
node.rawsource, lang, opts=opts, linenos=linenos,
location=node, **highlight_args
)
if self.in_footnote:
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(r'\begin{Verbatim}',
r'\begin{sphinxVerbatimintable}')
elif "output" in node['classes']:
hlcode = hlcode.replace(r'\begin{Verbatim}',
r'\begin{sphinxVerbatimOutput}')
elif "input" in node['classes']:
hlcode = hlcode.replace(r'\begin{Verbatim}',
r'\begin{sphinxVerbatimInput}')
else:
hlcode = hlcode.replace(r'\begin{Verbatim}',
r'\begin{sphinxVerbatim}')
# hlcode += ''.join(node["classes"])
# get consistent trailer
hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
if self.table and not self.in_footnote:
hlcode += r'\end{sphinxVerbatimintable}'
elif "output" in node["classes"]:
hlcode += r'\end{sphinxVerbatimOutput}'
else:
hlcode += r'\end{sphinxVerbatim}'
hllines = str(highlight_args.get('hl_lines', []))[1:-1]
if hllines:
self.body.append(CR + r'\fvset{hllines={, %s,}}%%' % hllines)
self.body.append(CR + hlcode + CR)
if hllines:
self.body.append(r'\sphinxresetverbatimhllines' + CR)
raise nodes.SkipNode
@JRRudy1
Copy link

JRRudy1 commented Aug 3, 2022

Would you mind pointing me in the right direction on how to use this? I am pulling my hair out trying to figure out the sphinxVerbatim errors that this appears to solve, but I can't find information anywhere on how to specify a custom LatexTranslator class for Jupyter-book to use. Any help would be greatly appreciated! Thanks

@tobydriscoll
Copy link
Author

Have a look at this discussion. My comment describes how I used it. My understanding is that sphinx adopted some form of enabling the same functionality, but I could be wrong about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment