Skip to content

Commit c5ec06f

Browse files
committed
some fixes for verbatim commands
1 parent 19d6665 commit c5ec06f

5 files changed

Lines changed: 173 additions & 44 deletions

File tree

‎flm/feature/headings.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ def recompose_pure_latex(self, node, recomposer):
107107

108108
heading_macroname = node.macroname
109109

110-
recopt_cells = recomposer.get_options('headings')
111-
heading_macroname_mapping = recopt_cells.get('macroname_mapping', None)
110+
recopt_headings = recomposer.get_options('headings')
111+
heading_macroname_mapping = recopt_headings.get('macroname_mapping', None)
112112
if heading_macroname_mapping:
113113
if heading_macroname in heading_macroname_mapping:
114114
heading_macroname = heading_macroname_mapping[heading_macroname]

‎flm/feature/verbatim.py‎

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
from pylatexenc.latexnodes import ParsedArgumentsInfo
24
from pylatexenc.latexnodes import parsers as latexnodes_parsers
35
from pylatexenc.latexnodes import nodes as latexnodes_nodes
@@ -45,12 +47,11 @@ def make_body_parser(self, token, nodeargd, arg_parsing_state_delta):
4547
environment_name=environment_name
4648
)
4749

48-
def render(self, node, render_context):
4950

50-
# environment_node_name = None
51+
def _get_verbatim_contents_info(self, node):
5152

5253
verbatim_lang = None
53-
54+
verbatim_contents = None
5455
is_inline = False
5556
is_environment = False
5657

@@ -89,6 +90,23 @@ def render(self, node, render_context):
8990
if 'verbatim_lang' in node_args:
9091
verbatim_lang = node_args['verbatim_lang'].get_content_as_chars()
9192

93+
return {
94+
'is_inline': is_inline,
95+
'is_environment': is_environment,
96+
'verbatim_contents': verbatim_contents,
97+
'verbatim_lang': verbatim_lang
98+
}
99+
100+
def render(self, node, render_context):
101+
102+
# environment_node_name = None
103+
104+
verbatim_info = self._get_verbatim_contents_info(node)
105+
is_inline = verbatim_info['is_inline']
106+
is_environment = verbatim_info['is_environment']
107+
verbatim_contents = verbatim_info['verbatim_contents']
108+
verbatim_lang = verbatim_info['verbatim_lang']
109+
92110
annotations = self.annotations or []
93111

94112
if self.verbatimtype is not None:
@@ -108,6 +126,36 @@ def render(self, node, render_context):
108126
annotations=annotations,
109127
)
110128

129+
def recompose_pure_latex(self, node, recomposer):
130+
131+
recopt_verbatim = recomposer.get_options('verbatim')
132+
use_fvextra = recopt_verbatim.get('use_fvextra', None)
133+
134+
if not use_fvextra:
135+
return False # ‘False’ means fall back onto standard recomposing method
136+
137+
verbatim_info = self._get_verbatim_contents_info(node)
138+
is_inline = verbatim_info['is_inline']
139+
is_environment = verbatim_info['is_environment']
140+
verbatim_contents = verbatim_info['verbatim_contents']
141+
verbatim_lang = verbatim_info['verbatim_lang']
142+
143+
if is_environment:
144+
return False # use standard method for environments
145+
146+
recomposer.ensure_latex_package('fvextra')
147+
148+
content_escaped = re.sub(r'[^a-zA-Z0-9]', lambda m: '\\'+m.group(), verbatim_contents)
149+
150+
recomposed = (
151+
r'\EscVerb[formatcom=\flmFmtVRB{'+node.macroname+r'}]{'
152+
+ content_escaped
153+
+ '}'
154+
)
155+
156+
return recomposed
157+
158+
111159
# FLM-doc
112160

113161
def get_flm_doc(self):

