├── tests
├── .gitignore
├── data
│ ├── svgbob.bob
│ ├── table.csv
│ ├── bit.yaml
│ ├── json.json
│ ├── aafigure.txt
│ └── io_plan.csv
├── images
│ ├── dummy.png
│ └── bitfield.svg
├── markdown
│ ├── rest.rst
│ ├── section1.md
│ ├── section2.md
│ ├── config.yaml
│ └── TITLE.md
├── .circleci
│ └── config.yml
└── Makefile
├── scripts
├── Dockerfile
├── wavedrom.sh
└── svgbob.sh
├── lua
├── tex-remove-sout.lua
├── tex-underline.lua
├── default_loader.lua
├── tex-quote.lua
├── hide-frontpage-metadata.lua
├── tex-rowcolors-reset.lua
├── docx-comment.lua
├── metadata-file.yaml
├── docx-custom-span-styles.lua
├── tex-landscape.lua
├── removable-note.lua
├── svgconvert.lua
├── docx-image-styles.lua
├── docx-appendixheadings.lua
├── docx-unnumberedheadings.lua
├── aafigure.lua
├── utils.lua
├── docx-colored-span.lua
├── wavedrom.lua
├── svgbob.lua
├── docx-pagebreak-toc.lua
├── preprocess.lua
├── docx-extract-bullet-lists.lua
├── listingtable.lua
├── table-width-simple.lua
├── docx-apply-cell-styles.lua
├── table-width.lua
├── csv2table-simple.lua
└── csv2table.lua
├── .github
└── workflows
│ └── wheel.yaml
├── LICENSE
├── Makefile
├── pandocker_lua_filters
└── __init__.py
├── .gitignore
├── README.md
└── setup.py
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | Out/
3 | .DS_Store
4 | svg/
5 | pd-images/
6 |
--------------------------------------------------------------------------------
/tests/data/svgbob.bob:
--------------------------------------------------------------------------------
1 | ""
2 | +-----------+
3 | |"svgbob" |
4 | +-----------+
5 | ""
6 |
--------------------------------------------------------------------------------
/tests/images/dummy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pandocker/pandocker-lua-filters/HEAD/tests/images/dummy.png
--------------------------------------------------------------------------------
/tests/data/table.csv:
--------------------------------------------------------------------------------
1 | this,is,a table,"multi\
2 | line\
3 | title"
4 | to,show,an,example
5 | of,table,markdown,"importer\
6 | of\
7 | multiline"
8 |
--------------------------------------------------------------------------------
/scripts/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM joseluisq/rust-linux-darwin-builder
2 |
3 | RUN apt-get update
4 | RUN apt-get -y install gcc-mingw-w64
5 | RUN rustup update
6 |
--------------------------------------------------------------------------------
/tests/markdown/rest.rst:
--------------------------------------------------------------------------------
1 | \newpage
2 |
3 | $$////////////~rest.rst~start~////////////$$
4 |
5 | - list
6 | - list depth-2
7 | - list depth-3
8 | - list depth-4
9 | - list depth-3
10 | - list depth-2
11 | - list depth-3
12 |
13 | $$////////////~rest.rst~end~////////////$$
14 |
15 | \newpage
16 |
--------------------------------------------------------------------------------
/tests/data/bit.yaml:
--------------------------------------------------------------------------------
1 | # list from LSB
2 | # bits: bit width
3 | # attr: information RO/WO/RW etc.
4 | # name: name of bitfield
5 | reg:
6 | - bits: 5
7 | - bits: 1
8 | attr: RW
9 | name: IPO
10 | - bits: 1
11 | attr: RW
12 | name: BRK
13 | - bits: 1
14 | name: CPK
15 | options:
16 | bits: 8
17 | fontfamily: "Source Code Pro"
18 | lanes: 1
19 | fontweight: "bold"
20 |
--------------------------------------------------------------------------------
/scripts/wavedrom.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | mkdir build
4 | cd build
5 | npm i wavedrom-cli nexe
6 | npx nexe --target linux-x64-10.16.0 -i ./node_modules/wavedrom-cli/wavedrom-cli.js -o /root/build/wavedrom-cli
7 | npx nexe --target windows-x64-10.16.0 -i ./node_modules/wavedrom-cli/wavedrom-cli.js -o /root/build/wavedrom-cli.exe
8 | npx nexe --target mac-x64-10.16.0 -i ./node_modules/wavedrom-cli/wavedrom-cli.js -o /root/build/wavedrom-cli.bin
9 |
--------------------------------------------------------------------------------
/tests/markdown/section1.md:
--------------------------------------------------------------------------------
1 | vvv section1.md start vvv
2 |
3 | ### This section is what is included
4 |
5 | - list
6 | - list depth-2
7 | - list depth-3
8 | - list depth-4
9 | - list depth-3
10 | - list depth-2
11 | - list depth-3
12 |
13 | ## #include "section2.md"
14 |
15 | ## #include "not-found.md"
16 |
17 | ## `#include "section2.md"`
18 |
19 | line break in single Para by a\
20 | backslash
21 |
22 | \^\^\^ section1.md end \^\^\^
23 |
--------------------------------------------------------------------------------
/lua/tex-remove-sout.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # tex-remove-sout.lua
3 |
4 | Removes Strikeout when tex output
5 | ]]
6 |
7 | local debug = require("pandocker.utils").debug
8 | local stringify = require("pandoc.utils").stringify
9 |
10 | if FORMAT == "latex" then
11 | function Strikeout(el)
12 | debug("[ lua ] strikeout span '" .. stringify(el.content) .. "' found and removed")
13 | return {}
14 | end
15 | return { { Strikeout = Strikeout } }
16 | end
17 |
--------------------------------------------------------------------------------
/lua/tex-underline.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # tex-underline.lua
3 |
4 | Finds underline class span and convert it to \underline{}
5 | ]]
6 |
7 | --local debug = require("pandocker.utils").debug
8 |
9 | if FORMAT == "latex" then
10 | function Span(el)
11 | if el.classes[1] == "underline" then
12 | table.insert(el.content, 1, pandoc.RawInline("latex", "\\underline{"))
13 | table.insert(el.content, pandoc.RawInline("latex", "}"))
14 | end
15 | return el
16 | end
17 | return { { Span = Span } }
18 | end
19 |
--------------------------------------------------------------------------------
/tests/data/json.json:
--------------------------------------------------------------------------------
1 | {
2 | "reg": [
3 | {
4 | "bits": 5,
5 | "attr": [
6 | "001",
7 | "110"
8 | ]
9 | },
10 | {
11 | "bits": 1,
12 | "attr": "RW",
13 | "name": "IPO"
14 | },
15 | {
16 | "bits": 1,
17 | "attr": "RW",
18 | "name": "BRK"
19 | },
20 | {
21 | "bits": 1,
22 | "name": "CPK"
23 | }
24 | ],
25 | "options": {
26 | "bits": 8,
27 | "fontfamily": "Source Code Pro",
28 | "lanes": 1,
29 | "fontweight": "bold"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/scripts/svgbob.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | sudo apt update
4 | sudo apt -y install gcc-mingw-w64
5 | rustup update
6 |
7 | rustup target add x86_64-unknown-linux-musl
8 | cargo install svgbob_cli --root=build/linux --target=x86_64-unknown-linux-musl
9 | mv build/linux/bin/svgbob_cli build/svgbob
10 |
11 | rustup target add x86_64-pc-windows-gnu
12 | cargo install svgbob_cli --root=build/windows --target=x86_64-pc-windows-gnu
13 | mv build/windows/bin/svgbob_cli.exe build/svgbob.exe
14 |
15 | rustup target add x86_64-apple-darwin
16 | cargo install svgbob_cli --root=build/osx --target=x86_64-apple-darwin
17 | mv build/osx/bin/svgbob_cli build/svgbob.bin
18 |
19 | ls build
20 |
--------------------------------------------------------------------------------
/lua/default_loader.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | HIGHLY INSPIRED FROM https://pandoc.org/lua-filters.html#default-metadata-file
3 | ]]
4 | -- read metadata file (placed same directory as this file) into string
5 | --local debug = require("pandocker.utils").debug
6 |
7 | local pwd, _ = require("pandocker.utils").basename(PANDOC_SCRIPT_FILE)
8 | local metafile = io.open(pwd .. 'metadata-file.yaml', 'r')
9 | local content = metafile:read("*a")
10 | metafile:close()
11 | -- get metadata
12 | local default_meta = pandoc.read(content, "markdown").meta
13 | --[[
14 | for i, v in pairs(default_meta) do
15 | debug(pandoc.utils.stringify(i) .. " = " .. pandoc.utils.stringify(v))
16 | end
17 | ]]
18 | return default_meta
19 |
--------------------------------------------------------------------------------
/lua/tex-quote.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | tex-quote.lua
3 | ]]
4 |
5 | local debug = require("pandocker.utils").debug
6 |
7 | local begin_env = pandoc.Para(pandoc.RawInline("latex", "\\begin{mdframed}[skipabove=3pt,hidealllines=true,leftline=true,linewidth=2pt]"))
8 | local end_env = pandoc.Para(pandoc.RawInline("latex", "\\end{mdframed}"))
9 |
10 | if FORMAT == "latex" then
11 | function BlockQuote(el)
12 | debug("[ lua ] BlockQuote found")
13 | --debug(pandoc.utils.stringify(el))
14 | table.insert(el.content, 1, begin_env)
15 | table.insert(el.content, #el.content + 1, end_env)
16 |
17 | return pandoc.Div(el.content)
18 | end
19 | return { { BlockQuote = BlockQuote } }
20 | end
21 |
--------------------------------------------------------------------------------
/tests/data/aafigure.txt:
--------------------------------------------------------------------------------
1 | A B
2 | AA BB
3 | AA BB
4 |
5 | ---- | ___ ~~~|
6 | | -- ___| | ===
7 | ~~~
8 |
9 | +
10 | | - + | - + | - + / -
11 | / / / / / / / / / / -- |/| / +
12 | | | | + + + - - - / / \ - \|/ |\
13 | + + + +-+-+ | +
14 | | | | + + + - - - \ \ / - /|\ |/
15 | \ \ \ \ \ \ \ \ \ \ -- |\| \ +
16 | | - + | - + | - + \ -
17 | +
18 |
19 | ---> | | | | | |
20 | ---< | | | | | |
21 | ---o ^ V v o O #
22 | ---O
23 | ---#
24 |
--------------------------------------------------------------------------------
/tests/markdown/section2.md:
--------------------------------------------------------------------------------
1 | $$////////////~section2.md~////////////$$
2 |
3 | This section is what is included 2
4 |
5 | Table: table without setting column widths {.class .class2}
6 |
7 | | This | is | |
8 | |:-----|:---|:-----------------------------------------------------------------------:|
9 | | | a | [colored text]{.highlight foreground="5B9ACF" background="darkMagenta"} |
10 |
11 | ::: rmnote :::
12 | Remove this block
13 | :::
14 |
15 | - [Highlighted text 1]{.highlight foreground="ABABAB"}
16 | - [_Highlighted text 2_]{.highlight background="red"}
17 | - [_Highlighted **text 3**_]{.highlight foreground="7F7F7F" background="darkgray"}
19 |
20 | - $$////////////~section2.md~////////////$$
21 |
--------------------------------------------------------------------------------
/.github/workflows/wheel.yaml:
--------------------------------------------------------------------------------
1 | name: Build python wheel package
2 | on: [ push, create ]
3 | jobs:
4 | make-wavedrom:
5 | name: Compile svgbob
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Checkout
9 | uses: actions/checkout@v4
10 | with:
11 | fetch-depth: 0
12 | - name: Install dependencies
13 | run: |
14 | pip3 install wheel setuptools setuptools_scm
15 | - name: Build svgbob image
16 | run: |
17 | docker build scripts/ -t svgbob
18 | - name: Build wheel
19 | run: make wheel
20 | - name: Upload artifact wheel (at a push)
21 | uses: actions/upload-artifact@v4
22 | with:
23 | name: wheel package
24 | path: dist
25 | - name: Upload to pypi (at a tag)
26 | uses: pypa/gh-action-pypi-publish@release/v1
27 | if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
28 | with:
29 | user: ${{ secrets.PYPI_USERNAME }}
30 | password: ${{ secrets.PYPI_PASSWORD }}
31 |
--------------------------------------------------------------------------------
/lua/hide-frontpage-metadata.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # hide-frontpage-metadata.lua
3 |
4 | hides certain metadata when LaTeX or Docx output
5 |
6 | ]]
7 |
8 | -- local pretty = require("pl.pretty")
9 |
10 | local stringify = require("pandoc.utils").stringify
11 |
12 | local debug = require("pandocker.utils").debug
13 |
14 | local MESSAGE = "[ lua ] metadata '%s' has found and removed"
15 |
16 | if FORMAT == "latex" or FORMAT == "docx" or FORMAT == "native" then
17 | local function get_vars (mt)
18 | local meta = {
19 | author = "author-meta",
20 | date = "date-meta",
21 | subtitle = "subtitle-meta",
22 | title = "title-meta",
23 | }
24 |
25 | for k, v in pairs(meta) do
26 | --debug(k .. ": " .. v)
27 | if mt[k] ~= nil then
28 | mt[v] = stringify(mt[k])
29 | --debug(stringify(mt[k]))
30 | mt[k] = nil
31 | debug(string.format(MESSAGE, k))
32 | end
33 | end
34 | --pretty.dump(mt)
35 | return mt
36 | end
37 | return { { Meta = get_vars } }
38 | end
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 pandocker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: html
2 |
3 | initdir:
4 | cd tests; \
5 | make initdir
6 |
7 | html:
8 | cd tests; \
9 | make html
10 |
11 | install:
12 | pip3 install --break-system-packages -U .
13 |
14 | uninstall:
15 | pip3 uninstall --break-system-packages -y pandocker-lua-filters
16 |
17 | reinstall: uninstall install
18 | # pip3 install .
19 |
20 | clean:
21 | rm -rf dist
22 | touch pandocker_lua_filters/version.py
23 | rm pandocker_lua_filters/version.py
24 | cd tests; \
25 | make clean
26 |
27 | tex:
28 | cd tests; \
29 | make tex
30 |
31 | docx:
32 | cd tests; \
33 | make docx
34 |
35 | pdf:
36 | cd tests; \
37 | make pdf
38 |
39 | native:
40 | cd tests; \
41 | make native
42 |
43 | #wavedrom:
44 | # @echo "wavedrom"
45 | # docker run --rm -v $(PWD):/root -w /tmp node:10 /root/scripts/wavedrom.sh
46 |
47 | build/svgbob: svgbob
48 | build/svgbob.bin: svgbob
49 | build/svgbob.exe: svgbob
50 | svgbob:
51 | @echo "svgbob"
52 | docker run --rm -v $(PWD):/tmp -w /tmp svgbob ./scripts/svgbob.sh
53 |
54 | wheel: build/svgbob build/svgbob.bin build/svgbob.exe
55 | sudo python3 setup.py bdist_wheel
56 |
57 | check: wheel
58 | twine check dist/pandocker_lua_filters*.whl
59 |
--------------------------------------------------------------------------------
/lua/tex-rowcolors-reset.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # tex-rowcolors-reset.lua
3 |
4 | Finds table and inserts tex command to reset row rule
5 | ]]
6 |
7 | local stringify = require("pandoc.utils").stringify
8 |
9 | local debug = require("pandocker.utils").debug
10 | local default_meta = require("pandocker.default_loader")["tex-rowcolors"]
11 | assert(default_meta)
12 |
13 | local METADATA_NOT_FOUND = "[ lua ] metadata '%s' was not found in source, applying default."
14 |
15 | local meta = {}
16 | local reset_colors = {}
17 |
18 | local function dump(tt, mm)
19 | for ii, vv in ipairs(tt) do
20 | print(mm .. ii .. " " .. tostring(vv["tag"]) .. "(" .. stringify(vv) .. ")")
21 | end
22 | end
23 |
24 | if FORMAT == "latex" then
25 | local function get_vars (mt)
26 | meta = mt["tex-rowcolors"]
27 | if meta == nil then
28 | meta = default_meta
29 | debug(string.format(METADATA_NOT_FOUND, "tex-rowcolors", ""))
30 | end
31 | reset_colors = pandoc.RawBlock("latex", stringify(meta))
32 | end
33 |
34 | local function reset_table_color(el)
35 | return { reset_colors, el }
36 | end
37 |
38 | return { { Meta = get_vars }, { Table = reset_table_color } }
39 | end
40 |
--------------------------------------------------------------------------------
/lua/docx-comment.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Generated by EmmyLua(https://github.com/EmmyLua)
3 | Created by yamamoto.
4 | DateTime: 2020/10/04 16:54
5 |
6 | # docx-comment.lua
7 |
8 | Convert a span with `comment` attribute
9 |
10 | [Comment point to]{comment="Comment string"}
11 |
12 | to Docx comment
13 |
14 | [Comment string]{.comment-start}Comment point to[]{.comment-end}
15 |
16 | ]]
17 |
18 | --local stringify = require("pandoc.utils").stringify
19 | local List = require("pandoc").List
20 |
21 | local debug = require("pandocker.utils").debug
22 | local KEY = "comment"
23 |
24 | if FORMAT == "docx" or FORMAT == "native" then
25 | local function replace(el)
26 | if not List({ nil, "" }):includes(el.attributes[KEY]) then
27 | -- 'comment' attribute value is not blank nor nil
28 | local comment_string = el.attributes[KEY]
29 | debug(comment_string)
30 | local comment_start = pandoc.Span({ pandoc.Str(comment_string) }, { "", { "comment-start" }, {} })
31 | local comment_end = pandoc.Span(pandoc.Null, { "", { "comment-end" }, {} })
32 | el.attributes[KEY] = nil
33 | return pandoc.Span({ comment_start, el, comment_end })
34 | end
35 | end
36 | end
37 |
38 | return { { Span = replace } }
39 |
--------------------------------------------------------------------------------
/tests/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: k4zuki/pandocker:lua-filter
6 | steps:
7 | - checkout
8 | - run:
9 | name: get submodule
10 | command: git submodule update --init
11 | - run:
12 | name: Prepare QR code for this build
13 | command: |
14 | make initdir
15 | pip3 install qrcode
16 | # qr https://github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/releases/download/build-`date +%b-%d-%Y`-`git rev-parse --short HEAD`/Pandocker-Docs-`git rev-parse --short HEAD`.pdf > images/QRcode.png
17 | - run:
18 | name: Make HTML
19 | command: make initdir html
20 | - run:
21 | name: Make PDF
22 | command: make initdir pdf
23 |
24 | - run:
25 | name: Deploy preparation
26 | command: |
27 | mkdir deploy
28 | mv tests/Out/*.html deploy/`basename tests/Out/*.html .html`-`git rev-parse --short HEAD`.html
29 | mv tests/Out/*.pdf deploy/`basename tests/Out/*.pdf .pdf`-`git rev-parse --short HEAD`.pdf
30 | - run:
31 | name: Deploy
32 | command: |
33 | ghr -replace -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME build-`date +%b-%d-%Y`-`git rev-parse --short HEAD` deploy/
34 |
--------------------------------------------------------------------------------
/lua/metadata-file.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rmnote: false
3 |
4 | include: []
5 |
6 | tex-rowcolors: "\\\\rowcolors{3}{white!100!white}{table-gray!100!white!100}"
7 |
8 | lgeometry: "top=20truemm,bottom=20truemm,left=20truemm,right=20truemm"
9 |
10 | heading-unnumbered:
11 | 1: "Heading Unnumbered 1"
12 | 2: "Heading Unnumbered 2"
13 | 3: "Heading Unnumbered 3"
14 | 4: "Heading Unnumbered 4"
15 | 5: "Heading Unnumbered 5"
16 |
17 | heading-appendix:
18 | 1: "Appendix Heading 1"
19 | 2: "Appendix Heading 2"
20 | 3: "Appendix Heading 3"
21 | 4: "Appendix Heading 4"
22 | 5: "Appendix Heading 5"
23 |
24 | custom-spans:
25 | red: "WarningTok"
26 | green: "PreprocessorTok"
27 | blue: "AttributeTok"
28 |
29 | bullet-style:
30 | 1: "Bullet List 1"
31 | 2: "Bullet List 2"
32 | 3: "Bullet List 3"
33 |
34 | figure-styles:
35 | anchor: "Graphic Anchor"
36 | caption: "Figure Caption"
37 |
38 | toc-title: "Table of Contents"
39 |
40 | table-cell-styles:
41 | header-default: "Table Head Left"
42 | header-left: "Table Head Left"
43 | header-center: "Table Head Center"
44 | header-right: "Table Head Right"
45 | body-default: "Table Body Left"
46 | body-left: "Table Body Left"
47 | body-center: "Table Body Center"
48 | body-right: "Table Body Right"
49 |
50 | svgbob:
51 | font-family: "Arial"
52 | font-size: 14
53 | scale: 1
54 | stroke-width: 2
55 |
56 | aafigure:
57 |
58 | ...
59 |
--------------------------------------------------------------------------------
/lua/docx-custom-span-styles.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # docx-custom-span-styles.lua
3 |
4 | - Generated by EmmyLua(https://github.com/EmmyLua)
5 | - Created by yamamoto.
6 | - DateTime: 2020/06/29 4:58
7 |
8 | ## Function
9 |
10 | Detects Span in custom class listed in config file and apply custom-styles attribute.
11 |
12 | ]]
13 | --local pretty = require("pl.pretty")
14 |
15 | local debug = require("pandocker.utils").debug
16 | local util_get_meta = require("pandocker.utils").util_get_meta
17 |
18 | local META_KEY = "custom-spans"
19 |
20 | local default_meta = require("pandocker.default_loader")[META_KEY]
21 | assert(default_meta)
22 |
23 | local meta = {}
24 | local APPLY_DEFAULT = "[ lua ] metadata '%s' was not found in source, applying default %s."
25 | local APPLY = "[ lua ] '%s' class Span found and applied '%s' custom character style"
26 |
27 | if FORMAT == "docx" or FORMAT == "native" then
28 | local function get_vars(mt)
29 | meta = util_get_meta(mt, default_meta, META_KEY)
30 | end
31 |
32 | local function replace(el)
33 | for k, v in pairs(meta) do
34 | if el.classes:includes(k) then
35 | local style = pandoc.utils.stringify(v)
36 | --debug(k .. ", " .. style)
37 | el.attributes["custom-style"] = style
38 | debug(string.format(APPLY, k, style))
39 | end
40 | end
41 |
42 | return el
43 | end
44 |
45 | return { { Meta = get_vars }, { Span = replace } }
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/lua/tex-landscape.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # tex-landscape.lua
3 |
4 | Finds `LANDSCAPE` class Div and inserts LaTeX RawBlock-s
5 | which sets contents of Div in landscape geometry.
6 |
7 | ## Syntax
8 |
9 | ```markdown
10 | ::: LANDSCAPE :::
11 | # #include "section1.md"
12 | :::::::::::::::::
13 | ```
14 | ]]
15 |
16 | local stringify = require("pandoc.utils").stringify
17 |
18 | local debug = require("pandocker.utils").debug
19 | local default_meta = require("pandocker.default_loader")["lgeometry"]
20 | assert(default_meta ~= nil)
21 |
22 | local NOT_FOUND = "[ lua ] metadata '%s' was not found in source, applying default %s."
23 | local MESSAGE = "[ lua ] Div in 'LANDSCAPE' class found"
24 |
25 | local meta = {}
26 | local start_landscape = ""
27 | local stop_landscape = pandoc.RawBlock("latex", "\\end{landscape}\\restoregeometry")
28 |
29 | local function dump(tt, mm)
30 | for ii, vv in ipairs(tt) do
31 | print(mm .. ii .. " " .. tostring(vv["tag"]) .. "(" .. stringify(vv) .. ")")
32 | end
33 | end
34 |
35 | local function get_vars (mt)
36 | meta = mt["lgeometry"]
37 | if meta == nil then
38 | meta = default_meta
39 | debug(string.format(NOT_FOUND, "lgeometry", ""))
40 | end
41 | start_landscape = pandoc.RawBlock("latex", "\\newgeometry{" .. stringify(meta) .. "}\\begin{landscape}")
42 | end
43 |
44 | local function landscape(el)
45 | if el.classes:find("LANDSCAPE") then
46 | debug(MESSAGE)
47 | if FORMAT == "latex" then
48 | table.insert(el.content, 1, start_landscape)
49 | table.insert(el.content, stop_landscape)
50 | end
51 | return el.content
52 | end
53 | end
54 |
55 | return { { Meta = get_vars }, { Div = landscape } }
56 |
--------------------------------------------------------------------------------
/pandocker_lua_filters/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """
3 | MIT License
4 |
5 | Copyright (c) 2020 Kazuki Yamamoto
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 | """
25 |
26 | import argparse
27 | import platform
28 | from .version import version
29 |
30 |
31 | def main():
32 | parser = argparse.ArgumentParser(description="")
33 | parser.add_argument('--version', action='version', version=str(version))
34 | args = parser.parse_args()
35 |
36 |
37 | def get_platform():
38 | pf = platform.platform()
39 | if pf.startswith("Windows"):
40 | print("Windows")
41 | elif pf.startswith("Darwin"):
42 | print("OSX")
43 | elif pf.startswith("Linux"):
44 | print("Linux")
45 |
46 |
47 | if __name__ == "__main__":
48 | main()
49 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 | pandocker_lua_filters/version.py
106 | windows/
107 | mac/
108 | linux/
109 | .npm/
110 | .nexe/
111 | .config/
112 |
--------------------------------------------------------------------------------
/lua/removable-note.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # removable-note.lua
3 |
4 | Finds "rmnote" class Div and removes if metadata "rmnote" is set `true`
5 |
6 | ## Syntax
7 |
8 | ```markdown
9 | ::: rmnote :::::::::::
10 | - All the contents
11 | - inside this div
12 |
13 | is removed when flag is set `true`.
14 | ::::::::::::::::::::::
15 | ```
16 | ]]
17 |
18 | local stringify = require("pandoc.utils").stringify
19 |
20 | local debug = require("pandocker.utils").debug
21 | local default_meta = require("pandocker.default_loader")["rmnote"]
22 | assert(default_meta ~= nil)
23 |
24 | local meta = {}
25 | local METADATA_NOT_FOUND = "[ lua ] metadata '%s' was not found in source, applying default %s."
26 |
27 | local function dump(tt, mm)
28 | for ii, vv in ipairs(tt) do
29 | print(mm .. ii .. " " .. tostring(vv["tag"]) .. "(" .. stringify(vv) .. ")")
30 | end
31 | end
32 |
33 | local function get_vars (mt)
34 | if tostring(PANDOC_VERSION) == "2.15" then
35 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
36 | return
37 | end
38 | meta = mt["rmnote"]
39 | if meta == nil then
40 | meta = default_meta
41 | debug(string.format(METADATA_NOT_FOUND, "rmnote", stringify(default_meta)))
42 | end
43 | meta = stringify(meta)
44 | --debug(tostring(meta == "true"))
45 | end
46 |
47 | local function remove(doc)
48 | for i, el in ipairs(doc.blocks) do
49 | --print(i .. " " .. el.tag .. "(" .. stringify(el) .. ")")
50 | if el.tag == "Div" and el.classes:find("rmnote") then
51 | if meta == "true" then
52 | --debug("remove")
53 | debug("[ lua ] Div in 'rmnote' class found and removed")
54 | table.remove(doc.blocks, i)
55 | end
56 | end
57 | end
58 | --dump(doc.blocks, " ")
59 | return doc
60 | end
61 | if tostring(PANDOC_VERSION) ~= "2.15" then
62 | return { { Meta = get_vars }, { Pandoc = remove } }
63 | else
64 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
65 | return
66 | end
67 |
68 |
--------------------------------------------------------------------------------
/tests/markdown/config.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: 本のタイトル
3 | subtitle: 本の概要
4 | circle: サークル名
5 | author: 本の作者
6 | comiket: コミケ
7 | year: 出版年
8 | publisher: 印刷会社で印刷製本
9 | docrevision: "1.0"
10 | # front: images/front-image.png
11 | verbcolored: false
12 | # rmnote: false
13 | #toc-title: "Table of Contents"
14 |
15 | svgbob:
16 | font-family: "Source Code Pro"
17 | font-size: 14
18 | scale: 1
19 | stroke-width: 2
20 |
21 | heading-unnumbered:
22 | 1: "Heading Unnumbered 1"
23 | 2: "Heading Unnumbered 2"
24 | 3: "Heading Unnumbered 3"
25 | 4: "Heading Unnumbered 4"
26 | 5: "Heading Unnumbered 4"
27 |
28 | heading-appendix:
29 | 1: "Appendix Heading 1"
30 | 2: "Appendix Heading 2"
31 | 3: "Appendix Heading 3"
32 | 4: "Appendix Heading 4"
33 | 5: "Appendix Heading 5"
34 |
35 | bullet-style:
36 | 1: "Bullet List 1"
37 | 2: "Bullet List 2"
38 | 3: "Bullet List 3"
39 |
40 | numbered-bullets:
41 | 1: "Number Bullet"
42 | 2: "Number Bullet 2"
43 | 3: "Number Bullet 3"
44 |
45 | custom-spans:
46 | red: "WarningTok"
47 | green: "PreprocessorTok"
48 | blue: "AttributeTok"
49 |
50 | image-div-style: "Image Caption"
51 |
52 | docx_coreprop:
53 | # author: "K4ZUKI" # str
54 | # category: "Category" # str
55 | # comments: "Comment" # str
56 | # keywords: "Keyword1 Keyword2" # str
57 | # last_modified_by: "K4ZUKI" # str
58 | # last_printed: "31-Dec-2018" # datetime DD-MMM-YYYY
59 | # modified: "31-Dec-2018" # datetime DD-MMM-YYYY
60 | # revision: 1123 # int < 32768
61 | # subject: "SubjecT" # str
62 | # title: "Title" # str
63 |
64 | # created: "31-Dec-2018" # datetime DD-MMM-YYYY set externally
65 | # content_status: "Status" # ignored?
66 | # identifier: "ID" # ignored?
67 | # language: "Japanese" # ignored?
68 | # version: "Version" # ignored?
69 |
70 | table-alignment-in-page: center # left / center /right
71 | table-cell-vertical-alignment: center # top / center / bottom / both
72 | read-only-recommended: true
73 | disable-table-autofit: false # setting 'true' requires explicit column widths setting
74 | table:
75 | # "Normal Table": "Centered"
76 | paragraph:
77 | "Image Caption": "Figure Caption"
78 | # "Normal": "Body Text"
79 | # "First Paragraph": "Body Text"
80 | character:
81 | ...
82 |
--------------------------------------------------------------------------------
/lua/svgconvert.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # svgconvert.lua
3 |
4 |
5 | # Note
6 | | Image (alt, src[, title[, attr] ])
7 | | {.class-1 .class-2 attr=alpha attr=beta #fig:figure}
8 | | | | | k v k v | |
9 | | | classes | | attributes | | identifier
10 | | | (preserve) | | (preserve) | | (preserve)
11 | ]]
12 |
13 | PANDOC_VERSION:must_be_at_least '2.8'
14 |
15 | local stringify = require("pandoc.utils").stringify
16 | local get_current_directory = require("pandoc.system").get_working_directory
17 |
18 | local debug = require("pandocker.utils").debug
19 | local file_exists = require("pandocker.utils").file_exists
20 |
21 | local MESSAGE = "[ lua ] convert a svg file to svg/%s.%s"
22 | local BYPASS = "[ lua ] Skipping conversion as target 'svg/%s.%s' exists"
23 | local ERROR_MESSAGE = "[ lua ] %s: file not found"
24 |
25 | local get_ext = {
26 | ["html"] = "svg",
27 | ["html5"] = "svg",
28 | ["latex"] = "pdf",
29 | ["docx"] = "png",
30 | }
31 |
32 | function convert_from_svg(el)
33 | --for k, v in pairs(el) do
34 | -- print(stringify(k), stringify(v))
35 | --end
36 | local ext = get_ext[FORMAT] or "png"
37 | local source_file = stringify(el.src)
38 | --debug(source_file)
39 | local source_base, source_ext = source_file:match('(.*)%.(.*)')
40 | if ext ~= "svg" and source_ext == "svg" then
41 | if file_exists(source_file) then
42 | local _, basename = require("pandocker.utils").basename(source_base)
43 | local abspath = get_current_directory()
44 | local fullpath = string.format("%s/svg/%s.%s", abspath, basename, ext)
45 | if not file_exists(fullpath) then
46 | pandoc.pipe("rsvg-convert", { source_file, "-f", ext, "-o", fullpath }, "")
47 | debug(string.format(MESSAGE, basename, ext))
48 | else
49 | debug(string.format(BYPASS, basename, ext))
50 | end
51 | el.src = fullpath
52 | --debug(abspath, path, source_file, basename, ext, fullpath)
53 | return el
54 | else
55 | debug(string.format(ERROR_MESSAGE, source_file))
56 | end
57 | end
58 | end
59 |
60 | return { { Image = convert_from_svg } }
61 |
--------------------------------------------------------------------------------
/tests/images/bitfield.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lua/docx-image-styles.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # docx-image-styles.lua
3 |
4 | applies different styles image and its caption
5 | when image link does not have caption
6 | ]]
7 |
8 | --local pretty = require("pl.pretty")
9 | --require("pl.stringx").import()
10 |
11 | local stringify = require("pandoc.utils").stringify
12 | local debug = require("pandocker.utils").debug
13 | --local file_exists = require("pandocker.utils").file_exists
14 |
15 | local MESSAGE = "[ lua ] Para having one Image element found"
16 | local NOT_FOUND = "[ lua ] metadata '%s' was not found in source, applying default %s."
17 |
18 | local default_meta = require("pandocker.default_loader")["figure-styles"]
19 |
20 | if FORMAT == "docx" or FORMAT == "native" then
21 | local function get_vars (mt)
22 | meta = mt["figure-styles"]
23 | if meta ~= nil then
24 | for k, v in pairs(default_meta) do
25 | if meta[k] == nil then
26 | meta[k] = v
27 | local d = pandoc.utils.stringify(mt["figure-styles"][k])
28 | debug(string.format(NOT_FOUND, "figure-styles." .. k, d))
29 | end
30 | end
31 | else
32 | meta = default_meta
33 | debug(string.format(NOT_FOUND, "figure-styles", ""))
34 | --debug("metadata 'heading-unnumbered' was not found in source, applying defaults.")
35 | end
36 | end
37 |
38 | local function para(elem)
39 | if #elem.content == 1 and elem.content[1].tag == "Image" then
40 | debug(MESSAGE)
41 | image = elem.content[1]
42 | --debug(stringify(image.src))
43 | local caption_div = pandoc.Div({})
44 | local image_div = pandoc.Div({})
45 | caption_div["attr"]["attributes"]["custom-style"] = stringify(meta["caption"])
46 | image_div["attr"]["attributes"]["custom-style"] = stringify(meta["anchor"])
47 |
48 | if stringify(image.caption) ~= "" then
49 | caption_div.content = { pandoc.Para(image.caption) }
50 | image.caption = {}
51 | image.title = ""
52 | end
53 | image_div.content = { pandoc.Para(image) }
54 |
55 | if PANDOC_VERSION < (3) then
56 | return { image_div, caption_div }
57 | else
58 | return { image_div }--, caption_div
59 | end
60 | end
61 | end
62 |
63 | if PANDOC_VERSION < (3) then
64 | return { { Meta = get_vars }, { Para = para } }
65 | else
66 | return { { Meta = get_vars }, { Plain = para } }
67 | end
68 | end
69 |
--------------------------------------------------------------------------------
/lua/docx-appendixheadings.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # AppendixHeadings
3 |
4 | ## Function
5 |
6 | Applies level 1~5 headers in 'appendix' class to use dedicated headers
7 |
8 | * Works with docx output only
9 | * Level 6 and lower level headers are remain untouched
10 | * "Appendix Heading x" must be prepared in template or inherits default style
11 |
12 | | Level | Numbered | Appendix |
13 | |-------------------------------------------|
14 | | 1 | Heading 1 | Appendix Heading 1 |
15 | | 2 | Heading 2 | Appendix Heading 2 |
16 | | 3 | Heading 3 | Appendix Heading 3 |
17 | | 4 | Heading 4 | Appendix Heading 4 |
18 | | 5 | Heading 5 | Appendix Heading 5 |
19 | | 6+ | Heading 6 | |
20 | ]]
21 |
22 | local debug = require("pandocker.utils").debug
23 |
24 | local META_KEY = "heading-appendix"
25 | local CLASS_KEY = "appendix"
26 |
27 | local default_meta = require("pandocker.default_loader")[META_KEY]
28 | assert(default_meta)
29 |
30 | local meta = {}
31 | local APPLY_DEFAULT = "[ lua ] metadata '%s' was not found in source, applying default %s."
32 | local TOO_DEEP_LEVEL = "[ lua ] unnumbered heading greater than level %d is found and ignored"
33 | local MAX_HEADING_LEVEL = 5
34 |
35 | if FORMAT == "docx" or FORMAT == "native" then
36 | local function get_vars (mt)
37 | meta = mt[META_KEY]
38 | if meta ~= nil then
39 | for k, v in pairs(default_meta) do
40 | if meta[k] == nil then
41 | meta[k] = v
42 | local d = pandoc.utils.stringify(mt[META_KEY][k])
43 | debug(string.format(APPLY_DEFAULT, META_KEY .. "." .. k, d))
44 | end
45 | end
46 | else
47 | meta = default_meta
48 | debug(string.format(APPLY_DEFAULT, META_KEY, ""))
49 | --debug("metadata 'heading-unnumbered' was not found in source, applying defaults.")
50 | end
51 | end
52 |
53 | local function replace(el)
54 | if el.classes:includes(CLASS_KEY) then
55 | if el.level <= MAX_HEADING_LEVEL then
56 | local style = pandoc.utils.stringify(meta[tostring(el.level)])
57 | el.attributes["custom-style"] = style
58 | local content = pandoc.Para(el.content)
59 | local attr = pandoc.Attr(el.identifier, el.classes, el.attributes)
60 |
61 | --debug(pandoc.utils.stringify(content))
62 | --debug(pandoc.utils.stringify(div))
63 | return pandoc.Div(content, attr)
64 | else
65 | debug(string.format(TOO_DEEP_LEVEL, MAX_HEADING_LEVEL))
66 | end
67 | end
68 | --debug(el.level .. tostring(el.classes[1]))
69 | end
70 |
71 | return { { Meta = get_vars }, { Header = replace } }
72 | end
73 |
--------------------------------------------------------------------------------
/lua/docx-unnumberedheadings.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # UnnumberedHeadings
3 |
4 | ## Function
5 |
6 | Converts level 1~5 headers in 'unnumbered' class to unnumbered headers
7 |
8 | * Works with docx output only
9 | * Level 6 and lower level headers are remain untouched
10 | * "Heading Unnumbered x" must be prepared in template or inherits default style
11 |
12 | | Level | Numbered | Unnumbered |
13 | |-------------------------------------------|
14 | | 1 | Heading 1 | Heading Unnumbered 1 |
15 | | 2 | Heading 2 | Heading Unnumbered 2 |
16 | | 3 | Heading 3 | Heading Unnumbered 3 |
17 | | 4 | Heading 4 | Heading Unnumbered 4 |
18 | | 5 | Heading 5 | Heading Unnumbered 5 |
19 | | 6+ | Heading 6 | |
20 | ]]
21 |
22 | local debug = require("pandocker.utils").debug
23 |
24 | local META_KEY = "heading-unnumbered"
25 | local CLASS_KEY = "unnumbered"
26 |
27 | local default_meta = require("pandocker.default_loader")[META_KEY]
28 | assert(default_meta)
29 |
30 | local meta = {}
31 | local APPLY_DEFAULT = "[ lua ] metadata '%s' was not found in source, applying default %s."
32 | local TOO_DEEP_LEVEL = "[ lua ] unnumbered heading greater than level %d is found and ignored"
33 | local MAX_HEADING_LEVEL = 5
34 |
35 | if FORMAT == "docx" or FORMAT == "native" then
36 | local function get_vars (mt)
37 | meta = mt[META_KEY]
38 | if meta ~= nil then
39 | for k, v in pairs(default_meta) do
40 | if meta[k] == nil then
41 | meta[k] = v
42 | local d = pandoc.utils.stringify(mt[META_KEY][k])
43 | debug(string.format(APPLY_DEFAULT, META_KEY .. "." .. k, d))
44 | end
45 | end
46 | else
47 | meta = default_meta
48 | debug(string.format(APPLY_DEFAULT, META_KEY, ""))
49 | --debug("metadata 'heading-unnumbered' was not found in source, applying defaults.")
50 | end
51 | end
52 |
53 | local function replace(el)
54 | if el.classes:includes(CLASS_KEY) then
55 | if el.level <= MAX_HEADING_LEVEL then
56 | local style = pandoc.utils.stringify(meta[tostring(el.level)])
57 | el.attributes["custom-style"] = style
58 | local content = pandoc.Para(el.content)
59 | local attr = pandoc.Attr(el.identifier, el.classes, el.attributes)
60 |
61 | --debug(pandoc.utils.stringify(content))
62 | --debug(pandoc.utils.stringify(div))
63 | return pandoc.Div(content, attr)
64 | else
65 | debug(string.format(TOO_DEEP_LEVEL, MAX_HEADING_LEVEL))
66 | end
67 | end
68 | --debug(el.level .. tostring(el.classes[1]))
69 | end
70 |
71 | return { { Meta = get_vars }, { Header = replace } }
72 | end
73 |
--------------------------------------------------------------------------------
/tests/data/io_plan.csv:
--------------------------------------------------------------------------------
1 | POSITION;FUNCTION;PORT
2 | CLK tile[0, 0] clk_side=E Input0;LOGIC_AS_CLK0;i_lac0
3 | CLK tile[0, 0] clk_side=W Input0;OSC_CLK;i_clk
4 | IOB tile[0, 0] coord[ 0, 6] Output0;[PIN 13] GPIO0_OUT;o_row[1]
5 | IOB tile[0, 0] coord[ 0, 6] Output1;[PIN 13] GPIO0_OE;o_row_oe[1]
6 | IOB tile[0, 0] coord[ 0, 7] Output0;[PIN 14] GPIO1_OUT;o_row[3]
7 | IOB tile[0, 0] coord[ 0, 7] Output1;[PIN 14] GPIO1_OE;o_row_oe[3]
8 | IOB tile[0, 0] coord[ 0, 8] Output0;[PIN 15] GPIO2_OUT;o_row[5]
9 | IOB tile[0, 0] coord[ 0, 8] Output1;[PIN 15] GPIO2_OE;o_row_oe[5]
10 | IOB tile[0, 0] coord[ 0, 9] Output0;[PIN 16] GPIO3_OUT;o_row[7]
11 | IOB tile[0, 0] coord[ 0, 9] Output1;[PIN 16] GPIO3_OE;o_row_oe[7]
12 | IOB tile[0, 0] coord[ 0, 10] Output0;[PIN 17] GPIO4_OUT;o_row[0]
13 | IOB tile[0, 0] coord[ 0, 10] Output1;[PIN 17] GPIO4_OE;o_row_oe[0]
14 | IOB tile[0, 0] coord[ 0, 22] Output0;[PIN 18] GPIO5_OUT;o_row[2]
15 | IOB tile[0, 0] coord[ 0, 22] Output1;[PIN 18] GPIO5_OE;o_row_oe[2]
16 | IOB tile[0, 0] coord[ 0, 23] Output0;[PIN 19] GPIO6_OUT;o_row[4]
17 | IOB tile[0, 0] coord[ 0, 23] Output1;[PIN 19] GPIO6_OE;o_row_oe[4]
18 | IOB tile[0, 0] coord[ 0, 24] Output0;[PIN 20] GPIO7_OUT;o_row[6]
19 | IOB tile[0, 0] coord[ 0, 24] Output1;[PIN 20] GPIO7_OE;o_row_oe[6]
20 | IOB tile[0, 0] coord[ 0, 25] Output0;OSC_EN;osc_en
21 | IOB tile[0, 0] coord[31, 4] Output0;[PIN 9] GPIO18_OUT;testbus[2]
22 | IOB tile[0, 0] coord[31, 4] Output1;[PIN 9] GPIO18_OE;testbus_oe[2]
23 | IOB tile[0, 0] coord[31, 5] Output0;[PIN 8] GPIO17_OUT;testbus[1]
24 | IOB tile[0, 0] coord[31, 5] Output1;[PIN 8] GPIO17_OE;testbus_oe[1]
25 | IOB tile[0, 0] coord[31, 6] Output0;[PIN 7] GPIO16_OUT;testbus[0]
26 | IOB tile[0, 0] coord[31, 6] Output1;[PIN 7] GPIO16_OE;testbus_oe[0]
27 | IOB tile[0, 0] coord[31, 8] Output0;[PIN 6] GPIO15_OUT;o_col[1]
28 | IOB tile[0, 0] coord[31, 8] Output1;[PIN 6] GPIO15_OE;o_col_oe[1]
29 | IOB tile[0, 0] coord[31, 9] Output0;[PIN 5] GPIO14_OUT;o_col[3]
30 | IOB tile[0, 0] coord[31, 9] Output1;[PIN 5] GPIO14_OE;o_col_oe[3]
31 | IOB tile[0, 0] coord[31, 10] Input0;[PIN 11] nRST;i_nreset
32 | IOB tile[0, 0] coord[31, 11] Output0;REF_LOGIC_AS_CLK0;scan_clk_out
33 | IOB tile[0, 0] coord[31, 12] Output0;LOGIC_AS_CLK0_EN;scan_clk_oe
34 | IOB tile[0, 0] coord[31, 22] Output0;[PIN 4] GPIO13_OUT;o_col[5]
35 | IOB tile[0, 0] coord[31, 22] Output1;[PIN 4] GPIO13_OE;o_col_oe[5]
36 | IOB tile[0, 0] coord[31, 23] Output0;[PIN 3] GPIO12_OUT;o_col[7]
37 | IOB tile[0, 0] coord[31, 23] Output1;[PIN 3] GPIO12_OE;o_col_oe[7]
38 | IOB tile[0, 0] coord[31, 24] Output0;[PIN 2] GPIO11_OUT;o_col[0]
39 | IOB tile[0, 0] coord[31, 24] Output1;[PIN 2] GPIO11_OE;o_col_oe[0]
40 | IOB tile[0, 0] coord[31, 25] Output0;[PIN 1] GPIO10_OUT;o_col[2]
41 | IOB tile[0, 0] coord[31, 25] Output1;[PIN 1] GPIO10_OE;o_col_oe[2]
42 | IOB tile[0, 0] coord[31, 26] Output0;[PIN 24] GPIO9_OUT;o_col[4]
43 | IOB tile[0, 0] coord[31, 26] Output1;[PIN 24] GPIO9_OE;o_col_oe[4]
44 | IOB tile[0, 0] coord[31, 27] Output0;[PIN 23] GPIO8_OUT;o_col[6]
45 | IOB tile[0, 0] coord[31, 27] Output1;[PIN 23] GPIO8_OE;o_col_oe[6]
46 |
--------------------------------------------------------------------------------
/lua/aafigure.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # aafigure.lua
3 | ]]
4 | PANDOC_VERSION:must_be_at_least '2.8'
5 |
6 | local abs_pwd = require("pandoc.system").get_working_directory()
7 | local stringify = require("pandoc.utils").stringify
8 |
9 | --local pretty = require("pl.pretty")
10 |
11 | local debug = require("pandocker.utils").debug
12 | local file_exists = require("pandocker.utils").file_exists
13 |
14 | local util_get_meta = require("pandocker.utils").util_get_meta
15 | local platform = require("pandocker.utils").get_os()
16 | local base = require("pandocker.utils").package_base_path()
17 |
18 | local META_KEY = "aafigure"
19 | local meta = {}
20 |
21 | local default_meta = require("pandocker.default_loader")[META_KEY]
22 | assert(default_meta)
23 |
24 | local MESSAGE = "[ lua ] convert aafigure to svg/%s.svg"
25 | local BYPASS = "[ lua ] Skipping conversion as target 'svg/%s.svg' exists"
26 | local NOT_FOUND = "[ lua ] %s: file not found"
27 | local AAFIGURE = "%s/bin/%s"
28 |
29 | local function get_meta(mt)
30 | meta = util_get_meta(mt, default_meta, META_KEY)
31 | --debug(stringify(meta))
32 | end
33 |
34 | function Link(el)
35 | if el.classes:includes(META_KEY) then
36 | if tostring(PANDOC_VERSION) == "2.15" then
37 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
38 | return
39 | end
40 | --debug("Link in 'wavedrom' class")
41 | if stringify(el.content) == "" then
42 | el.content = el.target
43 | end
44 | local idn = el.identifier
45 |
46 | -- remove classes
47 | local classes = {}
48 | for i, v in ipairs(el.classes) do
49 | if v ~= META_KEY then
50 | table.insert(classes, v)
51 | end
52 | end
53 |
54 | -- main block
55 | local source_file = stringify(el.target)
56 | local source_ext = source_file:match('.*%.(.*)')
57 | if file_exists(source_file) then
58 | -- reads file contents as string anyway; assuming input a JSON file
59 |
60 | local attr = pandoc.Attr(idn, classes, el.attributes)
61 | local content = io.open(source_file, "rb"):read("a")
62 | local hash = pandoc.utils.sha1(content)
63 | local fullpath = string.format("%s/svg/%s.svg", abs_pwd, hash)
64 |
65 | if not file_exists(fullpath) then
66 | local aafigure = META_KEY
67 | pandoc.pipe(aafigure, { source_file, "-o", fullpath }, "")
68 | debug(string.format(MESSAGE, hash))
69 | else
70 | debug(string.format(BYPASS, hash))
71 | end
72 | local img = pandoc.Image(el.content, fullpath, "fig:", attr)
73 | --pretty.dump(img)
74 | return img
75 | else
76 | debug(string.format(NOT_FOUND, source_file))
77 | end
78 | end
79 | end
80 |
81 | if tostring(PANDOC_VERSION) ~= "2.15" then
82 | --debug(tostring(tostring(PANDOC_VERSION) == "2.15"))
83 | return { { Meta = get_meta }, { Link = Link } }
84 | else
85 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
86 | return
87 | end
88 |
--------------------------------------------------------------------------------
/tests/Makefile:
--------------------------------------------------------------------------------
1 | ifeq ($(OS),Windows_NT)
2 | HOME = C:/Users/$(USERNAME)
3 | endif
4 | PIPBASE= $(shell get-pip-base)
5 | PANSTYLES= $(PIPBASE)/var
6 | MISC= $(PANSTYLES)/pandoc_misc
7 | MISC_SYS = $(MISC)/system
8 | MISC_USER = $(MISC)/user
9 | include $(MISC_SYS)/Makefile.in
10 | PROJECT= `pwd`
11 |
12 | ## userland: uncomment and replace
13 | # MDDIR:= markdown
14 | # DATADIR:= data
15 | # TARGETDIR:= Out
16 | # IMAGEDIR:= images
17 |
18 | # CONFIG:= config.yaml
19 | # INPUT:= TITLE.md
20 | # TARGET:= TARGET-$(DATE)-$(HASH)
21 | # REVERSE_INPUT:= reverse-input.docx
22 | #REFERENCE := $(DATADIR)/ref.docx
23 | #SYSTEM_DOCXFRONTPAGE := $(MDDIR)/frontpage.md
24 | # COREPROPFLAGS := --table "Normal Table=Centered"
25 | # COREPROPFLAGS += --paragraph "Normal=Body Text"
26 | ##
27 | LUA_FILTER_BASE = ../lua
28 | PANFLAGS := --read=markdown+east_asian_line_breaks
29 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/hide-frontpage-metadata.lua
30 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/preprocess.lua
31 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/tex-landscape.lua
32 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-unnumberedheadings.lua
33 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-appendixheadings.lua
34 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-pagebreak-toc.lua
35 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/csv2table.lua
36 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/csv2table-simple.lua
37 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/listingtable.lua
38 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/aafigure.lua
39 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/wavedrom.lua
40 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/tex-quote.lua
41 | #PANFLAGS += --filter=pantable
42 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/table-width.lua
43 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/table-width-simple.lua
44 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-apply-cell-styles.lua
45 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-colored-span.lua
46 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-custom-span-styles.lua
47 | #PANFLAGS += --filter=pandocker-blockdiag-filters
48 | #PANFLAGS += --filter=pandoc-svgbob-filter
49 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/svgbob.lua
50 | PANFLAGS += --filter=pandoc-imagine
51 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/svgconvert.lua
52 | #PANFLAGS += --filter=pandocker-filters
53 | #PANFLAGS += --filter=pandoc-docx-extract-bullet-list
54 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-extract-bullet-lists.lua
55 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/removable-note.lua
56 | PANFLAGS += --filter=pandoc-crossref
57 | PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/docx-image-styles.lua
58 | #PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/tex-rowcolors-reset.lua
59 | #PANFLAGS += --lua-filter=$(LUA_FILTER_BASE)/tex-remove-sout.lua
60 | PANFLAGS += --listings
61 | PANFLAGS += --top-level-division=chapter
62 | PANFLAGS += --number-sections --highlight-style=kate
63 | PANFLAGS += -M short-hash=$(HASH)
64 | PANFLAGS += -M tables=true
65 | PANFLAGS += -M envversion=$(ENV_VERSION)
66 | #PFLAGS += $(PANFLAGS)
67 | #PANFLAGS = $(PFLAGS)
68 |
69 | include $(MISC_SYS)/Makefile
70 |
71 | native: $(TARGETDIR)/$(TARGET)-native.txt
72 | $(TARGETDIR)/$(TARGET)-native.txt: $(MDDIR)/$(INPUT)
73 | $(PANDOC) $(PANFLAGS) -M linkReferences=true \
74 | $(MDDIR)/$(INPUT) -t native -o $(TARGETDIR)/$(TARGET)-native.txt
75 |
--------------------------------------------------------------------------------
/lua/utils.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # utils.lua
3 |
4 | Utility functions
5 | ]]
6 |
7 | local tablex = require("pl.tablex")
8 |
9 | local function debug(string)
10 | io.stderr:write(string .. "\n")
11 | end
12 |
13 | local function basename(path)
14 | --[[
15 | INSPIRED FROM https://stackoverflow.com/a/17387077/6592473?stw=2
16 | split `path` into pwd and file
17 |
18 | | path | pwd | file |
19 | |---------------------------------------------------|
20 | | /path | / | path |
21 | | /path/to/file | /path/to/ | file |
22 | | /path/to/file/ | /path/to/file/ | nil |
23 | | /path/to/file.txt | /path/to/ | file.txt |
24 | ]]
25 |
26 | return path:match('(.*/)(.*)')
27 | end
28 |
29 | -- Return true if file exists and is readable.
30 | -- from http://lua-users.org/wiki/FileInputOutput
31 | local function file_exists(path)
32 | local file = io.open(path, "rb")
33 | if file then
34 | file:close()
35 | end
36 | return file ~= nil
37 | end
38 |
39 | local function get_tf(item, default)
40 | if type(item) == "string" then
41 | item = string.upper(item)
42 | if tablex.search({ "TRUE", "YES" }, item) then
43 | return true
44 | else
45 | return false
46 | end
47 | else
48 | return default
49 | end
50 | end
51 |
52 | -- requires global definition of `default_meta` and `meta_key`
53 | local function get_meta(doc_meta, default_meta, meta_key)
54 | local NOT_FOUND = "[ lua ] metadata '%s' was not found in source, applying default %s."
55 |
56 | meta = doc_meta[meta_key]
57 | if meta ~= nil then
58 | for k, v in pairs(default_meta) do
59 | if meta[k] == nil then
60 | meta[k] = v
61 | local d = pandoc.utils.stringify(doc_meta[meta_key][k])
62 | debug(string.format(NOT_FOUND, meta_key .. "." .. k, d))
63 | end
64 | end
65 | else
66 | meta = default_meta
67 | debug(string.format(NOT_FOUND, meta_key, ""))
68 | end
69 | --pretty.dump(meta)
70 | return meta
71 | end
72 |
73 | --
74 | --[[ What operating system?
75 | Lua has only a small library of built in functions - often
76 | you have to pull in a library from another source, or write
77 | your own.
78 |
79 | Here is the start of a piece of code to identify operating
80 | system information (such as which OS you're running on.
81 | ]]
82 |
83 | local function getos()
84 |
85 | -- Unix, Linux varients
86 | fh, err = io.popen("uname -o 2>/dev/null", "r")
87 | if fh then
88 | osname = fh:read()
89 | end
90 | if osname then
91 | return osname
92 | end
93 |
94 | -- Add code for other operating systems here
95 | return "unknown"
96 | end
97 |
98 | local function package_base_path()
99 | local PACKAGE_BASE_PATH = "pip3 show pandocker-lua-filters | grep Location | cut -c11- | rev | cut -d/ -f4- | rev"
100 | local fh, err = io.popen(PACKAGE_BASE_PATH, "r")
101 | local base = ""
102 | if fh then
103 | base = fh:read()
104 | else
105 | base = "/"
106 | end
107 | return base
108 | end
109 |
110 | return {
111 | basename = basename,
112 | debug = debug,
113 | file_exists = file_exists,
114 | get_os = getos,
115 | get_tf = get_tf,
116 | util_get_meta = get_meta,
117 | package_base_path = package_base_path,
118 | }
119 |
--------------------------------------------------------------------------------
/tests/markdown/TITLE.md:
--------------------------------------------------------------------------------
1 | \toc
2 |
3 | \newpage
4 |
5 | text
text
6 | text
7 |
8 | ::: {.table }
9 |
10 | | text
text | |
11 | |--------------|----|
12 | | | |
13 | | | |
14 |
15 | :::
16 |
17 | :::{.table width=[0.5,0.3]}
18 | Table: table **width** {#tbl:table}
19 |
20 | | Table | Header | Row |
21 | |:------|:------:|-----:|
22 | | Cell | Cell | Cell |
23 |
24 | :::
25 |
26 | [@fig:wavedrom-2]
27 |
28 | ::: {#fig:tiled-figures width=[0.5,0.5]}
29 | ::: {.table noheader=true}
30 |
31 | | [Wavedrom(BitField)](data/json.json){.wavedrom width=70mm #fig:wavedrom-1} | [AAFigure](data/aafigure.txt){.aafigure width=70mm #fig:wavedrom-2} |
32 | |:--------------------------------------------------------------------------:|:--------------------------------------------------------------------------:|
33 | | [svgbob](data/svgbob.bob){.svgbob width=70mm #fig:wavedrom-3} | [Wavedrom(BitField)](data/json.json){.wavedrom width=70mm #fig:wavedrom-4} |
34 |
35 | :::
36 |
37 | Tiled figures
on a table
38 |
39 | :::
40 |
41 | # #include "rest.rst"
42 |
43 | [CSV file with caption](data/table.csv){.table}
44 |
45 | [Alignment = DLCR](data/table.csv){.table alignment=DLCR width=[0.5]}
46 |
47 | [Subset table](data/table.csv){.table subset_from=(1,2)}
48 |
49 | [Set widths](data/table.csv){.table width=[0.2,0.3,0.2,0.3]}
50 |
51 | [CSV file with caption2](data/io_plan.csv){.table delimiter=";"}
52 |
53 | ##### Auto caption
54 |
55 | [](data/table.csv){.table width=[0.5]}
56 |
57 | ##### No caption
58 |
59 | [](data/table.csv){.table nocaption=true}
60 |
61 | [@tbl:table]
62 |
63 | ## Level2
64 |
65 | # Level1 unnumbered {-}
66 |
67 | # Level1 {.subsection-toc}
68 |
69 | ## Level2 unnumbered {-}
70 |
71 | ##### Level5 unnumbered {-}
72 |
73 |
74 |
75 | ::::::{custom-style="Heading Unnumbered 3"}
76 | Level3 *unnumbered*
77 | ::::::
78 |
79 | :::::{custom-style="Bullet List 1"}
80 | Bullet List 1
81 |
82 | :::{custom-style="Bullet List 2"}
83 | Bullet List 2
84 | :::
85 | :::::
86 |
87 | [red?]{.red}
88 | [green?]{.green}
89 | [blue?]{.blue}
90 | [foo?]{.default-paragraph-font}
91 |
92 | [[@lst:lst]]{.underline}
93 |
94 | > Lorem ipsum dolor sit amet, にほんご
95 | >
96 | > > consectetur adipiscing elit, sed do eiusmod
97 | >
98 | > tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
99 | > quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
100 | > Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
101 | > dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
102 | > sunt in culpa qui officia deserunt mollit anim id est laborum.
103 |
104 | [bit.yaml](data/bit.yaml){.bitfield}
105 |
106 | #### Level4 unnumbered {-}
107 |
108 |
109 |
110 | [Title](markdown/config.yaml){.listingtable from=2 to=5 #lst:lst}
111 |
112 | [Wavedrom(BitField)](data/tutorial_0.json){.wavedrom #fig:wavedrom}
113 |
114 | \newpage
115 |
116 | [](markdown/config.yaml){.listingtable type=yaml from=2 to=10 nocaption=true}
117 |
118 | ::: LANDSCAPE
119 |
120 | [](data/ditaa.puml){.listingtable type=puml #lst:ditaa-sample}
121 |
122 | [](data/ditaa.puml){.listingtable nocaption=true
123 | .plantuml #fig:ditaa-sample im_out="img" im_fmt='png' caption="PlantUML x ditaa x imagine"}
124 |
125 | :::
126 |
127 | [This failes to list](markdown/config.yaml){.listingtable numbers=right type=yaml from=2 to=5 #lst:list}
128 |
129 | 
130 |
131 | ::: LANDSCAPE :::
132 |
133 | ##### Level5
134 |
135 | # #include "section2.md"
136 |
137 | :::
138 |
139 | ~~Strikeout~~ ~~ごはんはおかず~~
140 |
--------------------------------------------------------------------------------
/lua/docx-colored-span.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # docx-colored-span.lua
3 |
4 | Highlights a span in specified foreground and background colors.
5 | Foreground is specified by RRGGBB style hex value; Background is chosen from color name list.
6 | It won't change text content regardless of colors.
7 |
8 | ## Syntax
9 |
10 |
11 | [Highlighted text 1]{.highlight foreground="ABABAB"}
12 |
13 |
14 | [Highlighted text 2]{.highlight background="lightgray"}
15 |
16 |
17 | [Highlighted text 3]{.highlight foreground="ABABAB" background="darkgray"}
18 |
19 | ]]
20 |
21 | local List = require("pandoc").List
22 | local stringify = require("pandoc.utils").stringify
23 |
24 | local debug = require("pandocker.utils").debug
25 | local MESSAGE = "[ lua ] Colored span found"
26 | local KEY = "highlight"
27 |
28 | local COLORHEAD = pandoc.RawInline("openxml", "")
29 | local COLORMID = pandoc.RawInline("openxml", "")
30 | local COLORFOOT = pandoc.RawInline("openxml", "")
31 | local FG_KEY = "foreground"
32 | local FG_TAG = ""
33 | local FG_MESSAGE = "[ lua ] `- Foreground color - 0x%s"
34 | local BG_KEY = "background"
35 | local BG_TAG = ""
36 | local BG_MESSAGE = "[ lua ] `- Background color - %s"
37 |
38 | local BG_TABLE = List({
39 | default = 'default',
40 | black = 'black',
41 | blue = 'blue',
42 | cyan = 'cyan',
43 | green = 'green',
44 | magenta = 'magenta',
45 | red = 'red',
46 | white = 'white',
47 | yellow = 'yellow',
48 |
49 | lightgray = 'lightgray',
50 |
51 | darkblue = 'darkBlue',
52 | darkcyan = 'darkCyan',
53 | darkgray = 'darkGray',
54 | darkgreen = 'darkGreen',
55 | darkmagenta = 'darkMagenta',
56 | darkred = 'darkRed',
57 | darkyellow = 'darkYellow',
58 | })
59 |
60 | --[[
61 | ``{=openxml}
62 | **Span**
63 | ``{=openxml}
64 | ]]
65 |
66 | if FORMAT == "docx" or FORMAT == "native" then
67 | local function replace(el)
68 | if el.classes:includes(KEY) then
69 | local foreground = pandoc.Span({})
70 | local background = pandoc.Span({})
71 | local fg_name = ""
72 | local bg_name = "default"
73 |
74 | debug(MESSAGE)
75 |
76 | if el.attributes[FG_KEY] ~= nil then
77 | -- 'foreground' attribute value is not blank nor nil
78 | fg_name = el.attributes[FG_KEY]
79 | if string.match(fg_name, "^[0-9a-fA-F].....$") ~= nil then
80 | debug(string.format(FG_MESSAGE, fg_name))
81 | foreground = pandoc.RawInline("openxml", string.format(FG_TAG, fg_name))
82 | end
83 | el.attributes[FG_KEY] = nil
84 | end
85 |
86 | if el.attributes[BG_KEY] ~= nil then
87 | -- 'background' attribute value is not blank nor nil
88 | bg_name = el.attributes[BG_KEY]
89 | if BG_TABLE[string.lower(bg_name)] ~= nil then
90 | debug(string.format(BG_MESSAGE, BG_TABLE[bg_name]))
91 | background = pandoc.RawInline("openxml", string.format(BG_TAG, BG_TABLE[bg_name]))
92 | else
93 | debug(string.format("[ Lua ] `- Background color %s is not found", bg_name))
94 | end
95 | el.attributes[BG_KEY] = nil
96 | end
97 |
98 | return pandoc.Span({ COLORHEAD, foreground, background, COLORMID, el, COLORFOOT })
99 | end
100 | end
101 | return { { Span = replace } }
102 | end
103 |
--------------------------------------------------------------------------------
/lua/wavedrom.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # wavedrom.lua
3 |
4 | # Note
5 | | Link (content, target[, title[, attr] ])
6 | | [content](target){.class-1 .class-2 attr=alpha attr=beta #lst:list}
7 | | | | | k v k v | |
8 | | | classes | | attributes | identifier
9 | | .listingtable type=plain numbers=left from=5 to=10
10 | |
11 | | Image (alt, src[, title[, attr] ])
12 | | {.class-1 .class-2 attr=alpha attr=beta #fig:figure}
13 | | | | | k v k v | |
14 | | | classes | | attributes | | identifier
15 | | | (preserve) | | (preserve) | | (preserve)
16 |
17 | ]]
18 | PANDOC_VERSION:must_be_at_least '2.8'
19 |
20 | local yaml = require("lyaml")
21 | local json = require("cjson")
22 |
23 | local abs_pwd = require("pandoc.system").get_working_directory()
24 | local stringify = require("pandoc.utils").stringify
25 |
26 | --local pretty = require("pl.pretty")
27 |
28 | local debug = require("pandocker.utils").debug
29 | local file_exists = require("pandocker.utils").file_exists
30 |
31 | local INVALID_FILETYPE = "[ lua ] %s: invalid file format for wavedrom. must be JSON" -- or YAML
32 | local MESSAGE = "[ lua ] convert wavedrom to svg/%s.svg"
33 | local BYPASS = "[ lua ] Skipping conversion as target 'svg/%s.svg' exists"
34 | local NOT_FOUND = "[ lua ] %s: file not found"
35 |
36 | function Link(el)
37 | if el.classes:includes "wavedrom" or el.classes:includes "bitfield" then
38 | if tostring(PANDOC_VERSION) == "2.15" then
39 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
40 | return
41 | end
42 | --debug("Link in 'wavedrom' class")
43 | if stringify(el.content) == "" then
44 | el.content = el.target
45 | end
46 | local idn = el.identifier
47 |
48 | -- remove "wavedrom" and "bitfield" classes
49 | local classes = {}
50 | for i, v in ipairs(el.classes) do
51 | if v ~= "wavedrom" and v ~= "bitfield" then
52 | table.insert(classes, v)
53 | end
54 | end
55 |
56 | -- main block
57 | local source_file = stringify(el.target)
58 | local source_ext = source_file:match('.*%.(.*)')
59 | if file_exists(source_file) then
60 | -- reads file contents as string anyway; assuming input a JSON file
61 | local data = io.open(source_file, "r"):read("*a")
62 | if source_ext == "yaml" then
63 | -- if extension is YAML: convert to JSON string
64 | data = json.encode(yaml.load(data))
65 | --debug(json.encode(yaml.load(data)))
66 | elseif source_ext ~= "json" then
67 | -- prints error message if extension is not YAML nor JSON
68 | debug(string.format(INVALID_FILETYPE, source_file))
69 | return
70 | end
71 |
72 | local attr = pandoc.Attr(idn, classes, el.attributes)
73 | local content = io.open(source_file, "rb"):read("a")
74 | local hash = pandoc.utils.sha1(content)
75 | local fullpath = string.format("%s/svg/%s.svg", abs_pwd, hash)
76 |
77 | -- pipes JSON string to wavedrom-cli; equivalent to `echo | wavedrom-cli -i - -s `
78 | if not file_exists(fullpath) then
79 | pandoc.pipe("wavedrom-cli", { "-i", "-", "-s", fullpath }, data)
80 | debug(string.format(MESSAGE, hash))
81 | else
82 | debug(string.format(BYPASS, hash))
83 | end
84 | local img = pandoc.Image(el.content, fullpath, "fig:", attr)
85 | --pretty.dump(img)
86 | return img
87 | else
88 | debug(string.format(NOT_FOUND, source_file))
89 | end
90 | end
91 | end
92 |
--------------------------------------------------------------------------------
/lua/svgbob.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # svgbob.lua
3 | ]]
4 | PANDOC_VERSION:must_be_at_least '2.8'
5 |
6 | local abs_pwd = require("pandoc.system").get_working_directory()
7 | local stringify = require("pandoc.utils").stringify
8 |
9 | --local pretty = require("pl.pretty")
10 |
11 | local debug = require("pandocker.utils").debug
12 | local file_exists = require("pandocker.utils").file_exists
13 |
14 | local util_get_meta = require("pandocker.utils").util_get_meta
15 | local platform = require("pandocker.utils").get_os()
16 | local base = require("pandocker.utils").package_base_path()
17 |
18 | local META_KEY = "svgbob"
19 | local meta = {}
20 |
21 | local default_meta = require("pandocker.default_loader")[META_KEY]
22 | assert(default_meta)
23 |
24 | local MESSAGE = "[ lua ] convert svgbob to svg/%s.svg"
25 | local BYPASS = "[ lua ] Skipping conversion as target 'svg/%s.svg' exists"
26 | local NOT_FOUND = "[ lua ] %s: file not found"
27 | local SVGBOB = "%s/bin/%s"
28 |
29 | local function get_meta(mt)
30 | meta = util_get_meta(mt, default_meta, META_KEY)
31 | --debug(stringify(meta))
32 | end
33 |
34 | function Link(el)
35 | if el.classes:includes(META_KEY) then
36 | if tostring(PANDOC_VERSION) == "2.15" then
37 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
38 | return
39 | end
40 | --debug("Link in " .. META_KEY .. " class")
41 | if stringify(el.content) == "" then
42 | el.content = el.target
43 | end
44 | local idn = el.identifier
45 |
46 | -- remove svgbob classe
47 | local classes = {}
48 | for i, v in ipairs(el.classes) do
49 | if v ~= "svgbob" then
50 | table.insert(classes, v)
51 | end
52 | end
53 |
54 | -- main block
55 | local source_file = stringify(el.target)
56 | local source_ext = source_file:match('.*%.(.*)')
57 | if file_exists(source_file) then
58 | -- reads file contents as string anyway; assuming input a JSON file
59 |
60 | local attr = pandoc.Attr(idn, classes, el.attributes)
61 | local content = io.open(source_file, "rb"):read("a")
62 | local hash = pandoc.utils.sha1(content)
63 | local fullpath = string.format("%s/svg/%s.svg", abs_pwd, hash)
64 |
65 | if not file_exists(fullpath) then
66 | local font_family = '"' .. stringify(meta["font-family"]) .. '"'
67 | local font_size = stringify(meta["font-size"])
68 | local scale = stringify(meta["scale"])
69 | local stroke_width = stringify(meta["stroke-width"])
70 | local svgbob = "svgbob"
71 | if string.find(platform, "Linux") then
72 | svgbob = string.format(SVGBOB, base, "pandocker/svgbob")
73 | elseif string.find(platform, "Darwin") then
74 | svgbob = string.format(SVGBOB, base, "pandocker/svgbob.bin")
75 | else
76 | svgbob = string.format(SVGBOB, base, "pandocker/svgbob.exe")
77 | end
78 | pandoc.pipe(svgbob, { source_file,
79 | "--font-family", font_family,
80 | "--font-size", font_size,
81 | "--scale", scale,
82 | "--stroke-width", stroke_width,
83 | "-o", fullpath }, "")
84 | debug(string.format(MESSAGE, hash))
85 | else
86 | debug(string.format(BYPASS, hash))
87 | end
88 | local img = pandoc.Image(el.content, fullpath, "fig:", attr)
89 | --pretty.dump(img)
90 | return img
91 | else
92 | debug(string.format(NOT_FOUND, source_file))
93 | end
94 | end
95 | end
96 |
97 | return { { Meta = get_meta }, { Link = Link } }
98 |
--------------------------------------------------------------------------------
/lua/docx-pagebreak-toc.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # docx-pagebreak-toc.lua
3 |
4 | Finds commands to insert TOC, sub section TOC, line break or a page break
5 | Only works for `docx` format
6 | TOC title is set to "Table of Contents" by default. Metadata `toc-title` overrides this setting.
7 |
8 | ## Syntax
9 |
10 | ```markdown
11 |
12 | \toc
13 |
14 |
15 | \newpage
16 |
17 |
18 |
19 |
20 |
21 | # Level1 header {.subsection-toc}
22 |
23 | ```
24 | ]]
25 |
26 | --local stringify = require("pandoc.utils").stringify
27 | --local pretty = require("pl.pretty")
28 |
29 | local debug = require("pandocker.utils").debug
30 | local strip = require("pl.stringx").strip
31 |
32 | local RAW_TOC_TEMPLATE = [[
33 |
34 |
35 |
36 |
37 |
38 | %s
39 |
40 |
41 |
42 |
43 |
44 |
45 | ]]
46 | local RAW_PAGEBREAK = ""
47 | local NOT_FOUND = "[ lua ] metadata '%s' was not found in source, applying default %s."
48 |
49 | local meta_key = "toc-title"
50 | local default_meta = require("pandocker.default_loader")[meta_key]
51 |
52 | local function get_vars (mt)
53 | meta = mt[meta_key]
54 | if meta ~= nil and meta.tag == "MetaInlines" then
55 | meta = { table.unpack(meta) }
56 | else
57 | meta = { table.unpack(default_meta) }
58 | debug(string.format(NOT_FOUND, meta_key, "")
59 | )
60 | end
61 | end
62 |
63 | local function toc(el)
64 | if el.text == "\\toc" then
65 | if FORMAT == "docx" or FORMAT == "native" then
66 | debug("[ lua ] insert Table of Contents")
67 | el.text = string.format(RAW_TOC_TEMPLATE, [[TOC \o "1-3" \h \z \u]])
68 | el.format = "openxml"
69 | local para = pandoc.Para(meta)
70 | local div = pandoc.Div({ para, el })
71 | div["attr"]["attributes"]["custom-style"] = "TOC Heading"
72 | return div
73 | else
74 | --debug("\\toc, not docx")
75 | return {}
76 | end
77 | elseif el.text == "\\newpage" then
78 | if FORMAT == "docx" or FORMAT == "native" then
79 | debug("[ lua ] insert a Pagebreak")
80 | el.text = RAW_PAGEBREAK
81 | el.format = "openxml"
82 | return el
83 | elseif FORMAT ~= "latex" then
84 | --debug("\\newpage, not docx nor latex")
85 | return {}
86 | end
87 | end
88 | --elseif FORMAT == "latex" then
89 | end
90 |
91 | local function linebreak(el)
92 |
93 | local text = strip(el.text)
94 | --debug('"' .. el.text .. '", "' .. text .. '"')
95 | if text == "
" then
96 | if FORMAT == "docx" or FORMAT == "native" then
97 | debug("[ lua ] insert a LineBreak")
98 | el = pandoc.LineBreak()
99 | return el
100 | end
101 | end
102 | end
103 |
104 | local function subsection_toc(el)
105 | if FORMAT == "docx" or FORMAT == "native" then
106 | if el.level == 1 then
107 | if el.classes:find("subsection-toc") then
108 | local id = el.identifier
109 | debug("[ lua ] insert subsection TOC for #" .. id)
110 | local subsectoc = string.format(RAW_TOC_TEMPLATE, [[TOC \o "2-2" \h \b ”]] .. id .. [[” \u]])
111 | return { el, pandoc.RawBlock("openxml", subsectoc) }
112 | end
113 | end
114 | end
115 |
116 | end
117 |
118 | return { { Meta = get_vars }, { RawBlock = toc }, { RawInline = linebreak }, { Header = subsection_toc } }
119 |
--------------------------------------------------------------------------------
/lua/preprocess.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # preprocess.lua
3 |
4 | Finds heading starting with `#include` and "filename"
5 | and tries to include contents of filename into AST tree
6 |
7 | - Metadata "include" is used as search path list
8 | - Does not apply to contents of a Div
9 | - search paths are inherited from option parameter for pandoc
10 |
11 | ## Syntax
12 |
13 | ```markdown
14 | # #include "section1.md"
15 |
19 | ```
20 | ]]
21 |
22 | local stringify = require("pandoc.utils").stringify
23 |
24 | local debug = require("pandocker.utils").debug
25 | local file_exists = require("pandocker.utils").file_exists
26 | --local default_meta = require("pandocker.default_loader")["include"]
27 | --assert(default_meta ~= nil)
28 |
29 | --local search_paths = {}
30 | --local META_NOT_FOUND = "metadata '%s' was not found in source, applying default %s."
31 | local FILE_NOT_FOUND = "[ lua ] %s: file not found in search paths"
32 | local INCLUDED = "[ lua ] include and merge source file %s"
33 |
34 | local function dump(tt, mm)
35 | if mm == nil then
36 | mm = ""
37 | end
38 | for ii, vv in ipairs(tt) do
39 | print(mm, ii .. " " .. tostring(vv["tag"]) .. "(" .. stringify(vv) .. ")")
40 | end
41 | end
42 |
43 | --[[
44 | local function store_meta (mt)
45 | search_paths = mt["include"]
46 | if search_paths == nil then
47 | search_paths = default_meta
48 | debug(string.format(META_NOT_FOUND, "include", "./"))
49 | end
50 | table.insert(search_paths, "")
51 | end
52 | ]]
53 |
54 | local function replace(el)
55 | local rep = el.content
56 | local sub
57 | local data
58 | if #rep == 3 then
59 | if tostring(PANDOC_VERSION) == "2.15" then
60 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
61 | return
62 | end
63 | --dump(rep)
64 | if rep[1] == pandoc.Str("#include") and rep[2].tag == "Space" and rep[3].tag == "Quoted" then
65 | for _, v in ipairs(PANDOC_STATE.resource_path) do
66 | local included = "./" .. stringify(v) .. "/" .. stringify(rep[3].content)
67 | if file_exists(included) then
68 | debug(string.format(INCLUDED, included))
69 | data = io.open(included, "r"):read("*a")
70 | sub = pandoc.read(data)
71 | --dump(sub.blocks)
72 | return sub
73 | end
74 | end
75 | debug(string.format(FILE_NOT_FOUND, stringify(rep[3].content)))
76 | --print(stringify(rep[3].content))
77 | end
78 | end
79 | end
80 |
81 | local function preprocess(doc)
82 | local sub = {}
83 | local head = {}
84 | local tail = {}
85 | for i, el in ipairs(doc.blocks) do
86 | --print(i .. " " .. el.tag .. "(" .. stringify(el) .. ")")
87 | if el.tag == "Header" then
88 | sub = replace(el)
89 | --print(tostring(sub))
90 | if sub ~= nil then
91 | --sub = preprocess(sub)
92 | --print(#sub.blocks)
93 | --print("\n--- counter reset?")
94 | table.move(doc.blocks, 1, i - 1, 1, head) -- head has contents before #include
95 | --dump(head, "hh")
96 | table.move(doc.blocks, i + 1, #doc.blocks, 1, tail) -- tail has after #include
97 | --dump(sub.blocks, "ss")
98 | --dump(tail, "tt")
99 | table.move(sub.blocks, 1, #sub.blocks, #head + 1, head) -- concat head and sub.blocks -> head
100 | table.move(tail, 1, #tail, #head + 1, head) -- concat head and tail
101 | --dump(head, " ")
102 | doc.blocks = head
103 | return preprocess(doc)
104 | end
105 | end
106 | end
107 | return doc
108 | end
109 |
110 | return { { Pandoc = preprocess } }
111 |
--------------------------------------------------------------------------------
/lua/docx-extract-bullet-lists.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # docx-extract-bullet-lists.lua
3 |
4 | Finds and converts all bullet lists into Divs in certain styles
5 | Level-4 and deeper level items are promoted to level-3
6 |
7 | ## Syntax
8 | ```markdown
9 | # Inputs
10 |
11 | - Level1
12 | - Level2
13 | - Level3
14 | - Level4
15 |
16 |
17 | # Equivalent outputs
18 |
19 | :::{custom-style="Bullet List 1"}
20 | Level1
21 | :::
22 |
23 | :::{custom-style="Bullet List 2"}
24 | Level2
25 | :::
26 |
27 | :::{custom-style="Bullet List 3"}
28 | Level3
29 | :::
30 |
31 | :::{custom-style="Bullet List 3"}
32 | Level4
33 | :::
34 | ```
35 | ]]
36 |
37 | local stringify = require("pandoc.utils").stringify
38 |
39 | --local pretty = require("pl.pretty")
40 |
41 | local debug = require("pandocker.utils").debug
42 | local util_get_meta = require("pandocker.utils").util_get_meta
43 |
44 | local META_KEY = "bullet-style"
45 | local meta = {}
46 | local MAX_DEPTH = 3
47 | local TOO_DEEP = "[ lua ] Listed item found at too deep level. Promote to level-%d."
48 |
49 | local default_meta = require("pandocker.default_loader")[META_KEY]
50 | assert(default_meta)
51 |
52 | if FORMAT == "docx" or FORMAT == "native" then
53 |
54 | local function get_meta(mt)
55 | meta = util_get_meta(mt, default_meta, META_KEY)
56 | --debug(stringify(meta))
57 | end
58 |
59 | local function get_style(depth)
60 | local style = ""
61 | if depth > MAX_DEPTH then
62 | style = meta[tostring(MAX_DEPTH)]
63 | debug(string.format(TOO_DEEP, MAX_DEPTH))
64 | --debug(stringify(meta[tostring(max_depth)]))
65 | else
66 | style = meta[tostring(depth)]
67 | --debug(stringify(meta[tostring(depth)]))
68 | end
69 | return style
70 | end
71 |
72 | local function combine_para_plain(paras, depth)
73 | local _content = {}
74 | for idx, para in ipairs(paras) do
75 | table.insert(_content, para.content)
76 | if idx ~= #paras then
77 | table.insert(_content, {})
78 | end
79 | end
80 |
81 | bullet = pandoc.Div({ pandoc.LineBlock(_content) })
82 | bullet["attr"]["attributes"]["custom-style"] = stringify(get_style(depth))
83 | table.insert(bl, bullet)
84 | end
85 |
86 | local function extract_bullet_list(el, depth)
87 | local paras = {}
88 | local style = get_style(depth)
89 |
90 | for _, blocks in ipairs(el.content) do
91 | --debug(depth .. ", " .. #v .. ", " .. stringify(v))
92 | for idx, block in ipairs(blocks) do
93 | if block.tag ~= "Para" and block.tag ~= "Plain" then
94 | combine_para_plain(paras, depth)
95 | paras = {}
96 | if block.tag == "BulletList" then
97 | extract_bullet_list(block, depth + 1)
98 | else
99 | bullet = pandoc.Div(block)
100 | bullet["attr"]["attributes"]["custom-style"] = stringify(style)
101 | table.insert(bl, bullet)
102 | end
103 | else
104 | table.insert(paras, block)
105 | if idx == #blocks then
106 | combine_para_plain(paras, depth)
107 | paras = {}
108 | end
109 | --debug(depth .. " " .. e.tag .. " " .. stringify(e))
110 | end
111 | end
112 | end
113 | end
114 |
115 | local function bulletlist_to_divs(doc)
116 | local head = {}
117 | local tail = {}
118 |
119 | for i, el in ipairs(doc.blocks) do
120 | bl = {}
121 | if el.tag == "BulletList" then
122 | debug("[ lua ] Bullet list found")
123 | extract_bullet_list(el, 1)
124 | table.move(doc.blocks, 1, i - 1, 1, head) -- head has contents before BulletList
125 | table.move(doc.blocks, i + 1, #doc.blocks, 1, tail) -- tail has after BulletList
126 | table.move(bl, 1, #bl, #head + 1, head) -- concat head and bl -> head
127 | table.move(tail, 1, #tail, #head + 1, head) -- concat head and tail
128 | doc.blocks = head
129 | return bulletlist_to_divs(doc)
130 | --debug(stringify(bl))
131 | end
132 | end
133 | return doc
134 | end
135 |
136 | return { { Meta = get_meta }, { Pandoc = bulletlist_to_divs } }
137 | end
138 |
--------------------------------------------------------------------------------
/lua/listingtable.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # listingtable.lua
3 |
4 | Finds Link in `listingtable` class and get the file content into a CodeBlock
5 | Guesses included file type and adds to classes
6 | Cuts into subset if corresponding options are set
7 |
8 | ## Syntax
9 |
10 | ```markdown
11 | [Caption](/path/to/file){.listingtable }
12 | ```
13 |
14 | ### Attributes
15 |
16 | - `from`
17 | - `startFrom`
18 | - `to`
19 | - `type`
20 | - `numbers`
21 | - `nocaption`
22 |
23 | ## Note
24 |
25 | | Link (content, target[, title[, attr] ])
26 | | [content](target){.class-1 .class-2 attr=alpha attr=beta #lst:list}
27 | | | | | k v k v | |
28 | | | classes | | attributes | identifier
29 | | .listingtable type=plain numbers=left from=5 to=10
30 | ]]
31 |
32 | local tablex = require("pl.tablex")
33 |
34 | local stringify = require("pandoc.utils").stringify
35 |
36 | local debug = require("pandocker.utils").debug
37 | local get_tf = require("pandocker.utils").get_tf
38 | local new_structure_from = "3.3"
39 |
40 | local function listingtable(el)
41 | --[[
42 | debug(FORMAT)
43 | debug(stringify(el.content))
44 | debug(stringify(el.target))
45 | debug(stringify(el.identifier))
46 | ]]
47 |
48 | if el.classes:includes "listingtable" then
49 | if tostring(PANDOC_VERSION) == "2.15" then
50 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
51 | return
52 | end
53 | if stringify(el.content) == "" then
54 | if PANDOC_VERSION >= new_structure_from then
55 | el.content = { pandoc.Str(stringify(el.target)) }
56 | else
57 | el.content = el.target
58 | end
59 | end
60 | local listing_file = stringify(el.target)
61 | local lines = {}
62 | -- test if file exists
63 | if require("pandocker.utils").file_exists(listing_file) then
64 |
65 | --convert file contents to list of strings
66 | for line in io.lines(listing_file) do
67 | lines[#lines + 1] = line
68 | end
69 | debug(string.format("[ lua ] listing %s", listing_file))
70 | else
71 | debug("Failed to open " .. el.target)
72 | return
73 | end
74 | local caption = pandoc.Str(stringify(el.content))
75 | local file_type = el.attributes["type"] or "plain"
76 | local nocaption = get_tf(el.attributes.nocaption, false)
77 | local linefrom = tonumber(el.attributes["from"]) or 1
78 | if linefrom < 1 then
79 | linefrom = 1
80 | end
81 |
82 | local lineto = tonumber(el.attributes["to"]) or #lines
83 | if tonumber(lineto) > #lines then
84 | lineto = #lines
85 | end
86 | local attributes = {}
87 | for k, v in pairs(el.attributes) do
88 | if not tablex.search({ "type", "from", "to", "nocaption" }, k) then
89 | attributes[k] = v
90 | end
91 | end
92 | attributes["startFrom"] = el.attributes["startFrom"] or linefrom
93 | attributes["numbers"] = el.attributes["numbers"] or "left"
94 |
95 | local data = table.concat(lines, "\n", linefrom, lineto)
96 | --debug(data)
97 | local _, basename = require("pandocker.utils").basename(listing_file)
98 | local idn = el.identifier
99 | if idn == "" then
100 | idn = "lst:" .. string.gsub(basename, "%.", "_")
101 | end
102 | --debug(idn)
103 |
104 | el.classes:extend { file_type, "numberLines" }
105 | local attr = pandoc.Attr(idn, el.classes, attributes)
106 | local raw_code = pandoc.CodeBlock(data, attr)
107 |
108 | --[[
109 | debug(stringify(caption))
110 | debug(file_type)
111 | debug(linefrom)
112 | debug(lineto)
113 | debug(startFrom)
114 | debug(numbers)
115 | ]]
116 |
117 | local para = { raw_code }
118 | if not nocaption then
119 | if PANDOC_VERSION >= new_structure_from then
120 | table.insert(para, 1, pandoc.Para(pandoc.Inlines({ pandoc.Str("Listing:"), pandoc.Space() }):extend(el.content)))
121 | else
122 | table.insert(para, 1, pandoc.Para({ pandoc.Str("Listing:"), pandoc.Space(), caption }))
123 | end
124 | end
125 | --debug(stringify(para))
126 | return para
127 | end
128 | end
129 |
130 | function Para(el)
131 | if #(el.content) == 1 then
132 | el = el.content[1]
133 | if el.tag == "Link" then
134 | --debug("Para content is a Link")
135 | return listingtable(el)
136 | end
137 | end
138 | end
139 |
--------------------------------------------------------------------------------
/lua/table-width-simple.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # table-width.lua
3 |
4 | Applies table attributes to a table inside a Div
5 |
6 | ## Syntax
7 |
8 | :::{.table width=[w1,w2,...] noheader=true|false}
9 |
10 | : Caption {#tbl:table}
11 |
12 | | Header | Row | Table |
13 | |:----------|:-----:|------:|
14 | | Cell | Cell | Cell |
15 |
16 | :::
17 |
18 | where,
19 |
20 | - w1,w2,... : width value for each column. if not fully given padded by
21 | (1 - (sum of given widths)) / (number of unnumbered columns)
22 | e.g. When [0.5] is given for 4-column table, the first column will have 0.5 and the rest will have 0.16667 each
23 | of page width (i.e. (1 - 0.5) / 3)
24 | - noheader: flag if header row exists. `true` to move header row to head of body rows.
25 | Default is `false`. When table has only one blank row, header row overrides body row so that
26 | table has single row without header row.
27 |
28 | try:
29 | $ pandoc -t native -L lua/table-width.lua
30 | :::{.table width=[0.5] noheader=true}
31 | : Test1
32 |
33 | | Header |
34 | |:----------|
35 | | Cell |
36 | :::
37 |
38 | :::{.table width=[0.5] noheader=true}
39 | : Test2
40 |
41 | | Cell | Cell |
42 | |:----------|----------:|
43 | | | |
44 | :::
45 |
46 | :::{.table }
47 | | head | head2 |
48 | |----|----|
49 | |cell|cell|
50 | :::
51 |
52 |
53 | :::{.table }
54 | |head|
55 | |----|
56 | | |
57 | :::
58 | ]]
59 |
60 | --local stringify = require("pandoc.utils").stringify
61 |
62 | local pretty = require("pl.pretty")
63 | local seq = require("pl.seq")
64 | local tablex = require("pl.tablex")
65 | local List = require("pl.List")
66 | require("pl.stringx").import()
67 |
68 | local debug = require("pandocker.utils").debug
69 | local get_tf = require("pandocker.utils").get_tf
70 |
71 | local MESSAGE = "[ lua ] Div in 'table' class found"
72 | local NOHEADER_MESSAGE = "[ lua ] Move header row to body rows"
73 | local WIDTH_MESSAGE = "[ lua ] Adjust column ratio"
74 | local empty_attr = { "", {}, {} }
75 | local empty_cell = { attr = empty_attr,
76 | alignment = pandoc.AlignDefault,
77 | row_span = 1,
78 | col_span = 1,
79 | contents = {} }
80 |
81 | local function get_widths(attr)
82 | local widths = List()
83 | for num in string.gmatch(attr, "(%d+%.?%d*),?") do
84 | --debug(num)
85 | --[[
86 | num = tonumber(num)
87 | if num == 0 and FORMAT == "docx" then
88 | num = 0.01
89 | end
90 | ]]
91 | widths:append(tonumber(num))
92 | end
93 | --pretty.dump(widths)
94 | return widths
95 | end
96 |
97 | local function sum_content(row)
98 | local sum = 0
99 | -- Row is a list of Cell's
100 | --debug("simple_sum_content()")
101 | for _, cell in ipairs(row) do
102 | sum = sum + #cell
103 | end
104 | return sum
105 | end
106 |
107 | local function fill_widths(col_max, widths)
108 | if widths ~= nil then
109 | widths = get_widths(widths)
110 | debug(WIDTH_MESSAGE)
111 | else
112 | widths = {}
113 | end
114 |
115 | local rest = 1 - seq.sum(widths)
116 | local rest_columns_width = 0
117 | if rest <= 1 then
118 | rest_columns_width = rest / (col_max - #widths)
119 | end
120 | --debug(rest_columns_width)
121 |
122 | while col_max > #widths do
123 | if FORMAT == "docx" then
124 | table.insert(widths, 0.01)
125 | else
126 | table.insert(widths, rest_columns_width)
127 | end
128 | end
129 | --pretty.dump(widths)
130 | return widths
131 | end
132 |
133 | local function merge_colspecs(colspecs, widths)
134 | for idx, _ in ipairs(widths) do
135 | table.insert(colspecs[idx], widths[idx])
136 | end
137 | pretty.dump(table.colspecs)
138 | return colspecs
139 | end
140 |
141 | local function table_width(tbl, attr)
142 | debug(MESSAGE)
143 | --pretty.dump(el.attributes["width"])
144 | local widths = attr["width"]
145 | local noheader = get_tf(attr["noheader"], false)
146 |
147 | local headers = tbl.headers
148 | local body = tbl.rows
149 | local col_max = #tbl.widths
150 |
151 | if noheader and headers ~= {} then
152 | debug(NOHEADER_MESSAGE)
153 | if #body == 1 and sum_content(body[1]) == 0 then
154 | -- valid header row + first body row is blank
155 | -- -> remove header row + first body row has ex-header row contents
156 | debug("[ lua ] header row overrides first body row && remove header row (pandoc < 2.10)")
157 | tbl.rows[1] = headers
158 | else
159 | -- valid header row + first body row is not blank
160 | -- -> remove header row + ex-header row stacks at top of body rows
161 | debug("[ lua ] header row is inserted at head of body rows (pandoc < 2.10)")
162 | table.insert(tbl.rows, 1, headers)
163 | end
164 | tbl.headers = {}
165 | end
166 | widths = fill_widths(col_max, widths)
167 | tbl.widths = widths
168 |
169 | --pretty.dump(widths)
170 | return tbl
171 | end
172 |
173 | local function table_finder(el)
174 | if el.classes:find("table") then
175 | if #el.content == 1 and el.content[1].tag == "Table" then
176 | table_width(el.content[1], el.attributes)
177 | end
178 | end
179 | end
180 |
181 | if PANDOC_VERSION < { 2, 10 } then
182 | return { { Div = table_finder } }
183 | end
184 |
--------------------------------------------------------------------------------
/lua/docx-apply-cell-styles.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # docx-apply-cell-styles.lua
3 |
4 | Finds table; get list of alignment; get list of styles to apply; apply styles for each cell
5 | ]]
6 | --local pretty = require("pl.pretty")
7 |
8 | local stringify = require("pandoc.utils").stringify
9 | local debug = require("pandocker.utils").debug
10 | local util_get_meta = require("pandocker.utils").util_get_meta
11 |
12 | local meta_key = "table-cell-styles"
13 | local meta = {}
14 | local default_meta = require("pandocker.default_loader")[meta_key]
15 |
16 | local tablex = require("pl.tablex")
17 |
18 | MESSAGE = "[ lua ] Apply table cell styles"
19 |
20 | if FORMAT == "docx" or FORMAT == "native" then
21 |
22 | local function get_meta(mt)
23 | meta = util_get_meta(mt, default_meta, meta_key)
24 | end
25 |
26 | local function get_header_styles(align)
27 | local aligns_table = {
28 | AlignDefault = stringify(meta["header-default"]),
29 | AlignLeft = stringify(meta["header-left"]),
30 | AlignCenter = stringify(meta["header-center"]),
31 | AlignRight = stringify(meta["header-right"]) }
32 | --debug(aligns_table[align])
33 | return aligns_table[align]
34 | end
35 |
36 | local function get_body_styles(align)
37 | --pretty.dump(meta)
38 | local aligns_table = {
39 | AlignDefault = stringify(meta["body-default"]),
40 | AlignLeft = stringify(meta["body-left"]),
41 | AlignCenter = stringify(meta["body-center"]),
42 | AlignRight = stringify(meta["body-right"]) }
43 | --debug(aligns_table[align])
44 | return aligns_table[align]
45 | end
46 |
47 | local function plain2para(el)
48 | --pretty.dump(el.content)
49 | --pretty.dump(el.tag)
50 | if el.tag == "Plain" then
51 | el = pandoc.Para(el.content)
52 | end
53 | return el
54 | end
55 |
56 | local function get_aligns(el)
57 | local aligns = {}
58 | for _, v in ipairs(el.colspecs) do
59 | table.insert(aligns, v[1])
60 | end
61 | return aligns
62 | end
63 |
64 | local function get_headers(el)
65 | local headers = {}
66 | headers = el.head
67 | return headers
68 | end
69 |
70 | local function get_body_rows(el)
71 | local rows = {}
72 | rows = el.bodies[1].body
73 | return rows
74 | end
75 |
76 | local function apply_rows_styles(rows, styles)
77 | local row_attr = {}
78 | local _cell = {}
79 | --local rows_attr = rows[1]
80 | --rows = rows[2]
81 | for i, row in ipairs(rows) do
82 | if tablex.find(tablex.keys(row), "cells") ~= nil then
83 | -- pandoc >= 2.17
84 | row_attr = row.attr
85 | row = row.cells
86 | else
87 | -- pandoc < 2.17
88 | row_attr = row[1]
89 | row = row[2]
90 | end
91 | --debug(tostring(tablex.deepcompare(empty_attr, row_attr)))
92 | for j, cell in ipairs(row) do
93 | --pretty.dump(cell.contents)
94 | _cell = pandoc.Div(cell.contents)
95 | _cell["attr"]["attributes"]["custom-style"] = stringify(styles[j])
96 | cell.contents = { _cell }
97 | row[j] = cell
98 | end
99 | rows[i] = { row_attr, row }
100 | end
101 | return rows
102 | end
103 |
104 | local function apply_header_styles(header, styles)
105 | local headers
106 | local header_attr = nil
107 | if tablex.find(tablex.keys(header), "rows") ~= nil then
108 | -- pandoc >= 2.17
109 | header_attr = header.attr
110 | headers = header.rows
111 | header.rows = apply_rows_styles(headers, styles)
112 | return header
113 | else
114 | --debug("header[1]." .. tostring(tablex.keys(header[1])))
115 | -- pandoc < 2.17
116 | header_attr = header[1]
117 | headers = header[2]
118 | header = apply_rows_styles(headers, styles)
119 | return { header_attr, header }
120 | end
121 | end
122 |
123 | local function apply_cell_styles(el)
124 | debug(MESSAGE)
125 | local aligns = get_aligns(el)
126 | local headers = get_headers(el)
127 | local rows = get_body_rows(el)
128 | --pretty.dump(aligns)
129 | local body_styles = {}
130 | local header_styles = {}
131 | for _, v in ipairs(aligns) do
132 | table.insert(body_styles, get_body_styles(v))
133 | table.insert(header_styles, get_header_styles(v))
134 | end
135 | --pretty.dump(body_styles)
136 | --pretty.dump(header_styles)
137 | el.head = apply_header_styles(headers, header_styles)
138 | rows = apply_rows_styles(rows, body_styles)
139 |
140 | return el
141 | end
142 |
143 | local function apply_simple_cell_styles(el)
144 | debug(MESSAGE)
145 | local body_styles = {}
146 | local header_styles = {}
147 | for _, v in ipairs(el.aligns) do
148 | table.insert(body_styles, get_body_styles(v))
149 | table.insert(header_styles, get_header_styles(v))
150 | end
151 | for i, header in ipairs(el.headers) do
152 | if #header > 0 then
153 | local header_cell = pandoc.Div(header)
154 | header_cell["attr"]["attributes"]["custom-style"] = stringify(header_styles[i])
155 | el.headers[i] = { header_cell }
156 | end
157 | end
158 |
159 | for i, row in ipairs(el.rows) do
160 | for j, cell in ipairs(row) do
161 | --cell = plain2para(cell)
162 | local body_cell = pandoc.Div(cell)
163 | body_cell["attr"]["attributes"]["custom-style"] = stringify(body_styles[j])
164 | el.rows[i][j] = { body_cell }
165 | end
166 | end
167 | return el
168 | end
169 |
170 | local function version_switch (el)
171 | -- apply plein2para() for each Plain in el
172 | el = pandoc.walk_block(el, { Plain = plain2para })
173 | if PANDOC_VERSION < { 2, 10 } then
174 | return apply_simple_cell_styles(el)
175 | else
176 | return apply_cell_styles(el)
177 | end
178 | end
179 | return { { Meta = get_meta }, { Table = version_switch } }
180 |
181 | end
182 |
183 |
--------------------------------------------------------------------------------
/lua/table-width.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # table-width.lua
3 |
4 | Applies table attributes to a table inside a Div
5 |
6 | ## Syntax
7 |
8 | :::{.table width=[w1,w2,...] noheader=true|false}
9 |
10 | : Caption {#tbl:table}
11 |
12 | | Header | Row | Table |
13 | |:----------|:-----:|------:|
14 | | Cell | Cell | Cell |
15 |
16 | :::
17 |
18 | where,
19 |
20 | - w1,w2,... : width value for each column. if not fully given padded by
21 | (1 - (sum of given widths)) / (number of unnumbered columns)
22 | e.g. When [0.5] is given for 4-column table, the first column will have 0.5 and the rest will have 0.16667 each
23 | of page width (i.e. (1 - 0.5) / 3)
24 | - noheader: flag if header row exists. `true` to move header row to head of body rows.
25 | Default is `false`. When table has only one blank row, header row overrides body row so that
26 | table has single row without header row.
27 |
28 | try:
29 | $ pandoc -t native -L lua/table-width.lua
30 | :::{.table width=[0.5] noheader=true}
31 | : Test1
32 |
33 | | Header |
34 | |:----------|
35 | | Cell |
36 | :::
37 |
38 | :::{.table width=[0.5] noheader=true}
39 | : Test2
40 |
41 | | Cell | Cell |
42 | |:----------|----------:|
43 | | | |
44 | :::
45 |
46 | :::{.table }
47 | | head | head2 |
48 | |----|----|
49 | |cell|cell|
50 | :::
51 |
52 |
53 | :::{.table }
54 | |head|
55 | |----|
56 | | |
57 | :::
58 | ]]
59 |
60 | --local stringify = require("pandoc.utils").stringify
61 |
62 | local pretty = require("pl.pretty")
63 | local seq = require("pl.seq")
64 | local tablex = require("pl.tablex")
65 | local List = require("pl.List")
66 | require("pl.stringx").import()
67 |
68 | local debug = require("pandocker.utils").debug
69 | local get_tf = require("pandocker.utils").get_tf
70 |
71 | local MESSAGE = "[ lua ] Div in 'table' class found"
72 | local NOHEADER_MESSAGE = "[ lua ] Move header row to body rows"
73 | local WIDTH_MESSAGE = "[ lua ] Adjust column ratio"
74 | local empty_attr = { "", {}, {} }
75 | local empty_cell = { attr = empty_attr,
76 | alignment = pandoc.AlignDefault,
77 | row_span = 1,
78 | col_span = 1,
79 | contents = {} }
80 |
81 | local function get_widths(attr)
82 | local widths = List()
83 | for num in string.gmatch(attr, "(%d+%.?%d*),?") do
84 | --debug(num)
85 | num = tonumber(num)
86 | if num == 0 and FORMAT == "docx" then
87 | num = 0.01
88 | end
89 | widths:append(tonumber(num))
90 | end
91 | --pretty.dump(widths)
92 | return widths
93 | end
94 |
95 | local function sum_content(row)
96 | local sum = 0
97 | local cells = 0
98 | if tablex.find(tablex.keys(row), "cells") ~= nil then
99 | cells = row.cells -- pandoc >= 2.17
100 | else
101 | cells = row[2] -- 2.10 <= pandoc < 2.17
102 | end
103 | --pretty.dump(el)
104 | --row _should_ be a list of cells but:
105 | --when whole row is blank cells, __row is a nil__
106 | if row ~= nil then
107 | for _, cell in ipairs(cells) do
108 | --debug(tostring(tablex.deepcompare(empty_cell, cell)))
109 | if not tablex.deepcompare(empty_cell, cell) then
110 | --pretty.dump(cell)
111 | sum = sum + 1
112 | end
113 | end
114 | end
115 | return sum
116 | end
117 |
118 | local function fill_widths(col_max, widths)
119 | if widths ~= nil then
120 | widths = get_widths(widths)
121 | debug(WIDTH_MESSAGE)
122 | else
123 | widths = {}
124 | end
125 |
126 | local rest = 1 - seq.sum(widths)
127 | local rest_columns_width = 0
128 | if 0 < rest and rest <= 1 then
129 | rest_columns_width = rest / (col_max - #widths)
130 | else
131 | debug("[ Lua ] Sum of width exceeds page width")
132 | end
133 | --debug(rest_columns_width)
134 |
135 | while col_max > #widths do
136 | table.insert(widths, rest_columns_width)
137 | end
138 | --pretty.dump(widths)
139 | return widths
140 | end
141 |
142 | local function merge_colspecs(colspecs, widths)
143 | for idx, _ in ipairs(widths) do
144 | if #colspecs[idx] == 1 then
145 | table.insert(colspecs[idx], widths[idx])
146 | else
147 | colspecs[idx][2] = widths[idx]
148 | end
149 | end
150 | --pretty.dump(colspecs)
151 | return colspecs
152 | end
153 |
154 | local function table_width(tbl)
155 | debug(MESSAGE)
156 | --pretty.dump(tbl.attributes.width)
157 | local widths = tbl.attributes.width
158 | local noheader = get_tf(tbl.attributes.noheader, false)
159 | local empty_row = { empty_attr, {} }
160 |
161 | --debug("tbl.attributes." .. tostring(tablex.keys(tbl.attributes)))
162 | --debug("tbl.head." .. tostring(tablex.keys(tbl.head)))
163 | --debug("tbl.bodies[1]." .. tostring(tablex.keys(tbl.bodies[1])))
164 |
165 | --debug("tbl.head." .. tostring(tablex.keys(tbl.head)))
166 | local headers = nil
167 | if tablex.find(tablex.keys(tbl.head), "rows") ~= nil then
168 | headers = tbl.head.rows -- pandoc >= 2.17
169 | else
170 | headers = tbl.head[2] -- pandoc < 2.17
171 | end
172 |
173 | local body = tbl.bodies[1].body
174 | local col_max = #tbl.colspecs
175 | --pretty.dump(body)
176 |
177 | for _, v in ipairs(tablex.range(1, col_max)) do
178 | table.insert(empty_row[2], empty_cell)
179 | end
180 |
181 | if noheader and headers ~= {} then
182 | debug(NOHEADER_MESSAGE)
183 | --debug(#body)
184 | --debug(sum_content(body[1]))
185 | -- valid header row + first body row is blank
186 | if #body == 1 and sum_content(body[1]) == 0 then
187 | debug("[ lua ] header row overrides first body row && remove header row (pandoc >= 2.10)")
188 | tbl.bodies[1].body = headers
189 | else
190 | debug("[ lua ] header row is inserted at head of body rows (pandoc >= 2.10)")
191 | --pretty.dump(tbl.bodies[1].body)
192 | --pretty.dump(headers)
193 | table.insert(tbl.bodies[1].body, 1, headers[1])
194 | end
195 | tbl.head = pandoc.TableHead({ })
196 | end
197 | widths = fill_widths(col_max, widths)
198 | tbl.colspecs = merge_colspecs(tbl.colspecs, widths)
199 | --pretty.dump(tbl.colspecs)
200 | --pretty.dump(widths)
201 | return tbl
202 | end
203 |
204 | local function give_attribute_to_table(el)
205 | if el.classes:find("table") then
206 | if #el.content == 1 and el.content[1].tag == "Table" then
207 | el.content[1].attr = el.attr
208 | return { el.content[1] }
209 | end
210 | end
211 | end
212 |
213 | local function table_finder(el)
214 | if el.classes:find("table") then
215 | return { table_width(el) }
216 | end
217 | end
218 |
219 | if PANDOC_VERSION >= { 2, 10 } then
220 | return { { Div = give_attribute_to_table }, { Table = table_finder } }
221 | end
222 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pandocker-lua-filters
2 |
3 | Lua filters for pandoc
4 |
5 | ## Install
6 |
7 | - installs as a python package for ease of use
8 | - `pip install pandocker-lua-filters`
9 | - Lua filters should be installed under `/share/lua/{5.3|5.4}/pandocker` where
10 | `` can be confirmed by `python -c "import sys; print(sys.prefix)"`. It install **both** 5.3 and 5.4
11 | directories no matter of actual lua versions in system.
12 | This `/share/lua/{5.3|5.4}` should be added to `package.path` which can be confirmed
13 | by `lua -e "print(package.path)"`.
14 |
15 | ## General use
16 |
17 | #### Convert AAFigure ascii art
18 |
19 | - requires `aafigure` python package
20 |
21 | [**`aafigure.lua`**](lua/aafigure.lua)
22 |
23 | #### Convert CSV into table
24 |
25 | - requires `csv` and `penlight` luarocks packages
26 | - Pandoc below 2.10 applies "simple" filters
27 |
28 | [**`csv2table.lua`**](lua/csv2table.lua)
29 | [**`csv2table-simple.lua`**](lua/csv2table-simple.lua)
30 |
31 | #### Replace `title` `subtitle` `date` `author` metadata
32 |
33 | [**`hide-frontpage-metadata`**](lua/hide-frontpage-metadata.lua)
34 |
35 | #### Text file listing
36 |
37 | - requires `penlight` luarocks package
38 |
39 | [**`listingtable.lua`**](lua/listingtable.lua)
40 |
41 | #### Concatenate text files
42 |
43 | [**`preprocess.lua`**](lua/preprocess.lua)
44 |
45 | #### Removable note block
46 |
47 | [**`removable-note.lua`**](lua/removable-note.lua)
48 |
49 | #### Convert svgbob ascii art
50 |
51 | [**`svgbob.lua`**](lua/svgbob.lua)
52 |
53 | #### Convert SVG images to other formats
54 |
55 | - requires `rsvg-convert` in `$PATH`
56 |
57 | [**`svgconvert.lua`**](lua/svgconvert.lua)
58 |
59 | #### Applies table attributes to a table
60 |
61 | - requires `penlight` luarocks package
62 | - Pandoc below 2.10 applies "simple" filters
63 |
64 | [**`table-width.lua`**](lua/table-width.lua)
65 | [**`table-width-simple.lua`**](lua/table-width-simple.lua)
66 |
67 | #### Wavedrom / Bit-Field
68 |
69 | - requires `wavedrom-cli` in `$PATH` (`npm i -g wavedrom-cli`)
70 | - requires `lyaml` and `lua-cjson2` luarocks packages
71 |
72 | [**`wavedrom.lua`**](lua/wavedrom.lua)
73 |
74 | ## *LaTeX* output only
75 |
76 | #### Landscape pages
77 |
78 | [**`tex-landscape.lua`**](lua/tex-landscape.lua)
79 |
80 |
85 |
86 | #### Applies underline to `.underline` class span
87 |
88 | [**`tex-underline.lua`**](lua/tex-underline.lua)
89 |
90 | ## *Docx* output only
91 |
92 | #### Inserts a comment
93 |
94 | [**`docx-comment.lua`**](lua/docx-comment.lua)
95 |
96 | #### Apply custom (paragraph) styles for each table cell
97 |
98 | [**`docx-apply-cell-styles.lua`**](lua/docx-apply-cell-styles.lua)
99 |
100 | #### Apply custom (paragraph) styles for image and its caption
101 |
102 | [**`docx-image-styles.lua`**](lua/docx-image-styles.lua)
103 |
104 | #### Apply custom (character) styles for any span
105 |
106 | [**`docx-custom-span-styles.lua`**](lua/docx-custom-span-styles.lua)
107 |
108 | #### Apply in-place color for any span
109 |
110 | [**`docx-colored-span.lua`**](lua/docx-colored-span.lua)
111 |
112 | #### Apply custom (paragraph) styles for any unnumbered bullet lists
113 |
114 | Finds unnumbered bullet lists down to 3rd level and applies custom paragraph styles.
115 | **4th level and lower list items are escalated to 3rd level**.
116 |
117 | [**`docx-extract-bullet-lists.lua`**](lua/docx-extract-bullet-lists.lua)
118 |
119 | ##### Requirement for template
120 |
121 | - Prepare `Bullet List 1` to `Bullet List 3` paragraph styles (by the way this is 1st level list item)
122 | - Otherwise these headers inherit `Body` style (this is 2nd level)
123 |
124 | | Level | Unnumbered |
125 | |:-----:|:--------------|
126 | | 1 | Bullet List 1 |
127 | | 2 | Bullet List 2 |
128 | | 3+ | Bullet List 3 |
129 |
130 | #### TOC / Pagebreak / Linebreak / Sub section TOC
131 |
132 | [**`docx-pagebreak-toc.lua`**](lua/docx-pagebreak-toc.lua)
133 |
134 | - Adds TOC(Table Of Contents), sub sections, a line break or a page break at any point of document
135 |
136 | ##### Requirement for template
137 |
138 | TOC title is set to "Table of Contents" by default. Metadata `toc-title` overrides this setting.
139 |
140 | #### Appendix headings
141 |
142 | [**`docx-appendixheadings.lua`**](lua/docx-appendixheadings.lua)
143 |
144 | - Makes `appendix` class work to _appendix_ headings in DOCX format
145 | - Limited to level-1 to 5 headings
146 |
147 | ##### Requirement for template
148 |
149 | - Prepare `Appendix Heading 1` to `Appendix Heading 5` heading styles
150 | - Otherwise these headers inherit `Body` style
151 |
152 | | Level | Numbered | Unnumbered |
153 | |:-----:|:----------|:-------------------|
154 | | 1 | Heading 1 | Appendix Heading 1 |
155 | | 2 | Heading 2 | Appendix Heading 2 |
156 | | 3 | Heading 3 | Appendix Heading 3 |
157 | | 4 | Heading 4 | Appendix Heading 4 |
158 | | 5 | Heading 5 | Appendix Heading 5 |
159 | | 6 | Heading 6 | |
160 |
161 | #### Unnumbered headings
162 |
163 | [**`docx-unnumberedheadings.lua`**](lua/docx-unnumberedheadings.lua)
164 |
165 | - Makes `UnnumberHeadings` class work to _unnumber_ headings in DOCX format
166 | - Limited to level-1 to 5 headings
167 |
168 | ##### Requirement for template
169 |
170 | - Prepare `Heading Unnumbered 1` to `Heading Unnumbered 5` heading styles
171 | - Otherwise these headers inherit `Body` style
172 |
173 | | Level | Numbered | Unnumbered |
174 | |:-----:|:----------|:---------------------|
175 | | 1 | Heading 1 | Heading Unnumbered 1 |
176 | | 2 | Heading 2 | Heading Unnumbered 2 |
177 | | 3 | Heading 3 | Heading Unnumbered 3 |
178 | | 4 | Heading 4 | Heading Unnumbered 4 |
179 | | 5 | Heading 5 | Heading Unnumbered 5 |
180 | | 6 | Heading 6 | |
181 |
182 | #### Figure styles
183 |
184 | [**`docx-image-styles.lua`**](lua/docx-image-styles.lua)
185 |
186 | - Processes only paragraph having single image link
187 | - Blank lines required before and after image link
188 | - Requires `Graphic Anchor` and `Figure Caption` paragraph styles in template
189 | otherwise these styles inherit `Body` style
190 | - the filter creates two divs having `custom-style` attribute
191 | - after process the image is placed in `custom-style="Graphic Anchor"` div and its caption is
192 | in `custom-style="Figure Caption"`
193 | div respectively
194 |
195 | ##### Requirement for template
196 |
197 | - Prepare `Graphic Anchor` and `Figure Caption` styles
198 |
199 | # samples
200 |
201 | ```markdown
202 | {width=100mm #fig:centered}
203 | ```
204 |
205 | ## Want a new feature?
206 |
207 | Feature request (via issues) and PRs are welcome. Post questions in issues with `[Q]` in issue title.
208 |
209 | ### DIY
210 |
211 | As lua filters only requires pandoc itself, it is relatively easy
212 | to try develop a new filter. I recommend to use `k4zuki/pandocker-alpine`
213 | *docker image* like
214 |
215 | - `docker pull k4zuki/pandocker-alpine` to get image
216 | - clone this repo `git clone git@github.com:pandocker/pandocker-lua-filters.git`
217 | - `cd pandocker-lua-filters`
218 | - `docker run --rm -it -v/$PWD:/workdir k4zuki/pandocker-alpine` to start docker image
219 | - `make install` to install filters in image. They are installed in `/usr/local/share/lua/5.3/pandocker/`
220 | - `make reinstall` to *reinstall* so that filters will be updated
221 | - `make uninstall` to uninstall filters
222 | - `make html|pdf|docx` to compile test document
223 | - edit `tests/Makefile` to configure options for pandoc
224 |
225 | You don't have to `reinstall` for every source code updates. Instead edit `tests/Makefile`
226 | to run your new filter from inside repository.
227 |
--------------------------------------------------------------------------------
/lua/csv2table-simple.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # csv2table.lua
3 |
4 | Converts Link to a csv file into Table object
5 |
6 | ## Syntax
7 |
8 | [Caption](/path/to/file){.table width=[w1,w2,...] header=true nocaption=true alignment=a1a2... \
9 | subset_from=(y1,x1) subset_to=(y2,x2) #tbl:table}
10 | where,
11 |
12 | - Caption: caption of this table. if not given filename is used
13 | - /path/to/file : path to file. relative to directory where pandoc is invoked
14 | - header : flag to let first row as header row. defaults true
15 | - nocaption : Flag to unset temporary caption. defaults false
16 | - w1,w2,... : width value for each column. if not fully given padded by
17 | (1 - (sum of given widths)) / (number of unnumbered columns)
18 | e.g. When [0.5] is given for 4-column table, the first column will have 0.5 and the rest will have 0.16667 each
19 | of page width (i.e. (1 - 0.5) / 3)
20 | - a1a2... : alignment list for each column. c=Center, d=Default, l=Left, r=Right.
21 | if not given padded by d
22 | - subset_from : (row,col) pair to specify coordinate to cut FROM
23 | - subset_to : (row,col) pair to specify coordinate to cut TO
24 | - delimiter : separator character such as ";". default is ","
25 |
26 | ### Equivalent output
27 |
28 | : Caption {#tbl:table}
29 |
30 | | Header | Row | Table |
31 | |:----------|:-----:|------:|
32 | | Cell | Cell | Cell |
33 |
34 | ]]
35 |
36 | --local pretty = require("pl.pretty")
37 | require("pl.stringx").import()
38 | local List = require("pl.List")
39 | local tablex = require("pl.tablex")
40 | local seq = require("pl.seq")
41 | local csv = require("csv")
42 |
43 | local stringify = require("pandoc.utils").stringify
44 | local debug = require("pandocker.utils").debug
45 | local file_exists = require("pandocker.utils").file_exists
46 |
47 | local MESSAGE = "[ lua ] insert a table from %s"
48 | local FILE_NOT_FOUND = "[ lua ] %s: file not found"
49 |
50 | local table_template = [==[
51 | | table |
52 | |-------|
53 | | cell |
54 |
55 | Table: caption
56 | ]==]
57 |
58 | local my_table = pandoc.read(table_template, "markdown").blocks[1]
59 |
60 | local empty_attr = { "", {}, {} }
61 | local empty_row = function()
62 | return { {} }
63 | end
64 |
65 | local function get_tf(item, default)
66 | if type(item) == "string" then
67 | item = string.upper(item)
68 | if tablex.search({ "TRUE", "YES" }, item) then
69 | return true
70 | else
71 | return false
72 | end
73 | else
74 | return default
75 | end
76 | end
77 |
78 | local function get_cell(c)
79 | if type(c) ~= "string" then
80 | c = tostring(c)
81 | end
82 | --pretty.dump(c)
83 |
84 | local _cell = pandoc.read(c, "markdown").blocks
85 | return _cell -- List of Blocks
86 | end
87 |
88 | local function get_row(t)
89 | local row = {}
90 | for _, v in ipairs(t) do
91 | --dump(get_cell(v), "")
92 | table.insert(row, get_cell(v))
93 | end
94 | return row -- List of List of Blocks
95 | end
96 |
97 | local ALIGN = { ["D"] = pandoc.AlignDefault,
98 | ["L"] = pandoc.AlignLeft,
99 | ["C"] = pandoc.AlignCenter,
100 | ["R"] = pandoc.AlignRight
101 | }
102 |
103 | local function get_xy(attr)
104 | local _y = 1
105 | local _x = 1
106 | _y, _x = string.match(attr, "(%d+),(%d+)")
107 | --debug(attr .. " " .. _y .. " " .. _x)
108 | _y = tonumber(_y)
109 | _x = tonumber(_x)
110 | return _y, _x
111 | end
112 |
113 | local function get_widths(attr)
114 | local widths = List()
115 | for num in string.gmatch(attr, "(%d+%.?%d*),?") do
116 | --debug(num)
117 | widths:append(tonumber(num))
118 | end
119 | return widths
120 | end
121 |
122 | local function get_alignments(attr)
123 | local alignment = List()
124 | for al in string.gmatch(attr, "[dlrcDLRC]") do
125 | --debug(al)
126 | alignment:append(ALIGN[al:upper()])
127 | end
128 | return alignment
129 | end
130 |
131 | local function tabular(el)
132 | if el.classes:includes "table" then
133 | if tostring(PANDOC_VERSION) == "2.15" then
134 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
135 | return
136 | end
137 | local tab = {}
138 | local source_file = stringify(el.target)
139 | local header_avail = get_tf(el.attributes.header, true)
140 | local header = empty_row()
141 | local nocaption = get_tf(el.attributes.nocaption, false)
142 | local y_from = 1
143 | local x_from = 1
144 | local y_to = -1
145 | local x_to = -1
146 | local caption = ""
147 | local alignment = List()
148 | local widths = List()
149 | local delimiter = el.attributes.delimiter
150 | if el.attributes.delimiter == nil then
151 | delimiter = ","
152 | else
153 | debug("[ Lua ] apply different CSV delimiter for parse")
154 | end
155 |
156 | if file_exists(source_file) then
157 | tab = csv.open(source_file, { separator = delimiter })
158 | --pretty.dump(tab)
159 | else
160 | debug(string.format(FILE_NOT_FOUND, source_file))
161 | return
162 | end
163 | if stringify(el.content) == "" then
164 | if nocaption then
165 | caption = {}
166 | else
167 | caption = { pandoc.Str(el.target) }
168 | end
169 | else
170 | caption = el.content
171 | end
172 | --pretty.dump(caption)
173 | if el.identifier ~= "" then
174 | caption = List(caption)
175 | caption:append(pandoc.Space())
176 | caption:append(pandoc.Str("{#" .. el.identifier .. "}"))
177 | end
178 | if el.attributes.subset_from ~= nil then
179 | y_from, x_from = get_xy(el.attributes.subset_from)
180 | end
181 | if el.attributes.subset_to ~= nil then
182 | y_to, x_to = get_xy(el.attributes.subset_to)
183 | if x_to < x_from then
184 | x_to = x_from
185 | end
186 | if y_to < y_from then
187 | y_to = y_from
188 | end
189 | end
190 | if el.attributes.alignment ~= nil then
191 | alignment = get_alignments(el.attributes.alignment)
192 | end
193 | if el.attributes.width ~= nil then
194 | widths = get_widths(el.attributes.width)
195 | end
196 | local rows = List()
197 | local i = 1
198 | local col_max = 1
199 | for row in tab:lines() do
200 | if i >= y_from then
201 | row = List(row):slice(x_from, x_to)
202 | --pretty.dump(row)
203 | col_max = math.max(col_max, #row)
204 | rows:append(get_row(row))
205 | if y_to > 0 and i >= y_to then
206 | break
207 | end
208 | end
209 | i = i + 1
210 | end
211 | if header_avail then
212 | header = rows:pop(1)
213 | --pretty.dump(header)
214 | end
215 | --pretty.dump(header)
216 | while col_max > #alignment do
217 | alignment:append(ALIGN.D)
218 | end
219 |
220 | local rest = 1 - seq.sum(widths)
221 | local rest_columns_width = 0
222 | if rest <= 1 then
223 | rest_columns_width = rest / (col_max - #widths)
224 | end
225 | --debug(rest_width)
226 |
227 | while col_max > #widths do
228 | if FORMAT == "docx" then
229 | widths:append(0.01)
230 | else
231 | widths:append(rest_columns_width)
232 | end
233 | end
234 | --pretty.dump(alignment)
235 | debug(string.format(MESSAGE, source_file))
236 | return pandoc.Table(
237 | caption,
238 | alignment,
239 | widths,
240 | header,
241 | rows
242 | )
243 | end
244 | end
245 |
246 | local function link2table(el)
247 | if #el.content == 1 and el.content[1].tag == "Link" then
248 | return tabular(el.content[1])
249 | end
250 | end
251 |
252 | if PANDOC_VERSION < { 2, 10 } then
253 | return { { Para = link2table } }
254 | end
255 |
--------------------------------------------------------------------------------
/lua/csv2table.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | # csv2table.lua
3 |
4 | Converts Link to a csv file into Table object
5 |
6 | ## Syntax
7 |
8 | [Caption](/path/to/file){.table width=[w1,w2,...] header=true nocaption=true alignment=a1a2... \
9 | subset_from=(y1,x1) subset_to=(y2,x2) #tbl:table}
10 | where,
11 |
12 | - Caption: caption of this table. if not given filename is used
13 | - /path/to/file : path to file. relative to directory where pandoc is invoked
14 | - header : flag to let first row as header row. defaults true
15 | - nocaption : Flag to unset temporary caption. defaults false
16 | - w1,w2,... : width value for each column. if not fully given padded by
17 | (1 - (sum of given widths)) / (number of unnumbered columns)
18 | e.g. When [0.5] is given for 4-column table, the first column will have 0.5 and the rest will have 0.16667 each
19 | of page width (i.e. (1 - 0.5) / 3)
20 | - a1a2... : alignment list for each column. c=Center, d=Default, l=Left, r=Right.
21 | if not given padded by d
22 | - subset_from : (row,col) pair to specify coordinate to cut FROM
23 | - subset_to : (row,col) pair to specify coordinate to cut TO
24 | - delimiter : separator character such as ";". default is ","
25 |
26 | ### Equivalent output
27 |
28 | : Caption {#tbl:table}
29 |
30 | | Header | Row | Table |
31 | |:----------|:-----:|------:|
32 | | Cell | Cell | Cell |
33 |
34 | ]]
35 |
36 | local pretty = require("pl.pretty")
37 | require("pl.stringx").import()
38 | local List = require("pl.List")
39 | local tablex = require("pl.tablex")
40 | local seq = require("pl.seq")
41 | local csv = require("csv")
42 |
43 | local stringify = require("pandoc.utils").stringify
44 | local debug = require("pandocker.utils").debug
45 | local file_exists = require("pandocker.utils").file_exists
46 |
47 | local MESSAGE = "[ lua ] insert a table from %s"
48 | local FILE_NOT_FOUND = "[ lua ] %s: file not found"
49 |
50 | local table_template = [==[
51 | | table |
52 | |-------|
53 | | cell |
54 |
55 | Table: caption
56 | ]==]
57 |
58 | local my_table = pandoc.read(table_template, "markdown").blocks[1]
59 |
60 | local empty_attr = { "", {}, {} }
61 | local empty_row = function()
62 | return { empty_attr, {} }
63 | end
64 |
65 | local function get_tf(item, default)
66 | if type(item) == "string" then
67 | item = string.upper(item)
68 | if tablex.search({ "TRUE", "YES" }, item) then
69 | return true
70 | else
71 | return false
72 | end
73 | else
74 | return default
75 | end
76 | end
77 |
78 | local function get_cell(c)
79 | if type(c) ~= "string" then
80 | c = tostring(c)
81 | end
82 | --pretty.dump(c)
83 |
84 | local _cell = pandoc.read(c, "markdown").blocks
85 | return { attr = empty_attr,
86 | alignment = pandoc.AlignDefault,
87 | row_span = 1,
88 | col_span = 1,
89 | contents = pandoc.List(_cell) } -- Cell
90 | end
91 |
92 | local function get_row(t)
93 | local row = {}
94 | for _, v in ipairs(t) do
95 | --dump(get_cell(v), "")
96 | table.insert(row, get_cell(v))
97 | end
98 | return { empty_attr, row }
99 | end
100 |
101 | local ALIGN = { ["D"] = pandoc.AlignDefault,
102 | ["L"] = pandoc.AlignLeft,
103 | ["C"] = pandoc.AlignCenter,
104 | ["R"] = pandoc.AlignRight
105 | }
106 |
107 | local function get_xy(attr)
108 | local _y = 1
109 | local _x = 1
110 | _y, _x = string.match(attr, "(%d+),(%d+)")
111 | --debug(attr .. " " .. _y .. " " .. _x)
112 | _y = tonumber(_y)
113 | _x = tonumber(_x)
114 | return _y, _x
115 | end
116 |
117 | local function get_widths(attr)
118 | local widths = List()
119 | for num in string.gmatch(attr, "(%d+%.?%d*),?") do
120 | --debug(num)
121 | widths:append(tonumber(num))
122 | end
123 | return widths
124 | end
125 |
126 | local function get_alignments(attr)
127 | local alignment = List()
128 | for al in string.gmatch(attr, "[dlrcDLRC]") do
129 | --debug(al)
130 | alignment:append(ALIGN[al:upper()])
131 | end
132 | return alignment
133 | end
134 |
135 | local function tabular(el)
136 | if el.classes:includes "table" then
137 | if tostring(PANDOC_VERSION) == "2.15" then
138 | debug("[ Lua ] " .. PANDOC_SCRIPT_FILE .. ": Pandoc version 2.15 is not supported. Bypassing.")
139 | return
140 | end
141 | local tab = {}
142 | local source_file = stringify(el.target)
143 | local header_avail = get_tf(el.attributes.header, true)
144 | local header = empty_row()
145 | local nocaption = get_tf(el.attributes.nocaption, false)
146 | local y_from = 1
147 | local x_from = 1
148 | local y_to = -1
149 | local x_to = -1
150 | local caption = ""
151 | local alignment = List()
152 | local widths = List()
153 | local delimiter = el.attributes.delimiter
154 | if el.attributes.delimiter == nil then
155 | delimiter = ","
156 | else
157 | debug("[ Lua ] apply different CSV delimiter for parse")
158 | end
159 |
160 | if file_exists(source_file) then
161 | tab = csv.open(source_file, { separator = delimiter })
162 | --pretty.dump(tab)
163 | else
164 | debug(string.format(FILE_NOT_FOUND, source_file))
165 | return
166 | end
167 | if stringify(el.content) == "" then
168 | if nocaption then
169 | caption = {}
170 | else
171 | caption = { pandoc.Str(el.target) }
172 | end
173 | else
174 | caption = el.content
175 | end
176 | --pretty.dump(caption)
177 | if el.identifier ~= "" then
178 | caption = List(caption)
179 | caption:append(pandoc.Space())
180 | caption:append(pandoc.Str("{#" .. el.identifier .. "}"))
181 | end
182 | if el.attributes.subset_from ~= nil then
183 | y_from, x_from = get_xy(el.attributes.subset_from)
184 | end
185 | if el.attributes.subset_to ~= nil then
186 | y_to, x_to = get_xy(el.attributes.subset_to)
187 | if x_to < x_from then
188 | x_to = x_from
189 | end
190 | if y_to < y_from then
191 | y_to = y_from
192 | end
193 | end
194 | if el.attributes.alignment ~= nil then
195 | alignment = get_alignments(el.attributes.alignment)
196 | end
197 | if el.attributes.width ~= nil then
198 | widths = get_widths(el.attributes.width)
199 | end
200 | local rows = List()
201 | local i = 1
202 | local col_max = 1
203 | for row in tab:lines() do
204 | if i >= y_from then
205 | row = List(row):slice(x_from, x_to)
206 | --pretty.dump(row)
207 | col_max = math.max(col_max, #row)
208 | rows:append(get_row(row))
209 | if y_to > 0 and i >= y_to then
210 | break
211 | end
212 | end
213 | i = i + 1
214 | end
215 | if header_avail then
216 | header = rows:pop(1)
217 | --pretty.dump(header)
218 | end
219 | --pretty.dump(header)
220 | while col_max > #alignment do
221 | alignment:append(ALIGN.D)
222 | end
223 |
224 | local rest = 1 - seq.sum(widths)
225 | local rest_columns_width = 0
226 | if 0 < rest and rest <= 1 then
227 | rest_columns_width = rest / (col_max - #widths)
228 | else
229 | debug("[ Lua ] Sum of width exceeds page width")
230 | end
231 | --debug(rest_width)
232 |
233 | while col_max > #widths do
234 | widths:append(rest_columns_width)
235 | end
236 | --pretty.dump(alignment)
237 | debug(string.format(MESSAGE, source_file))
238 | --pretty.dump(header)
239 | local table = my_table:clone()
240 | --debug("table." .. tostring(tablex.keys(table)))
241 | --debug(tostring(tablex.keys(table.head)))
242 | if tablex.find(tablex.keys(table.head), "rows") ~= nil then
243 | -- pandoc >= 2.17
244 | table.head.rows = { header }
245 | else
246 | -- pandoc < 2.17
247 | table.head[2] = { header }
248 | end
249 | --pretty.dump(table.head)
250 | table.caption = { long = { pandoc.Plain(caption) } }
251 | --pretty.dump(table.caption)
252 | table.colspecs = tablex.zip(alignment, widths)
253 | --pretty.dump(table.colspecs)
254 | table.bodies = { { attr = empty_attr,
255 | head = { },
256 | body = rows,
257 | row_head_columns = 0 } }
258 | --pretty.dump(table.bodies)
259 | return table
260 | end
261 | end
262 |
263 | local function link2table(el)
264 | if #el.content == 1 and el.content[1].tag == "Link" then
265 | return tabular(el.content[1])
266 | end
267 | end
268 |
269 | if PANDOC_VERSION >= { 2, 10 } then
270 | return { { Para = link2table } }
271 | end
272 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | """A setuptools based setup module.
2 |
3 | See:
4 | https://packaging.python.org/en/latest/distributing.html
5 | https://github.com/pypa/sampleproject
6 | """
7 |
8 | # Always prefer setuptools over distutils
9 | from setuptools import setup, find_packages
10 | from os import path
11 | # io.open is needed for projects that support Python 2.7
12 | # It ensures open() defaults to text mode with universal newlines,
13 | # and accepts an argument to specify the text encoding
14 | # Python 3 only projects can skip this import
15 | from io import open
16 |
17 | here = path.abspath(path.dirname(__file__))
18 |
19 | list_of_filters = ["lua/aafigure.lua",
20 | "lua/csv2table.lua",
21 | "lua/csv2table-simple.lua",
22 | "lua/default_loader.lua",
23 | "lua/docx-appendixheadings.lua",
24 | "lua/docx-apply-cell-styles.lua",
25 | "lua/docx-comment.lua",
26 | "lua/docx-colored-span.lua",
27 | "lua/docx-custom-span-styles.lua",
28 | "lua/docx-extract-bullet-lists.lua",
29 | "lua/docx-image-styles.lua",
30 | "lua/docx-pagebreak-toc.lua",
31 | "lua/docx-unnumberedheadings.lua",
32 | "lua/hide-frontpage-metadata.lua",
33 | "lua/listingtable.lua",
34 | "lua/preprocess.lua",
35 | "lua/removable-note.lua",
36 | "lua/svgbob.lua",
37 | "lua/svgconvert.lua",
38 | "lua/table-width.lua",
39 | "lua/table-width-simple.lua",
40 | "lua/tex-landscape.lua",
41 | "lua/tex-quote.lua",
42 | "lua/tex-remove-sout.lua",
43 | "lua/tex-rowcolors-reset.lua",
44 | "lua/utils.lua",
45 | "lua/wavedrom.lua",
46 |
47 | "lua/metadata-file.yaml",
48 | ]
49 | # Get the long description from the README file
50 | with open(path.join(here, 'README.md'), encoding='utf-8') as f:
51 | long_description = f.read()
52 |
53 | # Arguments marked as "Required" below must be included for upload to PyPI.
54 | # Fields marked as "Optional" may be commented out.
55 |
56 | setup(
57 | # This is the name of your project. The first time you publish this
58 | # package, this name will be registered for you. It will determine how
59 | # users can install this project, e.g.:
60 | #
61 | # $ pip install sampleproject
62 | #
63 | # And where it will live on PyPI: https://pypi.org/project/sampleproject/
64 | #
65 | # There are some restrictions on what makes a valid project name
66 | # specification here:
67 | # https://packaging.python.org/specifications/core-metadata/#name
68 | name='pandocker-lua-filters', # Required
69 |
70 | # Versions should comply with PEP 440:
71 | # https://www.python.org/dev/peps/pep-0440/
72 | #
73 | # For a discussion on single-sourcing the version across setup.py and the
74 | # project code, see
75 | # https://packaging.python.org/en/latest/single_source_version.html
76 | # version='1.2.0', # Required
77 | use_scm_version={
78 | "relative_to": __file__,
79 | "write_to": "pandocker_lua_filters/version.py",
80 | },
81 | setup_requires=['setuptools_scm'],
82 |
83 | # This is a one-line description or tagline of what your project does. This
84 | # corresponds to the "Summary" metadata field:
85 | # https://packaging.python.org/specifications/core-metadata/#summary
86 | description='Lua filter collection for pandoc', # Optional
87 |
88 | # This is an optional longer description of your project that represents
89 | # the body of text which users will see when they visit PyPI.
90 | #
91 | # Often, this is the same as your README, so you can just read it in from
92 | # that file directly (as we have already done above)
93 | #
94 | # This field corresponds to the "Description" metadata field:
95 | # https://packaging.python.org/specifications/core-metadata/#description-optional
96 | long_description=long_description, # Optional
97 |
98 | # Denotes that our long_description is in Markdown; valid values are
99 | # text/plain, text/x-rst, and text/markdown
100 | #
101 | # Optional if long_description is written in reStructuredText (rst) but
102 | # required for plain-text or Markdown; if unspecified, "applications should
103 | # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and
104 | # fall back to text/plain if it is not valid rst" (see link below)
105 | #
106 | # This field corresponds to the "Description-Content-Type" metadata field:
107 | # https://packaging.python.org/specifications/core-metadata/#description-content-type-optional
108 | long_description_content_type='text/markdown', # Optional (see note above)
109 |
110 | # This should be a valid link to your project's main homepage.
111 | #
112 | # This field corresponds to the "Home-Page" metadata field:
113 | # https://packaging.python.org/specifications/core-metadata/#home-page-optional
114 | url='https://github.com/pandocker/pandocker-lua-filters', # Optional
115 |
116 | # This should be your name or the name of the organization which owns the
117 | # project.
118 | author='pandocker', # Optional
119 |
120 | # This should be a valid email address corresponding to the author listed
121 | # above.
122 | author_email='pandocker@github.com', # Optional
123 |
124 | # Classifiers help users find your project by categorizing it.
125 | #
126 | # For a list of valid classifiers, see https://pypi.org/classifiers/
127 | classifiers=[ # Optional
128 | # How mature is this project? Common values are
129 | # 3 - Alpha
130 | # 4 - Beta
131 | # 5 - Production/Stable
132 | 'Development Status :: 3 - Alpha',
133 |
134 | # Indicate who your project is intended for
135 | 'Intended Audience :: Developers',
136 | 'Topic :: Software Development :: Build Tools',
137 |
138 | # Pick your license as you wish
139 | 'License :: OSI Approved :: MIT License',
140 |
141 | # Specify the Python versions you support here. In particular, ensure
142 | # that you indicate whether you support Python 2, Python 3 or both.
143 | 'Programming Language :: Python :: 3.5',
144 | 'Programming Language :: Python :: 3.6',
145 | 'Programming Language :: Python :: 3.7',
146 | ],
147 |
148 | # This field adds keywords for your project which will appear on the
149 | # project page. What does your project relate to?
150 | #
151 | # Note that this is a string of words separated by whitespace, not a list.
152 | keywords='Pandoc Lua Filter', # Optional
153 |
154 | # You can just specify package directories manually here if your project is
155 | # simple. Or you can use find_packages().
156 | #
157 | # Alternatively, if you just want to distribute a single Python file, use
158 | # the `py_modules` argument instead as follows, which will expect a file
159 | # called `my_module.py` to exist:
160 | #
161 | # py_modules=["my_module"],
162 | #
163 | packages=find_packages(exclude=['contrib', 'docs', 'tests']), # Required
164 |
165 | # This field lists other packages that your project depends on to run.
166 | # Any package you put here will be installed by pip when your project is
167 | # installed, so they must be valid existing projects.
168 | #
169 | # For an analysis of "install_requires" vs pip's requirements files see:
170 | # https://packaging.python.org/en/latest/requirements.html
171 | install_requires=["aafigure"], # Optional
172 |
173 | # List additional groups of dependencies here (e.g. development
174 | # dependencies). Users will be able to install these using the "extras"
175 | # syntax, for example:
176 | #
177 | # $ pip install sampleproject[dev]
178 | #
179 | # Similar to `install_requires` above, these must be valid existing
180 | # projects.
181 | # extras_require={ # Optional
182 | # 'dev': ['check-manifest'],
183 | # 'test': ['coverage'],
184 | # },
185 |
186 | # If there are data files included in your packages that need to be
187 | # installed, specify them here.
188 | #
189 | # If using Python 2.6 or earlier, then these have to be included in
190 | # MANIFEST.in as well.
191 | # package_data={ # Optional
192 | # 'sample': ['package_data.dat'],
193 | # },
194 |
195 | # Although 'package_data' is the preferred approach, in some case you may
196 | # need to place data files outside of your packages. See:
197 | # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
198 | #
199 | # In this case, 'data_file' will be installed into '/my_data'
200 | data_files=[('share/lua/5.3/pandocker', list_of_filters),
201 | ('share/lua/5.4/pandocker', list_of_filters),
202 | ('bin/pandocker', ['build/svgbob',
203 | 'build/svgbob.bin',
204 | 'build/svgbob.exe',
205 | ]),
206 | ], # Optional
207 |
208 | # To provide executable scripts, use entry points in preference to the
209 | # "scripts" keyword. Entry points provide cross-platform support and allow
210 | # `pip` to create the appropriate form of executable for the target
211 | # platform.
212 | #
213 | # For example, the following would provide a command called `sample` which
214 | # executes the function `main` from this package when invoked:
215 | entry_points={ # Optional
216 | 'console_scripts': [
217 | 'pandocker-lua-filters=pandocker_lua_filters:main',
218 | 'get-platform=pandocker_lua_filters:get_platform',
219 | ],
220 | },
221 |
222 | # List additional URLs that are relevant to your project as a dict.
223 | #
224 | # This field corresponds to the "Project-URL" metadata fields:
225 | # https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use
226 | #
227 | # Examples listed include a pattern for specifying where the package tracks
228 | # issues, where the source is hosted, where to say thanks to the package
229 | # maintainers, and where to support the project financially. The key is
230 | # what's used to render the link text on PyPI.
231 | project_urls={ # Optional
232 | 'Bug Reports': 'https://github.com/pandocker/pandocker-lua-filters/issues',
233 | # 'Funding': 'https://donate.pypi.org',
234 | # 'Say Thanks!': 'http://saythanks.io/to/example',
235 | 'Source': 'https://github.com/pandocker/pandocker-lua-filters/',
236 | },
237 | )
238 |
--------------------------------------------------------------------------------