From af727e8e6e8c8e28e4bc63cccbda72fc4b32f6bf Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sat, 23 Oct 2021 20:17:28 +0200 Subject: [PATCH 01/16] A lua filter enabling multiple columns in Latex, PDF, and HTML documents based on Pandoc fenced divs --- column-div/Makefile | 19 ++++++ column-div/README.md | 138 ++++++++++++++++++++++++++++++++++++++ column-div/column-div.lua | 115 +++++++++++++++++++++++++++++++ column-div/expected.html | 62 +++++++++++++++++ column-div/expected.tex | 123 +++++++++++++++++++++++++++++++++ column-div/sample.md | 60 +++++++++++++++++ 6 files changed, 517 insertions(+) create mode 100644 column-div/Makefile create mode 100644 column-div/README.md create mode 100644 column-div/column-div.lua create mode 100644 column-div/expected.html create mode 100644 column-div/expected.tex create mode 100644 column-div/sample.md diff --git a/column-div/Makefile b/column-div/Makefile new file mode 100644 index 00000000..0d00387e --- /dev/null +++ b/column-div/Makefile @@ -0,0 +1,19 @@ +DIFF ?= diff --strip-trailing-cr -u + +.PHONY: test + +test: test_latex test_html + +test_html: sample.md expected.html column-div.lua + @pandoc -s --lua-filter column-div.lua --to=html $< \ + | $(DIFF) expected.html - + +test_latex: sample.md expected.tex column-div.lua + @pandoc -s --lua-filter column-div.lua --to=latex $< \ + | $(DIFF) expected.tex - + +expected.html: sample.md column-div.lua + pandoc -s --lua-filter column-div.lua --output $@ $< + +expected.tex: sample.md column-div.lua + pandoc -s --lua-filter column-div.lua --output $@ $< diff --git a/column-div/README.md b/column-div/README.md new file mode 100644 index 00000000..5d3b60da --- /dev/null +++ b/column-div/README.md @@ -0,0 +1,138 @@ +--- +title: "Column Div - leverage Pandoc native divs to make columns + an other things" +author: "Christophe Agathon" +--- + +Column Div +======= + +Columns and other things with Pandoc's markdown + +This Lua filter for Pandoc improves Pandoc's Div usage.Especially +fenced divs witten in Pandocs markdown. + +v1.0. Copyright: © 2021 Christophe Agathon + +License: MIT - see LICENSE file for details. + +Introduction +------------ +Pandoc fenced divs can be very powerful allowing providing, in +theory many document formating possibilities. Unfortunately, plain +Panfoc processing doesn't make full adventage of it and discards +some formating in HTML outputs and most of it in Latex outputs. + +Multiple columns in document are only partialy accessible in +Beamer (not plain Latex) and HTML outputs. + +As a result, it's not possible to render fancy multi columns +PDF document from markdown sources. + +The main purpose of this filter is to make it possible and give +similar formating features for both Latex/PDF and HTML outputs. + +Usage +----- + +### Basic usage + +Copy `column-div.lua` in your document folder or in your pandoc +data directory (details in +[Pandoc's manual](https://pandoc.org/MANUAL.html#option--lua-filter)). +Run it on your document with a `--luafilter` option: + +```bash +pandoc --luafilter column-div.lua SOURCE.md -o OUTPUT.pdf + +``` + +or specify it in a defaults file (details in +[Pandoc's manual](https://pandoc.org/MANUAL.html#option--defaults)). + +This will generate consistent HTML, Latex and PDF outputs from +Pandoc markdown files. + +### Formating the document + +Everything is done with Pandoc's fenced divs with class names and +attributes. The attributes are similar to those from Latex and/or +HTML styling. + +#### Multiple balanced columns +For Latex and PDF output, you will need to call the multicol +package. This can be done un the YAML header. + +**Example:** + +```markdown +--- +header-includes: + - | + ```{=latex} + \usepackage{multicol} + + ``` +--- + +Some regular text + +:::: {.multicols column-count="2"} +Some text formatted on 2 columns +:::: +``` + +* Latex output is done with `multicols` environment. +* HTML output uses `style="column-count: 2"` on a div block. + +#### Unbalanced columns + +No specific Latex package are needed. We use Nested Pandoc divs in +the same way that columns and column environments are used in +Beamer/Latex. + +**Example:** + +```markdown + +:::::::: {.columns} +:::: {.column width="20%" valign="c"} +Some text or image using 20% of the page width. +:::: +:::: {.column width="80%" valign="c"} +Some text or image using 80% of the page with. +:::: +:::::::: +``` + +* Beamer/Latex output is based on columns and column environments +* Plain Latex (and PDF) rendering use minipage environments +* HTML rendering is not affected by this filter since Pandoc do it +well already (based on divs with `width` attributes). + +#### Other usages + +HTML : you can already create divs with whatever class names youl +like and style them with `style=" … "` attributes. This is +proccessed by Pandoc and as nothing to do with this filter. + +This filter allows to do the same in Latex (and PDF). +The class name is used as the environment name and a +`data-latex=" … "` attribute allows you to pass options and +parameters to the `\begin` instruction. + +To Do +----- + +Others multi column features could be implemented as column +spacing, rules, etc. + +Since Pandoc does a very good job with the `width` styling +attribute to implement variable column width, it could easily +support HTML balanced column via the `column-count` attribute. + +Contributing +------------ + +PRs welcome. + diff --git a/column-div/column-div.lua b/column-div/column-div.lua new file mode 100644 index 00000000..271fa4a9 --- /dev/null +++ b/column-div/column-div.lua @@ -0,0 +1,115 @@ +--[[ +column-div - leverage Pandoc native divs to make balanced and unbalanced column + and other things based on class name and attirbutes. + +Copyright: © 2021 Christophe Agathon +License: MIT – see LICENSE file for details + +Credits: Romain Lesur and Yihui Xie for the original column filter + implementation (output in beamer format). + +Output: latex, pdf, html + +Usage: classname attributes + balanced columns .columns column-count + columns(container) .columns + column(each column) .column width(percent) valign(t|c|b) + other divs . data-latex + + See README.md for details + +Note: You need to include multicol latex package to get balanced columns + in latex or pdf + I tried to use well known html or latex parameter. + Even if lua doen't like hyphens like in column-count. +--]] +local List = require 'pandoc.List' + +function Div(div) + options = '' + local env = div.classes[1] + local returned_list + local begin_env + local end_env + local opt + + -- if the div has no class, the object is left unchanged + if not env then return nil end + + -- if the output is beamer do columns + if FORMAT:match 'beamer' then + -- build the returned list of blocks + begin_env = List:new{pandoc.RawBlock('tex', + '\\begin' .. '{' .. env .. '}' .. options)} + end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')} + returned_list = begin_env .. div.content .. end_env + + -- if the format is latex then do minipage and others (like multicol) + elseif FORMAT:match 'latex' then + -- build the returned list of blocks + if env == 'column' then + --opt = div.attributes['width'] + opt = div.attributes.width + if opt then + local width=tonumber(string.match(opt,'(%f[%d]%d[,.%d]*%f[%D])%%'))/100 + options = '{' .. tostring(width) .. '\\columnwidth}' + end + + opt = div.attributes.valign + if opt then options = '[' .. opt .. ']' .. options end + + begin_env = List:new{pandoc.RawBlock('tex', + '\\begin' .. '{' .. 'minipage' .. '}' .. options)} + end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. 'minipage' .. '}')} + returned_list = begin_env .. div.content .. end_env + + elseif env == 'columns' then + -- merge two consecutives RawBlocks (\end... and \begin...) + -- to get rid of the unwanted blank line + local blocks = div.content + local rbtxt = '' + + for i = #blocks-1, 1, -1 do + if i > 1 and blocks[i].tag == 'RawBlock' and blocks[i].text:match 'end' + and blocks[i+1].tag == 'RawBlock' and blocks[i+1].text:match 'begin' + then + rbtxt = blocks[i].text .. blocks[i+1].text + blocks:remove(i+1) + blocks[i].text = rbtxt + end + end + returned_list=blocks + + else + -- other environments ex: multicols + + -- process supported options + opt = div.attributes['column-count'] -- this synthax needed due to '_' + if opt then options = '{' .. opt .. '}' end + + -- default if no known options + if options == '' then options = div.attributes.data-latex end + + begin_env = List:new{pandoc.RawBlock('tex', + '\\begin' .. '{' .. env .. '}' .. options)} + end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')} + returned_list = begin_env .. div.content .. end_env + end + + -- if the format is html add support for multi columns + elseif FORMAT:match 'html' then + opt = div.attributes['column-count'] + if opt then + -- add column-count to style if it exists + if div.attributes.style then + div.attributes.style = div.attributes.style .. + '; column-count: ' .. opt + else + div.attributes.style = 'column-count:' .. opt + end + div.attributes['column-count'] = nil + returned_list = List:new{pandoc.Div(div.content, div.attr)} + end + end + return returned_list +end diff --git a/column-div/expected.html b/column-div/expected.html new file mode 100644 index 00000000..a112eaa8 --- /dev/null +++ b/column-div/expected.html @@ -0,0 +1,62 @@ + + + + + + + Test + + + +
+

Test

+
+

column-div test

+

content…

+

Three columns

+
+

content…

+

content…

+

content…

+
+

Two unbalanced columns

+
+
+

contents…

+
+

contents…

+
+
+

Columns in columns

+
+
+
+

contents…

+
+

contents…