‎flm/flmrecomposer/purelatex.py‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,20 @@ def recompose_delimited_nodelist(self, delimiters, nodelist, n):
463463
\providecommand\flmInlineVerbatimFormatDefault[1]{#1}
464464
465465
466-
\def\verba{\flmInlineVerb{\itshape}{}}
467-
\def\verbtext{\flmInlineVerb{}{}}
468-
\def\verbcode{\flmInlineVerb{\ttfamily}{}}
466+
\def\flmFmtVRBverba{\itshape}
467+
\def\flmFmtVRBverbtext{}
468+
\def\flmFmtVRBverbcode{\ttfamily}
469+
\def\flmFmtVRB#1{%
470+
\ifcsname flmFmtVRB#1\endcsname
471+
\csname flmFmtVRB#1\endcsname
472+
\else
473+
\flmFmtVRBverbcode
474+
\fi
475+
}
476+
477+
\def\verba{\flmInlineVerb{\flmFmtVRBverba}{}}
478+
\def\verbtext{\flmInlineVerb{\flmFmtVRBverbtext}{}}
479+
\def\verbcode{\flmInlineVerb{\flmFmtVRBverbcode}{}}
469480
470481
471482
"""

‎flm/fragmentrenderer/latex.py‎

Lines changed: 86 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ def render_verbatim(self, value, render_context, *,
196196
is_block_level=False, annotations=None, target_id=None):
197197
if 'verbatimcode' in annotations:
198198
return r'\begin{verbatim}' + '\n' + value + r'\end{verbatim}'
199+
# TODO: Maybe provide an interface to use \EscVerb here?? (cf fvextra latex package)
199200
# what to do with annotations / target_id ??
200201
if self.latex_wrap_verbatim_macro:
201202
return "\\" + self.latex_wrap_verbatim_macro + "{" + self.latexescape(value) + "}"
@@ -615,6 +616,9 @@ def collect_graphics_resource(self, graphics_resource, render_context):
615616
return graphics_resource.src_url, whoptc
616617

617618

619+
cells_max_width_latexdim = r'0.96\linewidth'
620+
cells_render_method = 'fit_width_test'
621+
618622
def render_cells(self, cells_model, render_context, target_id=None,
619623
render_cell_nodelist_contents_fn=None):
620624

@@ -717,44 +721,94 @@ def render_cells(self, cells_model, render_context, target_id=None,
717721

718722
stab_contents += '&'.join(stab_rowitems) + '\\\\' + '\n'
719723

720-
s = (
721-
r'\flmCellsBeginCenter' + '\n'
724+
def _typeset_table_contents(raw_args=None, colspec_one=None):
725+
if raw_args is not None:
726+
tblrargs = raw_args
727+
else:
728+
tblrargs = r'colspec={' + (colspec_one * tabwidth) + r'}'
729+
return (
730+
r'\begin{tblr}{' + tblrargs + r',' + '\n'
731+
+ r' hspan=minimal'
732+
+ cell_spans_styles
733+
+ "".join([ ",\n hline{"+rownrng+"}={"+colnrng+"}{"+lsty+"}"
734+
for (rownrng, colnrng, lsty) in cell_hlines ])
735+
+ "".join([ ",\n vline{"+colnrng+"}={"+rownrng+"}{"+lsty+"}"
736+
for (rownrng, colnrng, lsty) in cell_vlines ])
737+
+ r'}%' + '\n'
738+
+ r'\toprule'
739+
+ '\n'
740+
+ stab_contents
741+
+ r'\bottomrule' + '\n'
742+
+ r'\end{tblr}%' + '\n'
743+
)
744+
745+
if self.cells_render_method == 'simple':
746+
s = (
747+
r'\flmCellsBeginCenter' + '\n'
748+
+ _typeset_table_contents(colspec_one='c')
749+
+ r'\flmCellsEndCenter '
750+
)
751+
return s
752+
753+
if self.cells_render_method == 'fit_width_test':
754+
# Hack for automatic width detection -- typeset table once with 'c'
755+
# column types; if the width exceeds a maximum set width
756+
# (0.96\linewidth), then re-typeset the table with 'X[-1]' column
757+
# types. Store the typesetting code in a macro to be more compact.
758+
s = (
759+
r'\flmCellsBeginCenter' + '\n'
760+
+ r'\long\def\flmTempTypesetThisTable#1{%' + '\n'
761+
+ _typeset_table_contents(raw_args='#1')
762+
+ r'}%' + '\n'
763+
)
764+
# now, the code to automatically detect the correct width
765+
s += (
766+
r'\def\flmTmpMaxW{\dimexpr ' + self.cells_max_width_latexdim
767+
+ r'\relax}%' + '\n'
768+
+ r'\setbox0=\hbox{\flmTempTypesetThisTable{colspec={'
769+
+ ('c' * tabwidth) + r'}}}%' + '\n'
770+
+ r'\ifdim\wd0<\flmTmpMaxW\relax' + '\n'
771+
+ r' \leavevmode\box0 ' + '\n'
772+
+ r'\else' + '\n'
773+
+ r' \flmTempTypesetThisTable{width=\flmTmpMaxW,colspec={'
774+
+ ('X[-1]' * tabwidth) + r'}}' + '\n'
775+
+ r'\fi' + '\n'
776+
)
777+
s += r'\flmCellsEndCenter '
778+
return s
779+
780+
if self.cells_render_method == 'fit_width_test_dupl':
722781
# Hack for automatic width detection -- typeset table once with 'c'
723782
# column types; if the width exceeds a maximum set width
724783
# (0.96\linewidth), then re-typeset the table with 'X[-1]' column
725784
# types.
726-
r'\long\def\flmTempTypesetThisTable#1{%' + '\n'
727-
r'\begin{tblr}{#1,' + '\n' + r' hspan=minimal'
728-
+ cell_spans_styles
729-
+ "".join([ ",\n hline{"+rownrng+"}={"+colnrng+"}{"+lsty+"}"
730-
for (rownrng, colnrng, lsty) in cell_hlines ])
731-
+ "".join([ ",\n vline{"+colnrng+"}={"+rownrng+"}{"+lsty+"}"
732-
for (rownrng, colnrng, lsty) in cell_vlines ])
733-
+ r'}' + '\n'
734-
+ r'\toprule'
735-
+ '\n'
736-
)
737-
s += stab_contents
738-
s += r'\bottomrule' + '\n'
739-
s += r'\end{tblr}%' + '\n'
740-
s += r'}%' + '\n'
741-
# now, the code to automatically detect the correct width
742-
s += (
743-
r'\def\flmTmpMaxW{\dimexpr ' + self.max_table_width_latexdim + r'\relax}%' + '\n'
744-
+ r'\setbox0=\hbox{\flmTempTypesetThisTable{colspec={'
745-
+ ('c' * tabwidth) + r'}}}%' + '\n'
746-
+ r'\ifdim\wd0<\flmTmpMaxW\relax' + '\n'
747-
+ r' \leavevmode\box0 ' + '\n'
748-
+ r'\else' + '\n'
749-
+ r' \flmTempTypesetThisTable{width=\flmTmpMaxW,colspec={'
750-
+ ('X[-1]' * tabwidth) + r'}}' + '\n'
751-
+ r'\fi' + '\n'
752-
)
753-
s += r'\flmCellsEndCenter '
785+
#
786+
# But paste the code to typeset the table *TWICE* so that we do not
787+
# have to use this ugly \def hack. (Originally I thought that this
788+
# would enable us to use fragile commands like \verba{...} (like
789+
# \verb+...+) inside the table contents. But it doesn't work,
790+
# probably because of tblr itself.)
791+
s = (
792+
r'\flmCellsBeginCenter' + '\n'
793+
+ r'\def\flmTmpMaxW{\dimexpr ' + self.cells_max_width_latexdim
794+
+ r'\relax}%' + '\n'
795+
+ r'\setbox0=\hbox\bgroup'
796+
+ _typeset_table_contents(colspec_one='c')
797+
+ r'\egroup' + '\n'
798+
+ r'\ifdim\wd0<\flmTmpMaxW\relax' + '\n'
799+
+ r' \leavevmode\box0 ' + '\n'
800+
+ r'\else' + '\n'
801+
# Failed to typeset the table in the available width, try
802+
# variable sizing instead.
803+
+ _typeset_table_contents(colspec_one='X[-1]')
804+
+ r'\fi' + '\n'
805+
+ r'\flmCellsEndCenter '
806+
)
807+
return s
808+
809+
raise ValueError("Invalid cells_render_method: "+repr(self.cells_render_method))
754810

755-
return s
756811

757-
max_table_width_latexdim = r'0.96\linewidth'
758812

759813
# ------------------
760814

‎playground/mydraftforatable3.flm‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ flm:
55
comment_start: '%%'
66
features:
77
'flm.feature.cells.FeatureCells': true
8+
9+
renderer:
10+
latex:
11+
#cells_render_method: 'simple'
12+
cells_render_method: 'fit_width_test'
13+
#cells_render_method: 'fit_width_test_dupl'
14+
15+
workflow_config:
16+
flmlatex:
17+
recomposer_options:
18+
verbatim:
19+
use_fvextra: True
820
#$
921
---
1022

@@ -120,10 +132,6 @@ A & B & C \\
120132

121133

122134

123-
124-
125-
126-
127135
\begin{cells}
128136
\celldata<H c>{ One Heading & Two Headings & Three Headings }
129137
\celldata<c>[-]{
@@ -133,3 +141,11 @@ A & B this is a really long cell with tons of content! We can add more content a
133141
\cell<green>{X}
134142
\cell<yellow>[\merge{+2}]{YZ}
135143
\end{cells}
144+
145+
146+
147+
\begin{cells}
148+
\celldata<H c>{One & Two}
149+
\celldata<l>{Hi there & \verba{test_fragile_command} }
150+
\end{cells}
151+

0 commit comments

Comments
 (0)