diff --git a/examples/Makefile b/examples/Makefile index c56ad2c17..e084a9a75 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -5,7 +5,7 @@ AUXFILES=*.tmp *.tui *.tuo *.mp *.tuc *.markdown.in *.markdown.out \ AUXDIRS=_markdown_*/ LUACLI_OPTIONS=hashEnumerators=true definitionLists=true footnotes=true \ inlineFootnotes=true smartEllipses=true fencedCode=true contentBlocks=true \ - pipeTables=true + pipeTables=true tableCaptions=true OUTPUT=context-mkii.pdf context-mkiv.pdf latex-pdftex.pdf \ latex-luatex.pdf latex-xetex.pdf diff --git a/examples/context.tex b/examples/context.tex index c1a9a3ddc..7ed432344 100644 --- a/examples/context.tex +++ b/examples/context.tex @@ -11,6 +11,7 @@ \def\markdownOptionFencedCode{true} \def\markdownOptionContentBlocks{true} \def\markdownOptionPipeTables{true} +\def\markdownOptionTableCaptions{true} \definetyping [latex] \setuptyping [latex] [option=TEX] \starttext diff --git a/examples/example.md b/examples/example.md index 392c7c16b..8aeb423a2 100644 --- a/examples/example.md +++ b/examples/example.md @@ -36,6 +36,8 @@ This is a table: | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | + : Demonstration of pipe table syntax. + This is a bullet list: * The first item of a bullet list diff --git a/examples/latex.tex b/examples/latex.tex index 9e9e25831..07ebe631f 100644 --- a/examples/latex.tex +++ b/examples/latex.tex @@ -24,6 +24,7 @@ fencedCode, contentBlocks, pipeTables, + tableCaptions, ]{markdown} \begin{document} % Typeset the document `example.md` by letting the Markdown package handle diff --git a/markdown.dtx b/markdown.dtx index 4e66028b0..d8895db5b 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -4295,7 +4295,7 @@ defaultOptions.inlineFootnotes = false % %<*manual-options> -#### Option `pipeTables` +#### Option `pipeTables` {#pipe-tables} `pipeTables` (default value: `false`) @@ -4314,8 +4314,6 @@ defaultOptions.inlineFootnotes = false | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | - - : Demonstration of pipe table syntax. `````` : false @@ -5042,6 +5040,53 @@ defaultOptions.startNumber = true % %<*manual-options> +#### Option `tableCaptions` + +`tableCaptions` (default value: `false`) + +% \fi +% \begin{markdown} +% +% \Optitem[false]{tableCaptions}{\opt{true}, \opt{false}} +% +: true + + : Enable the Pandoc `table_captions` syntax extension for +% pipe tables (see the \Opt{pipeTables} option). + \iffalse + [pipe tables](#pipe-tables). +% \fi + + ``` md + | Right | Left | Default | Center | + |------:|:-----|---------|:------:| + | 12 | 12 | 12 | 12 | + | 123 | 123 | 123 | 123 | + | 1 | 1 | 1 | 1 | + + : Demonstration of pipe table syntax. + `````` + +: false + + : Enable the Pandoc `table_captions` syntax extension. + +% \end{markdown} +% \iffalse + + +% +%<*lua,lua-cli> +% \fi +% \begin{macrocode} +defaultOptions.tableCaptions = false +% \end{macrocode} +% \par +% \iffalse +% +%<*manual-options> + + #### Option `tightLists` `tightLists` (default value: `true`) @@ -5816,6 +5861,7 @@ bug](https://github.com/witiko/markdown/issues). \let\markdownOptionSlice\undefined \let\markdownOptionSmartEllipses\undefined \let\markdownOptionStartNumber\undefined +\let\markdownOptionTableCaptions\undefined \let\markdownOptionTightLists\undefined % \end{macrocode} % \par @@ -9451,11 +9497,12 @@ following text: #### Table Renderer The \mdef{markdownRendererTable} macro represents a table. This macro will only be produced, when the \Opt{pipeTables} option is `true`. The macro receives the -parameters `{`\meta{number of rows}`}{`\meta{number of columns}`}` followed by -`{`\meta{alignments}`}` and then by `{`\meta{row}`}` repeated \meta{number of -rows} times, where \meta{row} is `{`\meta{column}`}` repeated \meta{number of -columns} times, \meta{alignments} is \meta{alignment} repeated \meta{number of -columns} times, and \meta{alignment} is one of the following: +parameters `{`\meta{caption}`}{``{`\meta{number of rows}`}{`\meta{number of +columns}`}` followed by `{`\meta{alignments}`}` and then by `{`\meta{row}`}` +repeated \meta{number of rows} times, where \meta{row} is `{`\meta{column}`}` +repeated \meta{number of columns} times, \meta{alignments} is +\meta{alignment} repeated \meta{number of columns} times, and +\meta{alignment} is one of the following: - `d` -- The corresponding column has an unspecified (default) alignment. - `l` -- The corresponding column is left-aligned. @@ -9673,7 +9720,7 @@ following text: \def\markdownRendererFootnotePrototype#1{}% \def\markdownRendererCitePrototype#1{}% \def\markdownRendererTextCitePrototype#1{}% -\def\markdownRendererTablePrototype#1#2{}% +\def\markdownRendererTablePrototype#1#2#3{}% % \end{macrocode} % \par % \begin{markdown} @@ -10025,6 +10072,8 @@ pdflatex --shell-escape document.tex \def\markdownOptionSlice{#1}}% \define@key{markdownOptions}{startNumber}[true]{% \def\markdownOptionStartNumber{#1}}% +\define@key{markdownOptions}{tableCaptions}[true]{% + \def\markdownOptionTableCaptions{#1}}% \define@key{markdownOptions}{tightLists}[true]{% \def\markdownOptionTightLists{#1}}% \define@key{markdownOptions}{underscores}[true]{% @@ -10173,7 +10222,7 @@ pdflatex --shell-escape document.tex \define@key{markdownRenderers}{textCite}{% \renewcommand\markdownRendererTextCite[1]{#1}}% \define@key{markdownRenderers}{table}{% - \renewcommand\markdownRendererTable[2]{#1}}% + \renewcommand\markdownRendererTable[3]{#1}}% % \end{macrocode} % \par % \begin{markdown} @@ -10315,6 +10364,8 @@ pdflatex --shell-escape document.tex \renewcommand\markdownRendererCitePrototype[1]{#1}}% \define@key{markdownRendererPrototypes}{textCite}{% \renewcommand\markdownRendererTextCitePrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{table}{% + \renewcommand\markdownRendererTablePrototype[3]{#1}}% % \end{macrocode} % \par % \begin{markdown} @@ -11394,8 +11445,9 @@ function M.writer.new(options) % % \end{markdown} % \begin{macrocode} - function self.table(rows) - local buffer = {"\\markdownRendererTable{", #rows - 1, "}{", #rows[1], "}"} + function self.table(rows, caption) + local buffer = {"\\markdownRendererTable{", + caption or "", "}{", #rows - 1, "}{", #rows[1], "}"} local temp = rows[2] -- put alignments on the first row rows[2] = rows[1] rows[1] = temp @@ -12337,6 +12389,10 @@ parsers.table_hline = pipe_table_row(false , parsers.table_hline_column , parsers.table_hline_separator , parsers.table_hline_column) +parsers.table_caption_beginning = parsers.skipblanklines + * parsers.nonindentspace + * (P("table") + parsers.colon) + * parsers.optionalspace % \end{macrocode} % \par % \begin{markdown} @@ -12484,7 +12540,8 @@ parsers.define_reference_parser = parsers.leader * parsers.tag * parsers.colon % % \end{markdown} % \begin{macrocode} -parsers.Inline = V("Inline") +parsers.Inline = V("Inline") +parsers.IndentedInline = V("IndentedInline") -- parse many p between starter and ender parsers.between = function(p, starter, ender) @@ -12851,11 +12908,21 @@ larsers.table_row = pipe_table_row(true , (C((parsers.linechar - parsers.pipe)^0) / parse_inlines)) +if options.tableCaptions then + larsers.table_caption = #parsers.table_caption_beginning + * parsers.table_caption_beginning + * Ct(parsers.IndentedInline^1) + * parsers.newline +else + larsers.table_caption = parsers.fail +end + larsers.PipeTable = Ct(larsers.table_row * parsers.newline * parsers.table_hline * (parsers.newline * larsers.table_row)^0) - / make_pipe_table_rectangular - / writer.table + / make_pipe_table_rectangular + * larsers.table_caption^-1 + / writer.table % \end{macrocode} % \par % \begin{markdown} @@ -12971,6 +13038,9 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline + larsers.fencestart ) * parsers.spacechar^0 / writer.space + larsers.OptionalIndent + = parsers.spacechar^1 / writer.space + larsers.Space = parsers.spacechar^2 * larsers.Endline / writer.linebreak + parsers.spacechar^1 * larsers.Endline^-1 * parsers.eof / "" + parsers.spacechar^1 * larsers.Endline^-1 @@ -13380,8 +13450,29 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline + V("Smart") + V("Symbol"), + IndentedInline = V("Str") + + V("OptionalIndent") + + V("Endline") + + V("UlOrStarLine") + + V("Strong") + + V("Emph") + + V("InlineNote") + + V("NoteRef") + + V("Citations") + + V("Link") + + V("Image") + + V("Code") + + V("AutoLinkUrl") + + V("AutoLinkEmail") + + V("InlineHtml") + + V("HtmlEntity") + + V("EscapedChar") + + V("Smart") + + V("Symbol"), + Str = larsers.Str, Space = larsers.Space, + OptionalIndent = larsers.OptionalIndent, Endline = larsers.Endline, UlOrStarLine = larsers.UlOrStarLine, Strong = larsers.Strong, @@ -13770,6 +13861,9 @@ end \ifx\markdownOptionStartNumber\undefined\else startNumber = \markdownOptionStartNumber, \fi +\ifx\markdownOptionTableCaptions\undefined\else + tableCaptions = \markdownOptionTableCaptions, +\fi \ifx\markdownOptionTightLists\undefined\else tightLists = \markdownOptionTightLists, \fi @@ -14770,6 +14864,7 @@ local convert = md.new(\markdownLuaOptions) \newcount\markdownLaTeXColumnTotal \newtoks\markdownLaTeXTable \newtoks\markdownLaTeXTableAlignment +\newtoks\markdownLaTeXTableEnd \@ifpackageloaded{booktabs}{ \let\markdownLaTeXTopRule\toprule \let\markdownLaTeXMidRule\midrule @@ -14779,18 +14874,32 @@ local convert = md.new(\markdownLuaOptions) \let\markdownLaTeXMidRule\hline \let\markdownLaTeXBottomRule\hline } -\def\markdownRendererTablePrototype#1#2{% - \markdownLaTeXTable={}% - \markdownLaTeXTableAlignment={}% - \markdownLaTeXRowCounter=0% - \markdownLaTeXRowTotal=#1% - \markdownLaTeXColumnTotal=#2% - \markdownLaTeXRenderTableRow} +\markdownSetup{rendererPrototypes={ + table = {% + \markdownLaTeXTable={}% + \markdownLaTeXTableAlignment={}% + \markdownLaTeXTableEnd={% + \markdownLaTeXBottomRule + \end{tabular}}% + \if\empty#1\empty\else + \addto@hook\markdownLaTeXTable{% + \begin{table} + \centering}% + \addto@hook\markdownLaTeXTableEnd{% + \caption{#1} + \end{table}}% + \fi + \addto@hook\markdownLaTeXTable{\begin{tabular}}% + \markdownLaTeXRowCounter=0% + \markdownLaTeXRowTotal=#2% + \markdownLaTeXColumnTotal=#3% + \markdownLaTeXRenderTableRow + } +}} \def\markdownLaTeXRenderTableRow#1{% \markdownLaTeXColumnCounter=0% \ifnum\markdownLaTeXRowCounter=0\relax \markdownLaTeXReadAlignments#1% - \markdownLaTeXTable={\begin{tabular}}% \markdownLaTeXTable=\expandafter\expandafter\expandafter{% \expandafter\the\expandafter\markdownLaTeXTable\expandafter{% \the\markdownLaTeXTableAlignment}}% @@ -14803,10 +14912,10 @@ local convert = md.new(\markdownLuaOptions) \fi \advance\markdownLaTeXRowCounter by 1\relax \ifnum\markdownLaTeXRowCounter>\markdownLaTeXRowTotal\relax - \addto@hook\markdownLaTeXTable{% - \markdownLaTeXBottomRule - \end{tabular}}% + \markdownInfo{\the\markdownLaTeXTable} + \markdownInfo{\the\markdownLaTeXTableEnd} \the\markdownLaTeXTable + \the\markdownLaTeXTableEnd \expandafter\@gobble \fi\markdownLaTeXRenderTableRow} \def\markdownLaTeXReadAlignments#1{% @@ -15070,16 +15179,24 @@ local convert = md.new(\markdownLuaOptions) \newcount\markdownConTeXtColumnCounter \newcount\markdownConTeXtColumnTotal \newtoks\markdownConTeXtTable -\def\markdownRendererTablePrototype#1#2{% +\newtoks\markdownConTeXtTableFloat +\def\markdownRendererTablePrototype#1#2#3{% \markdownConTeXtTable={}% + \if\empty#1\empty + \markdownConTeXtTableFloat={% + \the\markdownConTeXtTable}% + \else + \markdownConTeXtTableFloat={% + \placetable{#1}{\the\markdownConTeXtTable}}% + \fi \begingroup \setupTABLE[r][each][topframe=off, bottomframe=off, leftframe=off, rightframe=off] \setupTABLE[c][each][topframe=off, bottomframe=off, leftframe=off, rightframe=off] \setupTABLE[r][1][topframe=on, bottomframe=on] \setupTABLE[r][#1][bottomframe=on] \markdownConTeXtRowCounter=0% - \markdownConTeXtRowTotal=#1% - \markdownConTeXtColumnTotal=#2% + \markdownConTeXtRowTotal=#2% + \markdownConTeXtColumnTotal=#3% \markdownConTeXtRenderTableRow} \def\markdownConTeXtRenderTableRow#1{% \markdownConTeXtColumnCounter=0% @@ -15097,7 +15214,7 @@ local convert = md.new(\markdownLuaOptions) \ifnum\markdownConTeXtRowCounter>\markdownConTeXtRowTotal\relax \markdownConTeXtTable=\expandafter{% \the\markdownConTeXtTable\eTABLE}% - \the\markdownConTeXtTable + \the\markdownConTeXtTableFloat \endgroup \expandafter\gobbleoneargument \fi\markdownConTeXtRenderTableRow} diff --git a/tests/support/latex-setup.tex b/tests/support/latex-setup.tex index d5ca24f8d..be002d6ec 100644 --- a/tests/support/latex-setup.tex +++ b/tests/support/latex-setup.tex @@ -158,5 +158,5 @@ textCite = {% \TEXTCITATIONS{#1}}, table = {% - \TABLE{#1}{#2}} + \TABLE{#1}{#2}{#3}} } diff --git a/tests/support/plain-setup.tex b/tests/support/plain-setup.tex index 2b9da68e0..1c163781e 100644 --- a/tests/support/plain-setup.tex +++ b/tests/support/plain-setup.tex @@ -138,5 +138,5 @@ \CITATIONS{#1}}% \def\markdownRendererTextCite#1{% \TEXTCITATIONS{#1}}% -\def\markdownRendererTable#1#2{% - \TABLE{#1}{#2}}% +\def\markdownRendererTable#1#2#3{% + \TABLE{#1}{#2}{#3}}% diff --git a/tests/support/setup.tex b/tests/support/setup.tex index 902f5845b..43613a767 100644 --- a/tests/support/setup.tex +++ b/tests/support/setup.tex @@ -31,11 +31,12 @@ \ifnum\COLCOUNTER>\COLTOTAL\relax \expandafter\GOBBLE \fi\DOCOL}% -\def\TABLE#1#2{% +\def\TABLE#1#2#3{% \ROWCOUNTER=0% - \def\ROWTOTAL{#1}% - \def\COLTOTAL{#2}% - \TYPE{BEGIN table (#1 rows, #2 columns)}% + \def\ROWTOTAL{#2}% + \def\COLTOTAL{#3}% + \TYPE{BEGIN table (#2 rows, #3 columns)}% + \TYPE{- caption: #1}% \DOROW}% % Citations parsing diff --git a/tests/testfiles/PHP_Markdown/tables.test b/tests/testfiles/PHP_Markdown/tables.test index 8b6a4f1fe..d1bd9edd4 100644 --- a/tests/testfiles/PHP_Markdown/tables.test +++ b/tests/testfiles/PHP_Markdown/tables.test @@ -114,6 +114,7 @@ Cell | Cell BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell 1 @@ -126,6 +127,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell 1 @@ -138,6 +140,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell 1 @@ -150,6 +153,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell 1 @@ -165,6 +169,7 @@ interblockSeparator interblockSeparator BEGIN table (2 rows, 1 columns) - alignment of column 1: d +- caption: - row 1, column 1: Header - row 2, column 1: Cell END table @@ -172,6 +177,7 @@ interblockSeparator interblockSeparator BEGIN table (2 rows, 1 columns) - alignment of column 1: d +- caption: - row 1, column 1: Header - row 2, column 1: Cell END table @@ -179,6 +185,7 @@ interblockSeparator interblockSeparator BEGIN table (2 rows, 1 columns) - alignment of column 1: d +- caption: - row 1, column 1: Header - row 2, column 1: Cell END table @@ -191,6 +198,7 @@ BEGIN table (3 rows, 4 columns) - alignment of column 2: l - alignment of column 3: c - alignment of column 4: r +- caption: - row 1, column 1: Default - row 1, column 2: Right - row 1, column 3: Center @@ -211,6 +219,7 @@ BEGIN table (3 rows, 4 columns) - alignment of column 2: l - alignment of column 3: c - alignment of column 4: r +- caption: - row 1, column 1: Default - row 1, column 2: Right - row 1, column 3: Center @@ -232,6 +241,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: A @@ -243,6 +253,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: A @@ -258,6 +269,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell @@ -269,6 +281,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell @@ -280,6 +293,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell @@ -291,6 +305,7 @@ interblockSeparator BEGIN table (3 rows, 2 columns) - alignment of column 1: d - alignment of column 2: d +- caption: - row 1, column 1: Header 1 - row 1, column 2: Header 2 - row 2, column 1: Cell @@ -305,6 +320,7 @@ headingOne: Too many pipes in rows interblockSeparator BEGIN table (3 rows, 1 columns) - alignment of column 1: d +- caption: - row 1, column 1: Header 1 - row 2, column 1: Cell - row 3, column 1: Cell diff --git a/tests/testfiles/lunamark-markdown/pipe-tables.test b/tests/testfiles/lunamark-markdown/no-table-captions.test similarity index 72% rename from tests/testfiles/lunamark-markdown/pipe-tables.test rename to tests/testfiles/lunamark-markdown/no-table-captions.test index 58a4c1f73..c02fd0c30 100644 --- a/tests/testfiles/lunamark-markdown/pipe-tables.test +++ b/tests/testfiles/lunamark-markdown/no-table-captions.test @@ -1,17 +1,23 @@ \def\markdownOptionPipeTables{true} <<< -This test ensures that the Lua `pipeTables` option correctly propagates through -the plain TeX interface. +This test ensures that the Lua `tableCaptions` option is disabled by +default. | Right | *Left* | Default | Center | |------:|:-------|-------------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | **123** | 123 | | 1 | 1 | 1 | 1 | + + : Demonstration of *pipe table* syntax with the caption spreading over + multiple lines. + +A caption may not span multiple paragraphs. >>> -codeSpan: pipeTables +codeSpan: tableCaptions interblockSeparator BEGIN table (4 rows, 4 columns) +- caption: - alignment of column 1: r - alignment of column 2: l - alignment of column 3: d @@ -33,3 +39,6 @@ BEGIN table (4 rows, 4 columns) - row 4, column 3: 1 - row 4, column 4: 1 END table +interblockSeparator +emphasis: pipe table +interblockSeparator diff --git a/tests/testfiles/lunamark-markdown/table-captions.test b/tests/testfiles/lunamark-markdown/table-captions.test new file mode 100644 index 000000000..273b718d5 --- /dev/null +++ b/tests/testfiles/lunamark-markdown/table-captions.test @@ -0,0 +1,43 @@ +\def\markdownOptionPipeTables{true} +\def\markdownOptionTableCaptions{true} +<<< +This test ensures that the Lua `tableCaptions` option correctly propagates +through the plain TeX interface. + +| Right | *Left* | Default | Center | +|------:|:-------|-------------|:------:| +| 12 | 12 | 12 | 12 | +| 123 | 123 | **123** | 123 | +| 1 | 1 | 1 | 1 | + + : Demonstration of *pipe table* syntax with the caption spreading over + multiple lines. + +A caption may not span multiple paragraphs. +>>> +codeSpan: tableCaptions +interblockSeparator +BEGIN table (4 rows, 4 columns) +- caption: Demonstration of (emphasis: pipe table) syntax with the caption spreading over multiple lines. +- alignment of column 1: r +- alignment of column 2: l +- alignment of column 3: d +- alignment of column 4: c +- row 1, column 1: Right +- row 1, column 2: (emphasis: Left) +- row 1, column 3: Default +- row 1, column 4: Center +- row 2, column 1: 12 +- row 2, column 2: 12 +- row 2, column 3: 12 +- row 2, column 4: 12 +- row 3, column 1: 123 +- row 3, column 2: 123 +- row 3, column 3: (strongEmphasis: 123) +- row 3, column 4: 123 +- row 4, column 1: 1 +- row 4, column 2: 1 +- row 4, column 3: 1 +- row 4, column 4: 1 +END table +interblockSeparator