+
+
+
+
+

contents…

+
+

contents…

+
+
+
+
+

contents…

+
+

contents…

+
+
+
+ + diff --git a/column-div/expected.tex b/column-div/expected.tex new file mode 100644 index 00000000..f4328283 --- /dev/null +++ b/column-div/expected.tex @@ -0,0 +1,123 @@ +% Options for packages loaded elsewhere +\PassOptionsToPackage{unicode}{hyperref} +\PassOptionsToPackage{hyphens}{url} +% +\documentclass[ +]{article} +\usepackage{lmodern} +\usepackage{amssymb,amsmath} +\usepackage{ifxetex,ifluatex} +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \usepackage[T1]{fontenc} + \usepackage[utf8]{inputenc} + \usepackage{textcomp} % provide euro and other symbols +\else % if luatex or xetex + \usepackage{unicode-math} + \defaultfontfeatures{Scale=MatchLowercase} + \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} +\fi +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +\usepackage{xcolor} +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} +\hypersetup{ + pdftitle={Test}, + hidelinks, + pdfcreator={LaTeX via pandoc}} +\urlstyle{same} % disable monospaced font for URLs +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering + +\title{Test} +\author{} +\date{} + +\begin{document} +\maketitle + +\hypertarget{column-div-test}{% +\section{column-div test}\label{column-div-test}} + +content\ldots{} + +\hypertarget{three-columns}{% +\subsection{Three columns}\label{three-columns}} + +\begin{multicols}{3} + +content\ldots{} + +content\ldots{} + +content\ldots{} + +\end{multicols} + +\hypertarget{two-unbalanced-columns}{% +\subsection{Two unbalanced columns}\label{two-unbalanced-columns}} + +\begin{minipage}[b]{0.4\columnwidth} + +contents\ldots{} + +\end{minipage}\begin{minipage}[b]{0.6\columnwidth} + +contents\ldots{} + +\end{minipage} + +\hypertarget{columns-in-columns}{% +\subsection{Columns in columns}\label{columns-in-columns}} + +\begin{multicols}{3} + +\begin{minipage}[b]{0.2\columnwidth} + +contents\ldots{} + +\end{minipage}\begin{minipage}[b]{0.8\columnwidth} + +contents\ldots{} + +\end{minipage} + +\begin{minipage}[b]{0.2\columnwidth} + +contents\ldots{} + +\end{minipage}\begin{minipage}[b]{0.8\columnwidth} + +contents\ldots{} + +\end{minipage} + +\begin{minipage}[b]{0.2\columnwidth} + +contents\ldots{} + +\end{minipage}\begin{minipage}[b]{0.8\columnwidth} + +contents\ldots{} + +\end{minipage} + +\end{multicols} + +\end{document} diff --git a/column-div/sample.md b/column-div/sample.md new file mode 100644 index 00000000..7852f21f --- /dev/null +++ b/column-div/sample.md @@ -0,0 +1,60 @@ +--- +title : Test +header-includes: + - | + ```{=latex} + \usepackage{multicol} + + ``` +--- + +# column-div test +content... + +## Three columns +::: {.multicols column-count="3"} +content... + +content... + +content... +::: + +## Two unbalanced columns +:::::: {.columns} +::: {.column width="40%" valign="b"} +contents... +::: +::: {.column width="60%" valign="b"} +contents... +::: +:::::: + +## Columns in columns + +::::::::: {.multicols column-count="3"} +:::::: {.columns} +::: {.column width="20%" valign="b"} +contents... +::: +::: {.column width="80%" valign="b"} +contents... +::: +:::::: +:::::: {.columns} +::: {.column width="20%" valign="b"} +contents... +::: +::: {.column width="80%" valign="b"} +contents... +::: +:::::: +:::::: {.columns} +::: {.column width="20%" valign="b"} +contents... +::: +::: {.column width="80%" valign="b"} +contents... +::: +:::::: +::::::::: \ No newline at end of file From 5296ecd54eb7dbb537e511b729753d601cd6fcbb Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sun, 24 Oct 2021 10:15:50 +0200 Subject: [PATCH 02/16] Forgot to update expected.* files before previous commit --- column-div/expected.html | 1 + column-div/expected.tex | 1 + 2 files changed, 2 insertions(+) diff --git a/column-div/expected.html b/column-div/expected.html index a112eaa8..7c46f5eb 100644 --- a/column-div/expected.html +++ b/column-div/expected.html @@ -13,6 +13,7 @@ div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} ul.task-list{list-style: none;} +
diff --git a/column-div/expected.tex b/column-div/expected.tex index f4328283..d0384ad2 100644 --- a/column-div/expected.tex +++ b/column-div/expected.tex @@ -44,6 +44,7 @@ \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \setcounter{secnumdepth}{-\maxdimen} % remove section numbering +\usepackage{multicol} \title{Test} \author{} From 9d650d4dc38c83f13dfeb69dc32dd9644dd60a0d Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sun, 24 Oct 2021 10:36:11 +0200 Subject: [PATCH 03/16] Don't use a standalone (pandoc -s) document for expected.tex since this filter targets document body only and pandoc does many things I don't control in the preamble. --- column-div/Makefile | 4 +-- column-div/expected.tex | 57 ----------------------------------------- 2 files changed, 2 insertions(+), 59 deletions(-) diff --git a/column-div/Makefile b/column-div/Makefile index 0d00387e..da6ff833 100644 --- a/column-div/Makefile +++ b/column-div/Makefile @@ -9,11 +9,11 @@ test_html: sample.md expected.html column-div.lua | $(DIFF) expected.html - test_latex: sample.md expected.tex column-div.lua - @pandoc -s --lua-filter column-div.lua --to=latex $< \ + @pandoc --lua-filter column-div.lua --to=latex $< \ | $(DIFF) expected.tex - expected.html: sample.md column-div.lua pandoc -s --lua-filter column-div.lua --output $@ $< expected.tex: sample.md column-div.lua - pandoc -s --lua-filter column-div.lua --output $@ $< + pandoc --lua-filter column-div.lua --output $@ $< diff --git a/column-div/expected.tex b/column-div/expected.tex index d0384ad2..faede347 100644 --- a/column-div/expected.tex +++ b/column-div/expected.tex @@ -1,58 +1,3 @@ -% Options for packages loaded elsewhere -\PassOptionsToPackage{unicode}{hyperref} -\PassOptionsToPackage{hyphens}{url} -% -\documentclass[ -]{article} -\usepackage{lmodern} -\usepackage{amssymb,amsmath} -\usepackage{ifxetex,ifluatex} -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[T1]{fontenc} - \usepackage[utf8]{inputenc} - \usepackage{textcomp} % provide euro and other symbols -\else % if luatex or xetex - \usepackage{unicode-math} - \defaultfontfeatures{Scale=MatchLowercase} - \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} -\fi -% Use upquote if available, for straight quotes in verbatim environments -\IfFileExists{upquote.sty}{\usepackage{upquote}}{} -\IfFileExists{microtype.sty}{% use microtype if available - \usepackage[]{microtype} - \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts -}{} -\makeatletter -\@ifundefined{KOMAClassName}{% if non-KOMA class - \IfFileExists{parskip.sty}{% - \usepackage{parskip} - }{% else - \setlength{\parindent}{0pt} - \setlength{\parskip}{6pt plus 2pt minus 1pt}} -}{% if KOMA class - \KOMAoptions{parskip=half}} -\makeatother -\usepackage{xcolor} -\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available -\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} -\hypersetup{ - pdftitle={Test}, - hidelinks, - pdfcreator={LaTeX via pandoc}} -\urlstyle{same} % disable monospaced font for URLs -\setlength{\emergencystretch}{3em} % prevent overfull lines -\providecommand{\tightlist}{% - \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} -\setcounter{secnumdepth}{-\maxdimen} % remove section numbering -\usepackage{multicol} - -\title{Test} -\author{} -\date{} - -\begin{document} -\maketitle - \hypertarget{column-div-test}{% \section{column-div test}\label{column-div-test}} @@ -120,5 +65,3 @@ \subsection{Columns in columns}\label{columns-in-columns}} \end{minipage} \end{multicols} - -\end{document} From 2cc9018fc3e340d7fb088d1c7bd667bef6c0ba6e Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sun, 24 Oct 2021 17:06:55 +0200 Subject: [PATCH 04/16] Allow 'signifiant' class names to be in random position in the list as suggested by Benct Philip Jonsson Plus other minor refactoring and some details in README.md Some enhencements in the sample file. --- column-div/README.md | 33 ++++++++++++++++++--------- column-div/column-div.lua | 48 +++++++++++++++++++++++++++------------ column-div/expected.html | 9 +++++--- column-div/expected.tex | 7 ++++-- column-div/sample.md | 8 +++++-- 5 files changed, 73 insertions(+), 32 deletions(-) diff --git a/column-div/README.md b/column-div/README.md index 5d3b60da..c16f7673 100644 --- a/column-div/README.md +++ b/column-div/README.md @@ -1,6 +1,6 @@ --- title: "Column Div - leverage Pandoc native divs to make columns - an other things" + and other things" author: "Christophe Agathon" --- @@ -32,6 +32,14 @@ PDF document from markdown sources. The main purpose of this filter is to make it possible and give similar formating features for both Latex/PDF and HTML outputs. +My guidelines are : + +1) Use Pandoc divs like many already have proposed for uneven and even columns +2) Same functionalities and rendering in HTML and Latex+PDF +3) Mess the least possible with plain Pandoc processing which is quite OK already for HTML (miss only column-count for even columning). +4) Allow users to use unknown Latex environments from exotic packages if they wish, provided they include them in the preamble. + + Usage ----- @@ -56,10 +64,10 @@ Pandoc markdown files. ### Formating the document Everything is done with Pandoc's fenced divs with class names and -attributes. The attributes are similar to those from Latex and/or -HTML styling. +attributes. The attributes are similar to those from HTML styling and/or +Latex. -#### Multiple balanced columns +#### Multiple even columns For Latex and PDF output, you will need to call the multicol package. This can be done un the YAML header. @@ -85,7 +93,7 @@ Some text formatted on 2 columns * Latex output is done with `multicols` environment. * HTML output uses `style="column-count: 2"` on a div block. -#### Unbalanced columns +#### Uneven columns No specific Latex package are needed. We use Nested Pandoc divs in the same way that columns and column environments are used in @@ -112,14 +120,17 @@ well already (based on divs with `width` attributes). #### Other usages -HTML : you can already create divs with whatever class names youl +For HTML outputs, you already can create divs with whatever class names you like and style them with `style=" … "` attributes. This is -proccessed by Pandoc and as nothing to do with this filter. +processed by Pandoc and has nothing to do with this filter. This filter allows to do the same in Latex (and PDF). -The class name is used as the environment name and a -`data-latex=" … "` attribute allows you to pass options and -parameters to the `\begin` instruction. +You can create whatever environment you need. The environment name is the +class name given to the fenced div. In case of multiple class names, the +first one is used. Other are ignored but allowed to help you to maintain +a single markdown source for PDF and HTML outputs. +The `data-latex=" … "` attribute allows you to pass options and +parameters to the `\begin` environment instruction. To Do ----- @@ -129,7 +140,7 @@ spacing, rules, etc. Since Pandoc does a very good job with the `width` styling attribute to implement variable column width, it could easily -support HTML balanced column via the `column-count` attribute. +support HTML even column via the `column-count` attribute. Contributing ------------ diff --git a/column-div/column-div.lua b/column-div/column-div.lua index 271fa4a9..6271ae52 100644 --- a/column-div/column-div.lua +++ b/column-div/column-div.lua @@ -26,18 +26,28 @@ Note: You need to include multicol latex package to get balanced columns local List = require 'pandoc.List' function Div(div) - options = '' - local env = div.classes[1] + local options = '' + local env = '' local returned_list local begin_env local end_env local opt -- if the div has no class, the object is left unchanged - if not env then return nil end + -- if the div has no class but an id, div.classes ~= nil + -- TODO: use a div with no class to build a 'scope' in Latex + -- usefull for user who would throw inline Latex code and limit it's + -- effect. + if not div.classes or #div.classes == 0 then return nil end -- if the output is beamer do columns if FORMAT:match 'beamer' then + -- only arbitrary environment support in beamer for now. Environment has to + -- be the firs class name. + env = div.classes[1] + if options == '' and div.attributes['data-latex'] then + options = div.attributes['data-latex'] + end -- build the returned list of blocks begin_env = List:new{pandoc.RawBlock('tex', '\\begin' .. '{' .. env .. '}' .. options)} @@ -47,8 +57,8 @@ function Div(div) -- if the format is latex then do minipage and others (like multicol) elseif FORMAT:match 'latex' then -- build the returned list of blocks - if env == 'column' then - --opt = div.attributes['width'] + if div.classes:includes('column') then + env = 'column' opt = div.attributes.width if opt then local width=tonumber(string.match(opt,'(%f[%d]%d[,.%d]*%f[%D])%%'))/100 @@ -63,7 +73,8 @@ function Div(div) end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. 'minipage' .. '}')} returned_list = begin_env .. div.content .. end_env - elseif env == 'columns' then + elseif div.classes:includes('columns') then + env = 'columns' -- merge two consecutives RawBlocks (\end... and \begin...) -- to get rid of the unwanted blank line local blocks = div.content @@ -82,13 +93,20 @@ function Div(div) else -- other environments ex: multicols - - -- process supported options - opt = div.attributes['column-count'] -- this synthax needed due to '_' - if opt then options = '{' .. opt .. '}' end - - -- default if no known options - if options == '' then options = div.attributes.data-latex end + if div.classes:includes('multicols') then + env = 'multicols' + -- process supported options + opt = div.attributes['column-count'] + if opt then options = '{' .. opt .. '}' end + else + -- Latex skilled users can use arbitrary environments passed as + -- the first (and only signifiant) class name. + env = div.classes[1] + -- default if no known options + if options == '' and div.attributes['data-latex'] then + options = div.attributes['data-latex'] + end + end begin_env = List:new{pandoc.RawBlock('tex', '\\begin' .. '{' .. env .. '}' .. options)} @@ -105,9 +123,11 @@ function Div(div) div.attributes.style = div.attributes.style .. '; column-count: ' .. opt else - div.attributes.style = 'column-count:' .. opt + div.attributes.style = 'column-count: ' .. opt end div.attributes['column-count'] = nil + -- column-count is "consumed" by the filter otherwise it would appear as + -- data-column-count="…" in the resulting document returned_list = List:new{pandoc.Div(div.content, div.attr)} end end diff --git a/column-div/expected.html b/column-div/expected.html index 7c46f5eb..f99ea173 100644 --- a/column-div/expected.html +++ b/column-div/expected.html @@ -21,13 +21,16 @@

