Open Freakwill opened 5 years ago
I'm interested in this. Will you be willing to write a renderer for this, preferably in pylatex_renderer
, so that people who do not want to install an additional package have the default latex_renderer
to fallback on?
If not, I can also look into this in a few. Thanks for the suggestion!
Following is just an attempt, not applying all features of pylatex
, such as package propagating, there must be a better one.
pylatex_renderer.py
:
# -*- coding: utf-8 -*-
"""
LaTeX renderer for mistletoe with pylatex.
"""
import mistletoe.latex_token as latex_token
from mistletoe.base_renderer import BaseRenderer
from pylatex import *
from pylatex.base_classes import *
from pylatex.utils import *
class PyLaTeXRenderer(BaseRenderer):
def __init__(self, *extras):
"""
Args:
extras (list): allows subclasses to add even more custom tokens.
"""
tokens = self._tokens_from_module(latex_token)
self.packages = []
super().__init__(*tokens, *extras)
def render_strong(self, token):
return bold(self.render_inner(token))
def render_emphasis(self, token):
return Command('textit', arguments=self.render_inner(token))
def render_inline_code(self, token):
return verbatim(self.render_inner(token))
def render_strikethrough(self, token):
self.packages.append(Package('ulem', options='normalem'))
return Command('sout', data=self.render_inner(token))
def render_image(self, token):
self.packages.append(Package('graphicx'))
return StandAloneGraphic(token.src)
def render_link(self, token):
self.packages.append(Package('hyperref'))
inner = self.render_inner(token)
return Command('href', arguments=[token.target, inner])
def render_auto_link(self, token):
self.packages.append(Package('hyperref'))
return Command('url', token.target)
@staticmethod
def render_math(token):
return token.content
def render_escape_sequence(self, token):
return self.render_inner(token)
def render_raw_text(self, token, escape=True):
return escape_latex(token.content) if escape else token.content
def render_heading(self, token):
inner = self.render_inner(token)
if token.level == 1:
return Section(inner)
elif token.level == 2:
return Subsection(inner)
return Subsubsection(inner)
def render_quote(self, token):
self.packages.append(Package('csquotes'))
class displayquote(Environment):
packages = ['csquotes']
data=self.render_inner(token)
return displayquote.dumps()
def render_paragraph(self, token):
return '\n{}\n'.format(self.render_inner(token))
def render_block_code(self, token):
self.packages.append(Package('listings'))
class lstlisting(Environment):
packages = ['listings']
options = Options(f'language={token.language}')
data=[self.render_raw_text(token.children[0], False)]
return lstlisting.dumps()
def render_list(self, token):
self.packages.append(Package('listings'))
tag = Enumerate if token.start is not None else Itemize
return tag(data=self.render_inner(token))
def render_list_item(self, token):
return self.render_inner(token)
def render_table(self, token):
def render_align(column_align):
if column_align != [None]:
return ''.join(map(get_align, token.column_align))
else:
return ''
def get_align(col):
if col is None:
return 'l'
elif col == 0:
return 'c'
elif col == 1:
return 'r'
raise RuntimeError('Unrecognized align option: ' + col)
if hasattr(token, 'header'):
head_inner = self.render_table_row(token.header)
tab.add_row(head_inner)
tab.add_hline()
inner = self.render_inner(token)
align = render_align(token.column_align)
tab = Tabular(align)
tab.add_row(inner)
return tab.dumps()
def render_table_row(self, token):
return dumps_list(token.children, token='&', mapper=self.render)
def render_table_cell(self, token):
return self.render_inner(token)
@staticmethod
def render_thematic_break(token):
return Command('hrulefill').dumps()
@staticmethod
def render_line_break(token):
return '\n' if token.soft else Command('newline').dumps()+'\n'
def render_document(self, token):
self.footnotes.update(token.footnotes)
with Document(packages=self.packages) as doc:
doc.data=self.render_inner(token)
return doc.dumps()
Pylatex
can produce more pretty latex codes.