Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tables vrules : adds vertical rules to tables (latex/pdf output) #216

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
af727e8
A lua filter enabling multiple columns in Latex, PDF, and HTML documents
chrisaga Oct 23, 2021
5296ecd
Forgot to update expected.* files before previous commit
chrisaga Oct 24, 2021
9d650d4
Don't use a standalone (pandoc -s) document for expected.tex since
chrisaga Oct 24, 2021
2cc9018
Allow 'signifiant' class names to be in random position in the list
chrisaga Oct 24, 2021
c887e85
add color (html and latex) and background-color (html) processing plus
chrisaga Nov 11, 2021
f4e7a64
background-color processing for latex output
chrisaga Nov 11, 2021
9918551
update test files to match changes in the filter
chrisaga Nov 12, 2021
f9167f8
Merge branch 'pandoc:master' into master
chrisaga Nov 24, 2021
cfc9479
Add color in sample.md and expected.* files
chrisaga Jan 16, 2022
f3ede85
Remove beamer support and arbitrary latex environment
chrisaga Jan 16, 2022
cf96742
Merge branch 'master' of github.com:chrisaga/lua-filters
chrisaga Jan 16, 2022
3371914
Update column-div/column-div.lua (tipo in comment)
chrisaga Jan 17, 2022
47ea5cd
Merge branch 'pandoc:master' into master
chrisaga Jan 22, 2022
1abec29
Create files
chrisaga Jan 22, 2022
e6976fc
First working filter with test file for the 4 kinds of tables supported
chrisaga Jan 22, 2022
816295e
Fix the gap between horizontal and vertical rules
chrisaga Jan 22, 2022
8a2fbca
Code cleaning
chrisaga Jan 22, 2022
fb6c1e9
Manage both horizontal and vertical rules without hacking longtable
chrisaga Jan 29, 2022
1aeeb12
Correct comment about fixing latex preamble
chrisaga Jan 30, 2022
61bcc01
Merge branch 'pandoc:master' into tables-vrules
chrisaga May 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions column-div/Makefile
Original file line number Diff line number Diff line change
@@ -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 --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 --lua-filter column-div.lua --output $@ $<
149 changes: 149 additions & 0 deletions column-div/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
title: "Column Div - leverage Pandoc native divs to make columns
and 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
<[email protected]>
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.

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
-----

### 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 HTML styling and/or
Latex.

#### Multiple even 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.

#### 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
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

For HTML outputs, you already can create divs with whatever class names you
like and style them with `style=" … "` attributes. This is
processed by Pandoc and has nothing to do with this filter.

This filter allows to do the same in Latex (and PDF).
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
-----

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 even column via the `column-count` attribute.

Contributing
------------

PRs welcome.

155 changes: 155 additions & 0 deletions column-div/column-div.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
--[[
column-div - leverage Pandoc native divs to make balanced and unbalanced column
and other things based on class name and attributes.

Copyright: © 2021 Christophe Agathon <[email protected]>
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 .<somename> 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.

Bugs: * html rendering throws a warning [WARNING] Ignoring duplicate attribute style="width:60%;".
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'

function Div(div)
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 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 format is latex then do minipage and others (like multicol)
if FORMAT:match 'latex' then
-- build the returned list of blocks
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
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
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}')}

-- add support for color
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

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
-- 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
if div.classes:includes('multicols') then
env = 'multicols'
-- 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.
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)}
end_env = List:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')}
returned_list = begin_env .. div.content .. end_env
end

-- 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
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
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)}
--returned_list = List:new{pandoc.Div(div.content)}
end
end
return returned_list
end
Loading