Test

column-div test

content…

+
+

content…

+

Three columns

-
+

content…

content…

content…

-

Two unbalanced columns

+

Two uneven columns

contents…

@@ -36,7 +39,7 @@

Two unbalanced columns

Columns in columns

-
+

contents…

diff --git a/column-div/expected.tex b/column-div/expected.tex index faede347..5131d92b 100644 --- a/column-div/expected.tex +++ b/column-div/expected.tex @@ -3,6 +3,9 @@ \section{column-div test}\label{column-div-test}} content\ldots{} +\leavevmode\hypertarget{thisdivdoesnothing}{}% +content\ldots{} + \hypertarget{three-columns}{% \subsection{Three columns}\label{three-columns}} @@ -16,8 +19,8 @@ \subsection{Three columns}\label{three-columns}} \end{multicols} -\hypertarget{two-unbalanced-columns}{% -\subsection{Two unbalanced columns}\label{two-unbalanced-columns}} +\hypertarget{two-uneven-columns}{% +\subsection{Two uneven columns}\label{two-uneven-columns}} \begin{minipage}[b]{0.4\columnwidth} diff --git a/column-div/sample.md b/column-div/sample.md index 7852f21f..1e659681 100644 --- a/column-div/sample.md +++ b/column-div/sample.md @@ -11,8 +11,12 @@ header-includes: # column-div test content... +::: {#thisdivdoesnothing} +content... +::: + ## Three columns -::: {.multicols column-count="3"} +::: {.anotherclassname .multicols column-count="3"} content... content... @@ -20,7 +24,7 @@ content... content... ::: -## Two unbalanced columns +## Two uneven columns :::::: {.columns} ::: {.column width="40%" valign="b"} contents... From c887e85739575780c13a94b11d45ab347993214c Mon Sep 17 00:00:00 2001 From: chrisaga Date: Thu, 11 Nov 2021 15:38:23 +0100 Subject: [PATCH 05/16] add color (html and latex) and background-color (html) processing plus small code refactoring --- column-div/column-div.lua | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/column-div/column-div.lua b/column-div/column-div.lua index 6271ae52..908c5653 100644 --- a/column-div/column-div.lua +++ b/column-div/column-div.lua @@ -1,6 +1,6 @@ --[[ column-div - leverage Pandoc native divs to make balanced and unbalanced column - and other things based on class name and attirbutes. + and other things based on class name and attributes. Copyright: © 2021 Christophe Agathon License: MIT – see LICENSE file for details @@ -50,7 +50,7 @@ function Div(div) end -- build the returned list of blocks begin_env = List:new{pandoc.RawBlock('tex', - '\\begin' .. '{' .. env .. '}' .. options)} + '\\begin{' .. env .. '}' .. options)} end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')} returned_list = begin_env .. div.content .. end_env @@ -69,8 +69,17 @@ function Div(div) if opt then options = '[' .. opt .. ']' .. options end begin_env = List:new{pandoc.RawBlock('tex', - '\\begin' .. '{' .. 'minipage' .. '}' .. options)} - end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. 'minipage' .. '}')} + '\\begin{minipage}' .. options)} + end_env = List:new{pandoc.RawBlock('tex', '\\end{minipage}')} + + -- add support for color TODO: background + opt = div.attributes.color + if opt then + begin_env = begin_env .. List:new{pandoc.RawBlock('tex', + '\\color{' .. opt .. '}')} + div.attributes.color = nil -- consume attribute + end + returned_list = begin_env .. div.content .. end_env elseif div.classes:includes('columns') then @@ -109,25 +118,39 @@ function Div(div) end begin_env = List:new{pandoc.RawBlock('tex', - '\\begin' .. '{' .. env .. '}' .. options)} + '\\begin{' .. env .. '}' .. options)} end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')} returned_list = begin_env .. div.content .. end_env end - -- if the format is html add support for multi columns + -- if the format is html add what is not already done by plain pandoc elseif FORMAT:match 'html' then + local style + -- add support for multi columns opt = div.attributes['column-count'] if opt then - -- add column-count to style if it exists - if div.attributes.style then - div.attributes.style = div.attributes.style .. - '; column-count: ' .. opt - else - div.attributes.style = 'column-count: ' .. opt - end + -- add column-count to style + style = 'column-count: ' .. opt .. ';' .. (style or '') div.attributes['column-count'] = nil -- column-count is "consumed" by the filter otherwise it would appear as -- data-column-count="…" in the resulting document + end + -- add support for color TODO: latex counterpart + opt = div.attributes.color + if opt then + -- add color to style + style = 'color: ' .. opt .. ';' .. (style or '') + div.attributes.color = nil -- consume attribute + end + opt = div.attributes['background-color'] + if opt then + -- add color to style + style = 'background-color: ' .. opt .. ';' .. (style or '') + div.attributes['background-color'] = nil -- consume attribute + end + -- if we have style then build returned list + if style then + div.attributes.style = style .. (div.attributes.style or '') returned_list = List:new{pandoc.Div(div.content, div.attr)} end end From f4e7a64ceceb485ff091534cf0841cde3e5b2385 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Thu, 11 Nov 2021 17:11:35 +0100 Subject: [PATCH 06/16] background-color processing for latex output --- column-div/column-div.lua | 40 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/column-div/column-div.lua b/column-div/column-div.lua index 908c5653..6ad9e96c 100644 --- a/column-div/column-div.lua +++ b/column-div/column-div.lua @@ -62,7 +62,14 @@ function Div(div) opt = div.attributes.width if opt then local width=tonumber(string.match(opt,'(%f[%d]%d[,.%d]*%f[%D])%%'))/100 - options = '{' .. tostring(width) .. '\\columnwidth}' + options = '{' .. tostring(width) + if div.attributes['background-color'] then + -- fix the width for the \colorbox + options = '{\\dimexpr' .. tostring(width) + .. '\\columnwidth-4\\fboxsep\\relax}' + else + options = '{' .. tostring(width) .. '\\columnwidth}' + end end opt = div.attributes.valign @@ -72,7 +79,7 @@ function Div(div) '\\begin{minipage}' .. options)} end_env = List:new{pandoc.RawBlock('tex', '\\end{minipage}')} - -- add support for color TODO: background + -- add support for color opt = div.attributes.color if opt then begin_env = begin_env .. List:new{pandoc.RawBlock('tex', @@ -80,25 +87,22 @@ function Div(div) div.attributes.color = nil -- consume attribute end + opt = div.attributes['background-color'] + if opt then + begin_env = List:new{pandoc.RawBlock('tex', + '\\colorbox{' .. opt .. '}{')} + .. begin_env + end_env = end_env .. List:new{pandoc.RawBlock('tex', '}')} + div.attributes['background-color'] = nil -- consume attribute + end + returned_list = begin_env .. div.content .. end_env elseif div.classes:includes('columns') then - env = 'columns' - -- merge two consecutives RawBlocks (\end... and \begin...) - -- to get rid of the unwanted blank line - local blocks = div.content - local rbtxt = '' - - for i = #blocks-1, 1, -1 do - if i > 1 and blocks[i].tag == 'RawBlock' and blocks[i].text:match 'end' - and blocks[i+1].tag == 'RawBlock' and blocks[i+1].text:match 'begin' - then - rbtxt = blocks[i].text .. blocks[i+1].text - blocks:remove(i+1) - blocks[i].text = rbtxt - end - end - returned_list=blocks + -- it turns-out that asimple Tex \mbox do the job + begin_env = List:new{pandoc.RawBlock('tex', '\\mbox{')} + end_env = List:new{pandoc.RawBlock('tex', '}')} + returned_list = begin_env .. div.content .. end_env else -- other environments ex: multicols From 99185511732e231e85a43ef3d9b77e1686d53a41 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Fri, 12 Nov 2021 11:00:47 +0100 Subject: [PATCH 07/16] update test files to match changes in the filter --- column-div/expected.html | 4 ++-- column-div/expected.tex | 32 ++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/column-div/expected.html b/column-div/expected.html index f99ea173..cd58e0eb 100644 --- a/column-div/expected.html +++ b/column-div/expected.html @@ -25,7 +25,7 @@

column-div test

content…

Three columns

-
+

content…

content…

content…

@@ -39,7 +39,7 @@

Two uneven columns

Columns in columns

-
+

contents…

diff --git a/column-div/expected.tex b/column-div/expected.tex index 5131d92b..37df955c 100644 --- a/column-div/expected.tex +++ b/column-div/expected.tex @@ -22,49 +22,73 @@ \subsection{Three columns}\label{three-columns}} \hypertarget{two-uneven-columns}{% \subsection{Two uneven columns}\label{two-uneven-columns}} +\mbox{ + \begin{minipage}[b]{0.4\columnwidth} contents\ldots{} -\end{minipage}\begin{minipage}[b]{0.6\columnwidth} +\end{minipage} + +\begin{minipage}[b]{0.6\columnwidth} contents\ldots{} \end{minipage} +} + \hypertarget{columns-in-columns}{% \subsection{Columns in columns}\label{columns-in-columns}} \begin{multicols}{3} +\mbox{ + \begin{minipage}[b]{0.2\columnwidth} contents\ldots{} -\end{minipage}\begin{minipage}[b]{0.8\columnwidth} +\end{minipage} + +\begin{minipage}[b]{0.8\columnwidth} contents\ldots{} \end{minipage} +} + +\mbox{ + \begin{minipage}[b]{0.2\columnwidth} contents\ldots{} -\end{minipage}\begin{minipage}[b]{0.8\columnwidth} +\end{minipage} + +\begin{minipage}[b]{0.8\columnwidth} contents\ldots{} \end{minipage} +} + +\mbox{ + \begin{minipage}[b]{0.2\columnwidth} contents\ldots{} -\end{minipage}\begin{minipage}[b]{0.8\columnwidth} +\end{minipage} + +\begin{minipage}[b]{0.8\columnwidth} contents\ldots{} \end{minipage} +} + \end{multicols} From cfc9479c6191d13c55026a4c6fb3df05f7b2966b Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sun, 16 Jan 2022 18:04:25 +0100 Subject: [PATCH 08/16] Add color in sample.md and expected.* files --- column-div/expected.html | 150 +++++++++++++++++++++++++++++++++++++++ column-div/expected.tex | 49 ++++++++++++- column-div/sample.md | 23 +++++- 3 files changed, 220 insertions(+), 2 deletions(-) diff --git a/column-div/expected.html b/column-div/expected.html index cd58e0eb..3f7820d8 100644 --- a/column-div/expected.html +++ b/column-div/expected.html @@ -6,13 +6,148 @@ Test + @@ -62,5 +197,20 @@

Columns in columns

+

Columns and Colors

+
+
+

blue content…

+
+

content on red background…

+
+
+
+
+

blue content on red background…

+
+

contents…

+
+
diff --git a/column-div/expected.tex b/column-div/expected.tex index 37df955c..a40af16b 100644 --- a/column-div/expected.tex +++ b/column-div/expected.tex @@ -3,7 +3,7 @@ \section{column-div test}\label{column-div-test}} content\ldots{} -\leavevmode\hypertarget{thisdivdoesnothing}{}% +\leavevmode\vadjust pre{\hypertarget{thisdivdoesnothing}{}}% content\ldots{} \hypertarget{three-columns}{% @@ -92,3 +92,50 @@ \subsection{Columns in columns}\label{columns-in-columns}} } \end{multicols} + +\hypertarget{columns-and-colors}{% +\subsection{Columns and Colors}\label{columns-and-colors}} + +\mbox{ + +\begin{minipage}{0.4\columnwidth} + +\color{blue} + +blue content\ldots{} + +\end{minipage} + +\colorbox{red}{ + +\begin{minipage}{\dimexpr0.6\columnwidth-4\fboxsep\relax} + +content on red background\ldots{} + +\end{minipage} + +} + +} + +\mbox{ + +\colorbox{red}{ + +\begin{minipage}{\dimexpr0.6\columnwidth-4\fboxsep\relax} + +\color{blue} + +blue content on red background\ldots{} + +\end{minipage} + +} + +\begin{minipage}{0.4\columnwidth} + +contents\ldots{} + +\end{minipage} + +} diff --git a/column-div/sample.md b/column-div/sample.md index 1e659681..a6a8d412 100644 --- a/column-div/sample.md +++ b/column-div/sample.md @@ -61,4 +61,25 @@ contents... contents... ::: :::::: -::::::::: \ No newline at end of file +::::::::: + + +## Columns and Colors + +:::::: {.columns} +::: {.column width="40%" color="blue"} +blue content... +::: +::: {.column width="60%" background-color="red"} +content on red background... +::: +:::::: + +:::::: {.columns} +::: {.column width="60%" color="blue" background-color="red"} +blue content on red background... +::: +::: {.column width="40%" } +contents... +::: +:::::: \ No newline at end of file From f3ede8567fe6008686f6e53b9cbd1f5b12ee6ec9 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sun, 16 Jan 2022 18:05:45 +0100 Subject: [PATCH 09/16] Remove beamer support and arbitrary latex environment --- column-div/column-div.lua | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/column-div/column-div.lua b/column-div/column-div.lua index 6ad9e96c..6329959e 100644 --- a/column-div/column-div.lua +++ b/column-div/column-div.lua @@ -22,6 +22,10 @@ Note: You need to include multicol latex package to get balanced columns in latex or pdf I tried to use well known html or latex parameter. Even if lua doen't like hyphens like in column-count. + +Bugs: * html rendering throws a warning [WARNING] Ignoring duplicate attribute style="width:60%;". + when widht AND color are set and totally ignore the width + attribute. Don't know if this bug is mine --]] local List = require 'pandoc.List' @@ -40,22 +44,8 @@ function Div(div) -- effect. if not div.classes or #div.classes == 0 then return nil end - -- if the output is beamer do columns - if FORMAT:match 'beamer' then - -- only arbitrary environment support in beamer for now. Environment has to - -- be the firs class name. - env = div.classes[1] - if options == '' and div.attributes['data-latex'] then - options = div.attributes['data-latex'] - end - -- build the returned list of blocks - begin_env = List:new{pandoc.RawBlock('tex', - '\\begin{' .. env .. '}' .. options)} - end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')} - returned_list = begin_env .. div.content .. end_env - -- if the format is latex then do minipage and others (like multicol) - elseif FORMAT:match 'latex' then + if FORMAT:match 'latex' then -- build the returned list of blocks if div.classes:includes('column') then env = 'column' @@ -111,6 +101,7 @@ function Div(div) -- process supported options opt = div.attributes['column-count'] if opt then options = '{' .. opt .. '}' end + --[[ This functionality will be moved in another filter since it can't be consistent with the positionless classname requirement else -- Latex skilled users can use arbitrary environments passed as -- the first (and only signifiant) class name. @@ -119,6 +110,7 @@ function Div(div) if options == '' and div.attributes['data-latex'] then options = div.attributes['data-latex'] end + --]] end begin_env = List:new{pandoc.RawBlock('tex', @@ -139,7 +131,7 @@ function Div(div) -- column-count is "consumed" by the filter otherwise it would appear as -- data-column-count="…" in the resulting document end - -- add support for color TODO: latex counterpart + -- add support for color opt = div.attributes.color if opt then -- add color to style @@ -156,6 +148,7 @@ function Div(div) if style then div.attributes.style = style .. (div.attributes.style or '') returned_list = List:new{pandoc.Div(div.content, div.attr)} + --returned_list = List:new{pandoc.Div(div.content)} end end return returned_list From 337191488f5e1bafd5d75031bf7277ad0f7c3d52 Mon Sep 17 00:00:00 2001 From: chrisaga <31566103+chrisaga@users.noreply.github.com> Date: Mon, 17 Jan 2022 14:03:24 +0100 Subject: [PATCH 10/16] Update column-div/column-div.lua (tipo in comment) Co-authored-by: Caleb Maclennan --- column-div/column-div.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/column-div/column-div.lua b/column-div/column-div.lua index 6329959e..942d8052 100644 --- a/column-div/column-div.lua +++ b/column-div/column-div.lua @@ -24,7 +24,7 @@ Note: You need to include multicol latex package to get balanced columns Even if lua doen't like hyphens like in column-count. Bugs: * html rendering throws a warning [WARNING] Ignoring duplicate attribute style="width:60%;". - when widht AND color are set and totally ignore the width + when width AND color are set and totally ignore the width attribute. Don't know if this bug is mine --]] local List = require 'pandoc.List' From 1abec29a0e13643b597ec693aab78479268ff060 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sat, 22 Jan 2022 12:02:14 +0100 Subject: [PATCH 11/16] Create files --- tables-vrules/Makefile | 12 ++++++ tables-vrules/README.md | 66 +++++++++++++++++++++++++++++++++ tables-vrules/sample.md | 51 +++++++++++++++++++++++++ tables-vrules/tables-vrules.lua | 20 ++++++++++ 4 files changed, 149 insertions(+) create mode 100644 tables-vrules/Makefile create mode 100644 tables-vrules/README.md create mode 100644 tables-vrules/sample.md create mode 100644 tables-vrules/tables-vrules.lua diff --git a/tables-vrules/Makefile b/tables-vrules/Makefile new file mode 100644 index 00000000..b33c9940 --- /dev/null +++ b/tables-vrules/Makefile @@ -0,0 +1,12 @@ +DIFF ?= diff --strip-trailing-cr -u + +.PHONY: test + +test: test_latex + +test_latex: sample.md expected.tex tables-vrules.lua + @pandoc --lua-filter tables-vrules.lua --to=latex $< \ + | $(DIFF) expected.tex - + +expected.tex: sample.md tables-vrules.lua + pandoc --lua-filter tables-vrules.lua --output $@ $< diff --git a/tables-vrules/README.md b/tables-vrules/README.md new file mode 100644 index 00000000..0336a9ff --- /dev/null +++ b/tables-vrules/README.md @@ -0,0 +1,66 @@ +--- +title: "tables-vrules - Pandoc filter to add vertical rules to tables" +author: "Christophe Agathon" +--- + +Tables VRules +======= + +Add vertical rules to tables. + +v1.0. Copyright: © 2021 Christophe Agathon + +License: MIT - see LICENSE file for details. + +Introduction +------------ + +Since pandoc has a strong policy against vertical rules in tables, peole have been looking for solutions to get those, especially when rendering PDF files via Latex. + +For more information you can refer to : + +* This Pandoc issue [https://github.com/jgm/pandoc/issues/922](https://github.com/jgm/pandoc/issues/922) +* This discussion on StackExchange [https://tex.stackexchange.com/questions/595615/how-can-i-reformat-a-table-using-markdown-pandoc-pdf/596005](https://tex.stackexchange.com/questions/595615/how-can-i-reformat-a-table-using-markdown-pandoc-pdf/596005) + +marjinshraagen proposed a solution based on a patch of `\LT@array` in Latex. It used to work pretty well. It doesn't anymore for Multiline Tables and Pipes Tables since Pandoc changed the Latex code it generates for those kind of tables. Don't know exactly when it changed but sometime between Pandoc version 2.9.2.1 and version 2.16. + +Since patching in Latex is tricky and I am not a Latex guru, I didn't manage to make it work again, so I made this filter which change the call to `longtable` to add vertical rules in a more "natural" whay. + + +Usage +----- + +### Formating the document + +Simply use on of the table synthax allowed by Pandoc (details in +[Pandoc's manual](https://pandoc.org/MANUAL.html#tables). + + +### Rendering the document + +Copy `tables-vrules.lua` in your document folder or in your pandoc +data directory (details in +[Pandoc's manual](https://pandoc.org/MANUAL.html#option--lua-filter)). +Run it on your document with a `--luafilter` option: + +```bash +pandoc --luafilter tables-vrules.lua SOURCE.md -o OUTPUT.pdf + +``` + +or specify it in a defaults file (details in +[Pandoc's manual](https://pandoc.org/MANUAL.html#option--defaults)). + +This will generate Tables with vertical rules in Latex and PDF documents from Pandoc markdown source files. + +### Limitations + +This filter is active only for Latex and PDF output. + +Vertical rules in HTML documents should be handled via css styling. + +Contributing +------------ + +PRs welcome. + diff --git a/tables-vrules/sample.md b/tables-vrules/sample.md new file mode 100644 index 00000000..3950c61d --- /dev/null +++ b/tables-vrules/sample.md @@ -0,0 +1,51 @@ + +# Simple Table + + Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 + +Table: Demonstration of simple table syntax. + +# Multiline Tables + +------------------------------------------------------------- + Centered Default Right Left + Header Aligned Aligned Aligned +----------- ------- --------------- ------------------------- + First row 12.0 Example of a row that + spans multiple lines. + + Second row 5.0 Here's another one. Note + the blank line between + rows. +------------------------------------------------------------- + +Table: Here's the caption. It, too, may span +multiple lines. + +# Grid Tables + +: Sample grid table. + ++---------------+---------------+--------------------+ +| Fruit | Price | Advantages | ++===============+===============+====================+ +| Bananas | $1.34 | - built-in wrapper | +| | | - bright color | ++---------------+---------------+--------------------+ +| Oranges | $2.10 | - cures scurvy | +| | | - tasty | ++---------------+---------------+--------------------+ + +# Pipes Tables + +| Right | Left | Default | Center | +|------:|:-----|---------|:------:| +| 12 | 12 | 12 | 12 | +| 123 | 123 | 123 | 123 | +| 1 | 1 | 1 | 1 | + + : Demonstration of pipe table syntax. \ No newline at end of file diff --git a/tables-vrules/tables-vrules.lua b/tables-vrules/tables-vrules.lua new file mode 100644 index 00000000..6646de53 --- /dev/null +++ b/tables-vrules/tables-vrules.lua @@ -0,0 +1,20 @@ + --[[ +tables-vrules - adds vertical rules to tables for latex output + +Copyright: © 2021 Christophe Agathon +License: MIT – see LICENSE file for details + +Credits: marijnschraagen for the original Latex hack + +Output: latex, pdf. + +Usage: See README.md for details + +--]] +local List = require 'pandoc.List' + + +function Table(table) + local returned-list + +end From e6976fcc3db471697cc23361d74d3b5dd6be39c6 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sat, 22 Jan 2022 20:21:22 +0100 Subject: [PATCH 12/16] First working filter with test file for the 4 kinds of tables supported by pandoc --- tables-vrules/Makefile | 4 +- tables-vrules/README.md | 4 +- tables-vrules/expected.tex | 196 ++++++++++++++++++++++++++++++++ tables-vrules/sample.md | 5 + tables-vrules/tables-vrules.lua | 56 ++++++++- 5 files changed, 261 insertions(+), 4 deletions(-) create mode 100644 tables-vrules/expected.tex diff --git a/tables-vrules/Makefile b/tables-vrules/Makefile index b33c9940..8e6d2a70 100644 --- a/tables-vrules/Makefile +++ b/tables-vrules/Makefile @@ -5,8 +5,8 @@ DIFF ?= diff --strip-trailing-cr -u test: test_latex test_latex: sample.md expected.tex tables-vrules.lua - @pandoc --lua-filter tables-vrules.lua --to=latex $< \ + @pandoc -s --lua-filter tables-vrules.lua --to=latex $< \ | $(DIFF) expected.tex - expected.tex: sample.md tables-vrules.lua - pandoc --lua-filter tables-vrules.lua --output $@ $< + pandoc -s --lua-filter tables-vrules.lua --output $@ $< diff --git a/tables-vrules/README.md b/tables-vrules/README.md index 0336a9ff..70a40006 100644 --- a/tables-vrules/README.md +++ b/tables-vrules/README.md @@ -24,7 +24,9 @@ For more information you can refer to : marjinshraagen proposed a solution based on a patch of `\LT@array` in Latex. It used to work pretty well. It doesn't anymore for Multiline Tables and Pipes Tables since Pandoc changed the Latex code it generates for those kind of tables. Don't know exactly when it changed but sometime between Pandoc version 2.9.2.1 and version 2.16. -Since patching in Latex is tricky and I am not a Latex guru, I didn't manage to make it work again, so I made this filter which change the call to `longtable` to add vertical rules in a more "natural" whay. +Since patching in Latex is tricky and I am not a Latex guru, I didn't manage to make it work again, so I made this filter which change the call to `longtable` to add vertical rules in a more "natural" way. + +The filter adds some code in the Latex preamble because Pandoc adds it only if there are tables in the document (which is OK) and only if the Tables blocks are not processed by a filter (which might be considered as bug). Usage diff --git a/tables-vrules/expected.tex b/tables-vrules/expected.tex new file mode 100644 index 00000000..ceb26127 --- /dev/null +++ b/tables-vrules/expected.tex @@ -0,0 +1,196 @@ +% Options for packages loaded elsewhere +\PassOptionsToPackage{unicode}{hyperref} +\PassOptionsToPackage{hyphens}{url} +% +\documentclass[ +]{article} +\usepackage{amsmath,amssymb} +\usepackage{lmodern} +\usepackage{iftex} +\ifPDFTeX + \usepackage[T1]{fontenc} + \usepackage[utf8]{inputenc} + \usepackage{textcomp} % provide euro and other symbols +\else % if luatex or xetex + \usepackage{unicode-math} + \defaultfontfeatures{Scale=MatchLowercase} + \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} +\fi +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +\usepackage{xcolor} +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} +\hypersetup{ + pdftitle={table-vrules lua filter test file}, + pdfauthor={Christophe Agathon}, + hidelinks, + pdfcreator={LaTeX via pandoc}} +\urlstyle{same} % disable monospaced font for URLs +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering +\usepackage{longtable,booktabs,array} + \usepackage{calc} % for calculating minipage widths + % Correct order of tables after \paragraph or \subparagraph + \usepackage{etoolbox} + \makeatletter + \patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} + \makeatother + % Allow footnotes in longtable head/foot + \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} + \makesavenoteenv{longtable} +\ifLuaTeX + \usepackage{selnolig} % disable illegal ligatures +\fi + +\title{table-vrules lua filter test file} +\author{Christophe Agathon} +\date{} + +\begin{document} +\maketitle + +\hypertarget{simple-table}{% +\section{Simple Table}\label{simple-table}} + +\begin{longtable}[]{@{}|r|l|c|l|@{}} +\caption{Demonstration of simple table syntax.}\tabularnewline +\toprule +Right & Left & Center & Default \\ +\midrule +\endfirsthead +\toprule +Right & Left & Center & Default \\ +\midrule +\endhead +12 & 12 & 12 & 12 \\ +123 & 123 & 123 & 123 \\ +1 & 1 & 1 & 1 \\ +\bottomrule +\end{longtable} + +\hypertarget{multiline-tables}{% +\section{Multiline Tables}\label{multiline-tables}} + +\begin{longtable}[]{@{} + |>{\centering\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.1667}} + |>{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.1111}} + |>{\raggedleft\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.2222}} + |>{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.3611}}|@{}} +\caption{Here's the caption. It, too, may span multiple +lines.}\tabularnewline +\toprule +\begin{minipage}[b]{\linewidth}\centering +Centered Header +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Default Aligned +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft +Right Aligned +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Left Aligned +\end{minipage} \\ +\midrule +\endfirsthead +\toprule +\begin{minipage}[b]{\linewidth}\centering +Centered Header +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Default Aligned +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft +Right Aligned +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Left Aligned +\end{minipage} \\ +\midrule +\endhead +First & row & 12.0 & Example of a row that spans multiple lines. \\ +Second & row & 5.0 & Here's another one. Note the blank line between +rows. \\ +\bottomrule +\end{longtable} + +\hypertarget{grid-tables}{% +\section{Grid Tables}\label{grid-tables}} + +\begin{longtable}[]{@{} + |>{\raggedright\arraybackslash}p{(\columnwidth - 4\tabcolsep) * \real{0.2222}} + |>{\raggedright\arraybackslash}p{(\columnwidth - 4\tabcolsep) * \real{0.2222}} + |>{\raggedright\arraybackslash}p{(\columnwidth - 4\tabcolsep) * \real{0.2917}}|@{}} +\caption{Sample grid table.}\tabularnewline +\toprule +\begin{minipage}[b]{\linewidth}\raggedright +Fruit +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Price +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Advantages +\end{minipage} \\ +\midrule +\endfirsthead +\toprule +\begin{minipage}[b]{\linewidth}\raggedright +Fruit +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Price +\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright +Advantages +\end{minipage} \\ +\midrule +\endhead +Bananas & \$1.34 & \begin{minipage}[t]{\linewidth}\raggedright +\begin{itemize} +\tightlist +\item + built-in wrapper +\item + bright color +\end{itemize} +\end{minipage} \\ +Oranges & \$2.10 & \begin{minipage}[t]{\linewidth}\raggedright +\begin{itemize} +\tightlist +\item + cures scurvy +\item + tasty +\end{itemize} +\end{minipage} \\ +\bottomrule +\end{longtable} + +\hypertarget{pipes-tables}{% +\section{Pipes Tables}\label{pipes-tables}} + +\begin{longtable}[]{@{}|r|l|l|c|@{}} +\caption{Demonstration of pipe table syntax.}\tabularnewline +\toprule +Right & Left & Default & Center \\ +\midrule +\endfirsthead +\toprule +Right & Left & Default & Center \\ +\midrule +\endhead +12 & 12 & 12 & 12 \\ +123 & 123 & 123 & 123 \\ +1 & 1 & 1 & 1 \\ +\bottomrule +\end{longtable} + +\end{document} diff --git a/tables-vrules/sample.md b/tables-vrules/sample.md index 3950c61d..4cfa5d8d 100644 --- a/tables-vrules/sample.md +++ b/tables-vrules/sample.md @@ -1,3 +1,8 @@ +--- +title: table-vrules lua filter test file +author: Christophe Agathon + +--- # Simple Table diff --git a/tables-vrules/tables-vrules.lua b/tables-vrules/tables-vrules.lua index 6646de53..65daf20f 100644 --- a/tables-vrules/tables-vrules.lua +++ b/tables-vrules/tables-vrules.lua @@ -15,6 +15,60 @@ local List = require 'pandoc.List' function Table(table) - local returned-list + local returned_list + local latex_code = '' + local coldef ='' + local envdef ='' + local new_coldef ='' + if FORMAT:match 'latex' then + + --print(pandoc.utils.stringify(table.caption)) + + latex_code = pandoc.write ( pandoc.Pandoc({table}),'latex' ) + envdef, begdef, coldef, enddef = latex_code:match("((\\begin{longtable}%[[^%]]*%]{@{})(.*)(@{}}))") + + if not coldef then return nil end + + if coldef:match('^[lrc]+$') then + -- old style + new_coldef = coldef:gsub('(.)','|%1') .. '|' + else + -- asuming new style + new_coldef = coldef:gsub('(>)','|%1') .. '|' + end + --print ('>', coldef) + --print ('>', new_coldef) + --print ('>', envdef) + --print ('>', begdef .. new_coldef .. enddef .. + -- latex_code:sub(envdef:len() + 1)) + returned_list = List:new{pandoc.RawBlock('tex', + begdef .. new_coldef .. enddef .. + latex_code:sub(envdef:len() + 1))} + end + return returned_list +end + +function Meta(meta) + -- We have to add this since Pandoc doesn't do it when a filter is + -- processing tables (is it a bug or a feature ???) + -- + includes = [[\usepackage{longtable,booktabs,array} + \usepackage{calc} % for calculating minipage widths + % Correct order of tables after \paragraph or \subparagraph + \usepackage{etoolbox} + \makeatletter + \patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} + \makeatother + % Allow footnotes in longtable head/foot + \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} + \makesavenoteenv{longtable} ]] + + if meta['header-includes'] then + table.insert(meta['header-includes'], pandoc.RawBlock('tex', includes)) + else + meta['header-includes'] = List:new{pandoc.RawBlock('tex', includes)} + end + + return meta end From 816295ee371dc9f2538959ba1deeebb228864973 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sat, 22 Jan 2022 20:31:33 +0100 Subject: [PATCH 13/16] Fix the gap between horizontal and vertical rules --- tables-vrules/expected.tex | 9 +++++++-- tables-vrules/tables-vrules.lua | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tables-vrules/expected.tex b/tables-vrules/expected.tex index ceb26127..8655dbb3 100644 --- a/tables-vrules/expected.tex +++ b/tables-vrules/expected.tex @@ -45,7 +45,8 @@ \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \setcounter{secnumdepth}{-\maxdimen} % remove section numbering -\usepackage{longtable,booktabs,array} +%begin tables-vrules.lua + \usepackage{longtable,booktabs,array} \usepackage{calc} % for calculating minipage widths % Correct order of tables after \paragraph or \subparagraph \usepackage{etoolbox} @@ -54,7 +55,11 @@ \makeatother % Allow footnotes in longtable head/foot \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} - \makesavenoteenv{longtable} + \makesavenoteenv{longtable} + \setlength{\aboverulesep}{0pt} + \setlength{\belowrulesep}{0pt} + \renewcommand{\arraystretch}{1.3} +%end tables-vrules.lua \ifLuaTeX \usepackage{selnolig} % disable illegal ligatures \fi diff --git a/tables-vrules/tables-vrules.lua b/tables-vrules/tables-vrules.lua index 65daf20f..d2adece3 100644 --- a/tables-vrules/tables-vrules.lua +++ b/tables-vrules/tables-vrules.lua @@ -53,7 +53,8 @@ function Meta(meta) -- We have to add this since Pandoc doesn't do it when a filter is -- processing tables (is it a bug or a feature ???) -- - includes = [[\usepackage{longtable,booktabs,array} + includes = [[%begin tables-vrules.lua + \usepackage{longtable,booktabs,array} \usepackage{calc} % for calculating minipage widths % Correct order of tables after \paragraph or \subparagraph \usepackage{etoolbox} @@ -62,7 +63,11 @@ function Meta(meta) \makeatother % Allow footnotes in longtable head/foot \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} - \makesavenoteenv{longtable} ]] + \makesavenoteenv{longtable} + \setlength{\aboverulesep}{0pt} + \setlength{\belowrulesep}{0pt} + \renewcommand{\arraystretch}{1.3} +%end tables-vrules.lua]] if meta['header-includes'] then table.insert(meta['header-includes'], pandoc.RawBlock('tex', includes)) From 8a2fbca5a422e461d023bfc0b81828ce57984886 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sat, 22 Jan 2022 20:39:51 +0100 Subject: [PATCH 14/16] Code cleaning --- tables-vrules/tables-vrules.lua | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tables-vrules/tables-vrules.lua b/tables-vrules/tables-vrules.lua index d2adece3..c454f0b7 100644 --- a/tables-vrules/tables-vrules.lua +++ b/tables-vrules/tables-vrules.lua @@ -2,6 +2,7 @@ tables-vrules - adds vertical rules to tables for latex output Copyright: © 2021 Christophe Agathon + License: MIT – see LICENSE file for details Credits: marijnschraagen for the original Latex hack @@ -23,10 +24,9 @@ function Table(table) if FORMAT:match 'latex' then - --print(pandoc.utils.stringify(table.caption)) - latex_code = pandoc.write ( pandoc.Pandoc({table}),'latex' ) - envdef, begdef, coldef, enddef = latex_code:match("((\\begin{longtable}%[[^%]]*%]{@{})(.*)(@{}}))") + envdef, begdef, coldef, enddef = + latex_code:match("((\\begin{longtable}%[[^%]]*%]{@{})(.*)(@{}}))") if not coldef then return nil end @@ -37,11 +37,6 @@ function Table(table) -- asuming new style new_coldef = coldef:gsub('(>)','|%1') .. '|' end - --print ('>', coldef) - --print ('>', new_coldef) - --print ('>', envdef) - --print ('>', begdef .. new_coldef .. enddef .. - -- latex_code:sub(envdef:len() + 1)) returned_list = List:new{pandoc.RawBlock('tex', begdef .. new_coldef .. enddef .. latex_code:sub(envdef:len() + 1))} @@ -52,7 +47,7 @@ end function Meta(meta) -- We have to add this since Pandoc doesn't do it when a filter is -- processing tables (is it a bug or a feature ???) - -- + includes = [[%begin tables-vrules.lua \usepackage{longtable,booktabs,array} \usepackage{calc} % for calculating minipage widths From fb6c1e956b4e884b2a1f126694ff9d0c583be739 Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sat, 29 Jan 2022 16:24:21 +0100 Subject: [PATCH 15/16] Manage both horizontal and vertical rules without hacking longtable commands --- tables-vrules/Makefile | 8 +-- tables-vrules/README.md | 42 +++++++++--- tables-vrules/expected.tex | 38 +++++++---- tables-vrules/sample.md | 2 + tables-vrules/tables-rules.lua | 114 ++++++++++++++++++++++++++++++++ tables-vrules/tables-vrules.lua | 74 --------------------- 6 files changed, 179 insertions(+), 99 deletions(-) create mode 100644 tables-vrules/tables-rules.lua delete mode 100644 tables-vrules/tables-vrules.lua diff --git a/tables-vrules/Makefile b/tables-vrules/Makefile index 8e6d2a70..ab1ab717 100644 --- a/tables-vrules/Makefile +++ b/tables-vrules/Makefile @@ -4,9 +4,9 @@ DIFF ?= diff --strip-trailing-cr -u test: test_latex -test_latex: sample.md expected.tex tables-vrules.lua - @pandoc -s --lua-filter tables-vrules.lua --to=latex $< \ +test_latex: sample.md expected.tex tables-rules.lua + @pandoc -s --lua-filter tables-rules.lua --to=latex $< \ | $(DIFF) expected.tex - -expected.tex: sample.md tables-vrules.lua - pandoc -s --lua-filter tables-vrules.lua --output $@ $< +expected.tex: sample.md tables-rules.lua + pandoc -s --lua-filter tables-rules.lua --output $@ $< diff --git a/tables-vrules/README.md b/tables-vrules/README.md index 70a40006..a62e468e 100644 --- a/tables-vrules/README.md +++ b/tables-vrules/README.md @@ -1,12 +1,12 @@ --- -title: "tables-vrules - Pandoc filter to add vertical rules to tables" +title: "tables-rules - Pandoc filter to add rules to tables in LaTeX" author: "Christophe Agathon" --- -Tables VRules +Tables Rules ======= -Add vertical rules to tables. +Add vertical and horizontal rules to tables. v1.0. Copyright: © 2021 Christophe Agathon @@ -15,7 +15,14 @@ License: MIT - see LICENSE file for details. Introduction ------------ -Since pandoc has a strong policy against vertical rules in tables, peole have been looking for solutions to get those, especially when rendering PDF files via Latex. +This filter manages vertical and horizontal rules in latex generated by Pandoc. + +Two boolean metadata `tables-vrules` and `tables-hrules` control if tables will have vertical or horizontal rules, or both. + +History +------- + +Since pandoc has a strong policy against vertical rules in tables, people have been looking for solutions to get those, especially when rendering PDF files via Latex. For more information you can refer to : @@ -26,27 +33,46 @@ marjinshraagen proposed a solution based on a patch of `\LT@array` in Latex. It Since patching in Latex is tricky and I am not a Latex guru, I didn't manage to make it work again, so I made this filter which change the call to `longtable` to add vertical rules in a more "natural" way. +Note +---- + +### Préamble + The filter adds some code in the Latex preamble because Pandoc adds it only if there are tables in the document (which is OK) and only if the Tables blocks are not processed by a filter (which might be considered as bug). +### Filter order + +You would probably call this filter after your other filters since it generates raw LaTeX code for every table in the document. Pandoc blocs and inlines are no longer available for subsequent filters. + +This might be better to do this in a writer than in a filter unfortunately writers are not modular like filters and one would have to implement the whole LaTeX writer to do this. + +### Compatibility + +Since the processing is not based on a LaTeX \patchcmd, compatibility is high. +Its compatible with `colortbl` and `array` packages. + +Rules are not doubled below the table first row (header) and last row as it happens with others hacks. Usage ----- ### Formating the document -Simply use on of the table synthax allowed by Pandoc (details in +Simply use one of the table synthax allowed by Pandoc (details in [Pandoc's manual](https://pandoc.org/MANUAL.html#tables). +Set `tables-vrules: true` and/or `tables-hrules: true` in the YAML preamble to get rules on all the tables of the document. + ### Rendering the document -Copy `tables-vrules.lua` in your document folder or in your pandoc +Copy `tables-rules.lua` in your document folder or in your pandoc data directory (details in [Pandoc's manual](https://pandoc.org/MANUAL.html#option--lua-filter)). Run it on your document with a `--luafilter` option: ```bash -pandoc --luafilter tables-vrules.lua SOURCE.md -o OUTPUT.pdf +pandoc --luafilter tables-rules.lua SOURCE.md -o OUTPUT.pdf ``` @@ -59,7 +85,7 @@ This will generate Tables with vertical rules in Latex and PDF documents from Pa This filter is active only for Latex and PDF output. -Vertical rules in HTML documents should be handled via css styling. +Rules in HTML documents should be handled via css styling. Contributing ------------ diff --git a/tables-vrules/expected.tex b/tables-vrules/expected.tex index 8655dbb3..1c4f180b 100644 --- a/tables-vrules/expected.tex +++ b/tables-vrules/expected.tex @@ -46,19 +46,19 @@ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \setcounter{secnumdepth}{-\maxdimen} % remove section numbering %begin tables-vrules.lua - \usepackage{longtable,booktabs,array} - \usepackage{calc} % for calculating minipage widths - % Correct order of tables after \paragraph or \subparagraph - \usepackage{etoolbox} - \makeatletter - \patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} - \makeatother - % Allow footnotes in longtable head/foot - \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} - \makesavenoteenv{longtable} - \setlength{\aboverulesep}{0pt} - \setlength{\belowrulesep}{0pt} - \renewcommand{\arraystretch}{1.3} +\usepackage{longtable,booktabs,array} +\usepackage{calc} % for calculating minipage widths +% Correct order of tables after \paragraph or \subparagraph +\usepackage{etoolbox} +\makeatletter +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +% Allow footnotes in longtable head/foot +\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} +\makesavenoteenv{longtable} +\setlength{\aboverulesep}{0pt} +\setlength{\belowrulesep}{0pt} +\renewcommand{\arraystretch}{1.3} %end tables-vrules.lua \ifLuaTeX \usepackage{selnolig} % disable illegal ligatures @@ -85,7 +85,11 @@ \section{Simple Table}\label{simple-table}} \midrule \endhead 12 & 12 & 12 & 12 \\ + +\midrule 123 & 123 & 123 & 123 \\ + +\midrule 1 & 1 & 1 & 1 \\ \bottomrule \end{longtable} @@ -125,6 +129,8 @@ \section{Multiline Tables}\label{multiline-tables}} \midrule \endhead First & row & 12.0 & Example of a row that spans multiple lines. \\ + +\midrule Second & row & 5.0 & Here's another one. Note the blank line between rows. \\ \bottomrule @@ -167,6 +173,8 @@ \section{Grid Tables}\label{grid-tables}} bright color \end{itemize} \end{minipage} \\ + +\midrule Oranges & \$2.10 & \begin{minipage}[t]{\linewidth}\raggedright \begin{itemize} \tightlist @@ -193,7 +201,11 @@ \section{Pipes Tables}\label{pipes-tables}} \midrule \endhead 12 & 12 & 12 & 12 \\ + +\midrule 123 & 123 & 123 & 123 \\ + +\midrule 1 & 1 & 1 & 1 \\ \bottomrule \end{longtable} diff --git a/tables-vrules/sample.md b/tables-vrules/sample.md index 4cfa5d8d..71ecb6e6 100644 --- a/tables-vrules/sample.md +++ b/tables-vrules/sample.md @@ -1,6 +1,8 @@ --- title: table-vrules lua filter test file author: Christophe Agathon +tables-vrules: true +tables-hrules: true --- diff --git a/tables-vrules/tables-rules.lua b/tables-vrules/tables-rules.lua new file mode 100644 index 00000000..4ff6ce1f --- /dev/null +++ b/tables-vrules/tables-rules.lua @@ -0,0 +1,114 @@ + --[[ +tables-vrules - adds vertical rules to tables for latex output + +Copyright: © 2021 Christophe Agathon + +License: MIT – see LICENSE file for details + +Credits: marijnschraagen for the original Latex hack + +Output: latex, pdf. + +Usage: See README.md for details + +--]] +local List = require 'pandoc.List' + +local vars = {} + +function get_vars (meta) + vars.vrules = meta['tables-vrules'] + vars.hrules = meta['tables-hrules'] +end + +function repl_midrules(m1, m2) + if m2:match('^\\[%w]+rule') then + -- don't double the rule + return m1 .. m2 + else + return m1 .. '\n\\midrule\n' .. m2 + end +end + +function Table(table) + local returned_list + local latex_code = '' + local coldef ='' + local envdef ='' + local new_coldef ='' + local end_line = '' + + if not vars.vrules and not vars.hrules then return nil end + + if FORMAT:match 'latex' then + + -- Get latex code for the whole table + latex_code = pandoc.write ( pandoc.Pandoc({table}),'latex' ) + + -- Rewrite column definition to add vertical rules if needed + if vars.vrules then + envdef, begdef, coldef, enddef = + latex_code:match("((\\begin{longtable}%[[^%]]*%]{@{})(.*)(@{}}))") + + if coldef then + if coldef:match('^[lrc]+$') then + -- old style + new_coldef = coldef:gsub('(.)', '|%1') .. '|' + else + -- asuming new style + new_coldef = coldef:gsub('(>)', '|%1') .. '|' + end + latex_code = latex_code:sub(envdef:len() + 1) + end + end + + -- Add \midrules after each row if needed + if vars.hrules then + latex_code = latex_code:gsub('(\\\\\n)([\\%w]+)', repl_midrules) + end + + -- Return modified latex code as a raw block + if vars.vrules then + returned_list = List:new{pandoc.RawBlock('tex', + begdef .. new_coldef .. enddef .. + latex_code)} + else + returned_list = List:new{pandoc.RawBlock('tex', latex_code)} + end + end + return returned_list +end + +function Meta(meta) + -- We have to add this since Pandoc doesn't do it when a filter is + -- processing tables (is it a bug or a feature ???) + + if not vars.vrules and not vars.hrules then return nil end + includes = [[ +%begin tables-vrules.lua +\usepackage{longtable,booktabs,array} +\usepackage{calc} % for calculating minipage widths +% Correct order of tables after \paragraph or \subparagraph +\usepackage{etoolbox} +\makeatletter +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +% Allow footnotes in longtable head/foot +\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} +\makesavenoteenv{longtable} +\setlength{\aboverulesep}{0pt} +\setlength{\belowrulesep}{0pt} +\renewcommand{\arraystretch}{1.3} +%end tables-vrules.lua +]] + + if meta['header-includes'] then + table.insert(meta['header-includes'], pandoc.RawBlock('tex', includes)) + else + meta['header-includes'] = List:new{pandoc.RawBlock('tex', includes)} + end + + return meta +end + +return {{Meta = get_vars}, {Table = Table}, {Meta = Meta}} diff --git a/tables-vrules/tables-vrules.lua b/tables-vrules/tables-vrules.lua deleted file mode 100644 index c454f0b7..00000000 --- a/tables-vrules/tables-vrules.lua +++ /dev/null @@ -1,74 +0,0 @@ - --[[ -tables-vrules - adds vertical rules to tables for latex output - -Copyright: © 2021 Christophe Agathon - -License: MIT – see LICENSE file for details - -Credits: marijnschraagen for the original Latex hack - -Output: latex, pdf. - -Usage: See README.md for details - ---]] -local List = require 'pandoc.List' - - -function Table(table) - local returned_list - local latex_code = '' - local coldef ='' - local envdef ='' - local new_coldef ='' - - if FORMAT:match 'latex' then - - latex_code = pandoc.write ( pandoc.Pandoc({table}),'latex' ) - envdef, begdef, coldef, enddef = - latex_code:match("((\\begin{longtable}%[[^%]]*%]{@{})(.*)(@{}}))") - - if not coldef then return nil end - - if coldef:match('^[lrc]+$') then - -- old style - new_coldef = coldef:gsub('(.)','|%1') .. '|' - else - -- asuming new style - new_coldef = coldef:gsub('(>)','|%1') .. '|' - end - returned_list = List:new{pandoc.RawBlock('tex', - begdef .. new_coldef .. enddef .. - latex_code:sub(envdef:len() + 1))} - end - return returned_list -end - -function Meta(meta) - -- We have to add this since Pandoc doesn't do it when a filter is - -- processing tables (is it a bug or a feature ???) - - includes = [[%begin tables-vrules.lua - \usepackage{longtable,booktabs,array} - \usepackage{calc} % for calculating minipage widths - % Correct order of tables after \paragraph or \subparagraph - \usepackage{etoolbox} - \makeatletter - \patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} - \makeatother - % Allow footnotes in longtable head/foot - \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} - \makesavenoteenv{longtable} - \setlength{\aboverulesep}{0pt} - \setlength{\belowrulesep}{0pt} - \renewcommand{\arraystretch}{1.3} -%end tables-vrules.lua]] - - if meta['header-includes'] then - table.insert(meta['header-includes'], pandoc.RawBlock('tex', includes)) - else - meta['header-includes'] = List:new{pandoc.RawBlock('tex', includes)} - end - - return meta -end From 1aeeb1231848f13823637bf0b62be15e8af0286e Mon Sep 17 00:00:00 2001 From: chrisaga Date: Sun, 30 Jan 2022 10:14:23 +0100 Subject: [PATCH 16/16] Correct comment about fixing latex preamble --- tables-vrules/tables-rules.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tables-vrules/tables-rules.lua b/tables-vrules/tables-rules.lua index 4ff6ce1f..627c17ce 100644 --- a/tables-vrules/tables-rules.lua +++ b/tables-vrules/tables-rules.lua @@ -61,7 +61,7 @@ function Table(table) latex_code = latex_code:sub(envdef:len() + 1) end end - + -- Add \midrules after each row if needed if vars.hrules then latex_code = latex_code:gsub('(\\\\\n)([\\%w]+)', repl_midrules) @@ -80,8 +80,8 @@ function Table(table) end function Meta(meta) - -- We have to add this since Pandoc doesn't do it when a filter is - -- processing tables (is it a bug or a feature ???) + -- We have to add this since Pandoc doesn't because there are no + -- table anymore in the AST. We converted them in RawBlocks if not vars.vrules and not vars.hrules then return nil end includes = [[