├── .editorconfig
├── .github
└── workflows
│ ├── ci.yaml
│ └── website.yml
├── .gitignore
├── .tools
└── docs.lua
├── LICENSE
├── Makefile
├── README.md
├── greetings.lua
└── test
├── expected.native
├── input.md
└── test.yaml
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 | end_of_line = lf
9 | charset = utf-8
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 |
13 | [Makefile]
14 | indent_style = tab
15 |
16 | [*.lua]
17 | indent_style = space
18 | indent_size = 2
19 | # Code should stay below 80 characters per line.
20 | max_line_length = 80
21 |
22 | [*.md]
23 | # Text with 60 to 66 characters per line is said to be the easiest
24 | # to read.
25 | max_line_length = 66
26 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | # Run on all pull requests that change code.
5 | pull_request:
6 | paths-ignore:
7 | - 'README.md'
8 | - LICENSE
9 | - .editorconfig
10 | # Run every time a code change is pushed.
11 | push:
12 | paths-ignore:
13 | - 'README.md'
14 | - LICENSE
15 | - .editorconfig
16 | # Test if things still work each Tuesday morning at 5:39 UTC.
17 | # This way we will catch incompatible pandoc changes in a timely
18 | # manner.
19 | schedule:
20 | # At 5:39am each Tuesday
21 | - cron: '39 5 * * 2'
22 |
23 | jobs:
24 | test:
25 | runs-on: ubuntu-latest
26 | strategy:
27 | fail-fast: true
28 | matrix:
29 | pandoc:
30 | - edge
31 | - latest
32 | # This should be the oldest version that's supported
33 | # - 2.19.2
34 |
35 | container:
36 | image: pandoc/core:${{ matrix.pandoc }}
37 |
38 | steps:
39 | - name: Checkout
40 | uses: actions/checkout@v4
41 |
42 | - name: Install dependencies
43 | run: apk add make
44 |
45 | - name: Test
46 | run: make test
47 |
--------------------------------------------------------------------------------
/.github/workflows/website.yml:
--------------------------------------------------------------------------------
1 | name: Publish Website
2 |
3 | # Allow one concurrent deployment
4 | concurrency:
5 | group: "pages"
6 | cancel-in-progress: true
7 |
8 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
9 | permissions:
10 | contents: read
11 | pages: write
12 | id-token: write
13 |
14 | on:
15 | push:
16 | branches: ['main']
17 |
18 | jobs:
19 | website:
20 | runs-on: ubuntu-latest
21 | environment:
22 | name: github-pages
23 | url: ${{ steps.deployment.outputs.page_url }}
24 | steps:
25 | - name: Checkout repository
26 | uses: actions/checkout@v4
27 | - name: Setup Pages
28 | uses: actions/configure-pages@v5
29 | - name: Render Website
30 | run: |
31 | make -B website \
32 | PANDOC="docker run --rm --volume $(pwd):/data \
33 | --user $(id -u):$(id -g) pandoc/core:latest"
34 | - name: Upload artifact
35 | uses: actions/upload-pages-artifact@v3
36 | with:
37 | path: '_site'
38 | - name: Deploy to GitHub Pages
39 | id: deployment
40 | uses: actions/deploy-pages@main
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /_site/
2 |
--------------------------------------------------------------------------------
/.tools/docs.lua:
--------------------------------------------------------------------------------
1 | local path = require 'pandoc.path'
2 | local utils = require 'pandoc.utils'
3 | local stringify = utils.stringify
4 |
5 | local function read_file (filename)
6 | local fh = io.open(filename)
7 | local content = fh:read('*a')
8 | fh:close()
9 | return content
10 | end
11 |
12 | local formats_by_extension = {
13 | md = 'markdown',
14 | latex = 'latex',
15 | native = 'haskell',
16 | tex = 'latex',
17 | html = 'html',
18 | }
19 |
20 | local function sample_blocks (sample_file)
21 | local sample_content = read_file(sample_file)
22 | local extension = select(2, path.split_extension(sample_file)):sub(2)
23 | local format = formats_by_extension[extension] or extension
24 | local filename = path.filename(sample_file)
25 |
26 | local sample_attr = pandoc.Attr('', {format, 'sample'})
27 | return {
28 | pandoc.Header(3, pandoc.Str(filename), {filename}),
29 | pandoc.CodeBlock(sample_content, sample_attr)
30 | }
31 | end
32 |
33 | local function result_block_raw(result_file, format)
34 | local result_content = read_file(result_file)
35 |
36 | return pandoc.CodeBlock(result_content,
37 | pandoc.Attr('', {format, 'sample'})
38 | )
39 | end
40 |
41 | local function result_block_html(filename)
42 | local html = ''
46 | return pandoc.RawBlock('html', html)
47 | end
48 |
49 | local function result_blocks(result_file)
50 | local extension = select(2, path.split_extension(result_file)):sub(2)
51 | local format = formats_by_extension[extension] or extension
52 | local filename = path.filename(result_file)
53 | local result = pandoc.List:new({
54 | pandoc.Header(3,
55 | pandoc.Link(pandoc.Str(filename), filename),
56 | {filename}
57 | )
58 | })
59 |
60 | if format == 'html' then
61 | result:insert(result_block_html(filename))
62 | else
63 | result:insert(result_block_raw(result_file, format))
64 | end
65 |
66 | return result
67 | end
68 |
69 |
70 | local function code_blocks (code_file)
71 | local code_content = read_file(code_file)
72 | local code_attr = pandoc.Attr(code_file, {'lua'})
73 | return {
74 | pandoc.CodeBlock(code_content, code_attr)
75 | }
76 | end
77 |
78 | function Pandoc (doc)
79 | local meta = doc.meta
80 | local blocks = doc.blocks
81 |
82 | -- Set document title from README title. There should usually be just
83 | -- a single level 1 heading.
84 | blocks = blocks:walk{
85 | Header = function (h)
86 | if h.level == 1 then
87 | meta.title = h.content
88 | return {}
89 | end
90 | end
91 | }
92 |
93 | -- Add the sample file as an example.
94 | blocks:extend{pandoc.Header(2, 'Example', pandoc.Attr('Example'))}
95 | blocks:extend(sample_blocks(stringify(meta['sample-file'])))
96 | blocks:extend(result_blocks(stringify(meta['result-file'])))
97 |
98 | -- Add the filter code.
99 | local code_file = stringify(meta['code-file'])
100 | blocks:extend{pandoc.Header(2, 'Code', pandoc.Attr('Code'))}
101 | blocks:extend{pandoc.Para{pandoc.Link(pandoc.Str(code_file), code_file)}}
102 | blocks:extend(code_blocks(code_file))
103 |
104 | return pandoc.Pandoc(blocks, meta)
105 | end
106 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright © 2021–2022 Albert Krewinkel and contributors.
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 | # Name of the filter file, *with* `.lua` file extension.
2 | FILTER_FILE := $(wildcard *.lua)
3 | # Name of the filter, *without* `.lua` file extension
4 | FILTER_NAME = $(patsubst %.lua,%,$(FILTER_FILE))
5 |
6 | # Allow to use a different pandoc binary, e.g. when testing.
7 | PANDOC ?= pandoc
8 | # Allow to adjust the diff command if necessary
9 | DIFF = diff
10 | # Use a POSIX sed with ERE ('v' is specific to GNU sed)
11 | SED := sed $(shell sed v /dev/null 2>&1 && echo " --posix") -E
12 |
13 | # Pandoc formats for test outputs
14 | ifeq "$(FORMAT)" ""
15 | FORMAT = native
16 | endif
17 |
18 | # Directory containing the Quarto extension
19 | QUARTO_EXT_DIR = _extensions/$(FILTER_NAME)
20 | # The extension's name. Used in the Quarto extension metadata
21 | EXT_NAME = $(FILTER_NAME)
22 | # Current version, i.e., the latest tag. Used to version the quarto
23 | # extension.
24 | VERSION = $(shell git tag --sort=-version:refname --merged | head -n1 | \
25 | sed -e 's/^v//' | tr -d "\n")
26 | ifeq "$(VERSION)" ""
27 | VERSION = 0.0.0
28 | endif
29 |
30 | # GitHub repository; used to setup the filter.
31 | REPO_PATH = $(shell git remote get-url origin | sed -e 's%.*github\.com[/:]%%')
32 | REPO_NAME = $(shell git remote get-url origin | sed -e 's%.*/%%')
33 | USER_NAME = $(shell git config user.name)
34 |
35 | ## Show available targets
36 | # Comments preceding "simple" targets (those which do not use macro
37 | # name or starts with underscore or dot) and introduced by two dashes
38 | # are used as their description.
39 | .PHONY: help
40 | help:
41 | @tabs 22 ; $(SED) -ne \
42 | '/^## / h ; /^[^_.$$#][^ ]+:/ { G; s/^(.*):.*##(.*)/\1@\2/; P ; h ; }' \
43 | $(MAKEFILE_LIST) | tr @ '\t'
44 |
45 | #
46 | # Test
47 | #
48 |
49 | ## Test that running the filter on the sample input yields expected outputs
50 | # The automatic variable `$<` refers to the first dependency
51 | # (i.e., the filter file).
52 | # let `test` be a PHONY target so that it is run each time it's called.
53 | .PHONY: test
54 | test: $(FILTER_FILE) test/input.md test/test.yaml
55 | @for ext in $(FORMAT) ; do \
56 | $(PANDOC) --defaults test/test.yaml --to $$ext | \
57 | $(DIFF) test/expected.$$ext - ; \
58 | done
59 |
60 | ## Generate the expected output
61 | # This target **must not** be a dependency of the `test` target, as that
62 | # would cause it to be regenerated on each run, making the test
63 | # pointless.
64 | .PHONY: generate
65 | generate: $(FILTER_FILE) test/input.md test/test.yaml
66 | @for ext in $(FORMAT) ; do \
67 | $(PANDOC) --defaults test/test.yaml --to $$ext \
68 | --output test/expected.$$ext ; \
69 | done
70 |
71 | #
72 | # Website
73 | #
74 |
75 | ## Generate website files in _site
76 | .PHONY: website
77 | website: _site/index.html _site/$(FILTER_FILE)
78 |
79 | _site/index.html: README.md test/input.md $(FILTER_FILE) .tools/docs.lua \
80 | _site/output.md _site/style.css
81 | @mkdir -p _site
82 | $(PANDOC) \
83 | --standalone \
84 | --lua-filter=.tools/docs.lua \
85 | --metadata=sample-file:test/input.md \
86 | --metadata=result-file:_site/output.md \
87 | --metadata=code-file:$(FILTER_FILE) \
88 | --css=style.css \
89 | --toc \
90 | --output=$@ $<
91 |
92 | _site/style.css:
93 | @mkdir -p _site
94 | curl \
95 | --output $@ \
96 | 'https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/light.css'
97 |
98 | _site/output.md: $(FILTER_FILE) test/input.md test/test.yaml
99 | @mkdir -p _site
100 | $(PANDOC) \
101 | --defaults=test/test.yaml \
102 | --to=markdown \
103 | --output=$@
104 |
105 | _site/$(FILTER_FILE): $(FILTER_FILE)
106 | @mkdir -p _site
107 | (cd _site && ln -sf ../$< $<)
108 |
109 | #
110 | # Quarto extension
111 | #
112 |
113 | ## Creates or updates the quarto extension
114 | .PHONY: quarto-extension
115 | quarto-extension: $(QUARTO_EXT_DIR)/_extension.yml \
116 | $(QUARTO_EXT_DIR)/$(FILTER_FILE)
117 |
118 | $(QUARTO_EXT_DIR):
119 | mkdir -p $@
120 |
121 | # This may change, so re-create the file every time
122 | .PHONY: $(QUARTO_EXT_DIR)/_extension.yml
123 | $(QUARTO_EXT_DIR)/_extension.yml: _extensions/$(FILTER_NAME)
124 | @printf 'Creating %s\n' $@
125 | @printf 'name: %s\n' "$(EXT_NAME)" > $@
126 | @printf 'author: %s\n' "$(USER_NAME)" >> $@
127 | @printf 'version: %s\n' "$(VERSION)" >> $@
128 | @printf 'contributes:\n filters:\n - %s\n' $(FILTER_FILE) >> $@
129 |
130 | # The filter file must be below the quarto _extensions folder: a
131 | # symlink in the extension would not work due to the way in which
132 | # quarto installs extensions.
133 | $(QUARTO_EXT_DIR)/$(FILTER_FILE): $(FILTER_FILE) $(QUARTO_EXT_DIR)
134 | if [ ! -L $(FILTER_FILE) ]; then \
135 | mv $(FILTER_FILE) $(QUARTO_EXT_DIR)/$(FILTER_FILE) && \
136 | ln -s $(QUARTO_EXT_DIR)/$(FILTER_FILE) $(FILTER_FILE); \
137 | fi
138 |
139 | #
140 | # Release
141 | #
142 |
143 | ## Sets a new release (uses VERSION macro if defined)
144 | .PHONY: release
145 | release: quarto-extension regenerate
146 | git commit -am "Release $(FILTER_NAME) $(VERSION)"
147 | git tag v$(VERSION) -m "$(FILTER_NAME) $(VERSION)"
148 | @echo 'Do not forget to push the tag back to github with `git push --tags`'
149 |
150 | #
151 | # Set up (normally used only once)
152 | #
153 |
154 | ## Update filter name
155 | .PHONY: update-name
156 | update-name:
157 | sed -i'.bak' -e 's/greetings/$(FILTER_NAME)/g' README.md
158 | sed -i'.bak' -e 's/greetings/$(FILTER_NAME)/g' test/test.yaml
159 | rm README.md.bak test/test.yaml.bak
160 |
161 | ## Set everything up (must be used only once)
162 | .PHONY: setup
163 | setup: update-name
164 | git mv greetings.lua $(REPO_NAME).lua
165 | @# Crude method to updates the examples and links; removes the
166 | @# template instructions from the README.
167 | sed -i'.bak' \
168 | -e 's/greetings/$(REPO_NAME)/g' \
169 | -e 's#tarleb/lua-filter-template#$(REPO_PATH)#g' \
170 | -e '/^\* \*/,/^\* \*/d' \
171 | README.md
172 | sed -i'.bak' -e 's/greetings/$(REPO_NAME)/g' test/test.yaml
173 | sed -i'.bak' -e 's/Albert Krewinkel/$(USER_NAME)/' LICENSE
174 | rm README.md.bak test/test.yaml.bak LICENSE.bak
175 |
176 | #
177 | # Helpers
178 | #
179 |
180 | ## Clean regenerables files
181 | .PHONY: clean
182 | clean:
183 | rm -f _site/output.md _site/index.html _site/style.css
184 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Greetings, a Lua Filter Template
2 | ==================================================================
3 |
4 | [![GitHub build status][CI badge]][CI workflow]
5 |
6 | Greetings is a friendly Lua filter that adds a welcoming message
7 | to the document.
8 |
9 | [CI badge]: https://img.shields.io/github/actions/workflow/status/tarleb/lua-filter-template/ci.yaml?branch=main
10 | [CI workflow]: https://github.com/tarleb/lua-filter-template/actions/workflows/ci.yaml
11 |
12 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
13 |
14 | This repository serves as a template intended to make publishing
15 | of pandoc [Lua filters][] easy and convenient. Just click "use
16 | this template" and then make modifications in your new repository.
17 | See also the GitHub documentation on [creating a repository from a
18 | template][from template].
19 |
20 | [Lua filters]: https://pandoc.org/lua-filters.html
21 | [from template]: https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template
22 |
23 | Template Usage
24 | ------------------------------------------------------------------
25 |
26 | This section describes how to use the template.
27 |
28 | ### Checklist
29 |
30 | A few things should be updated in the repository after cloning
31 | this template. You can use the checklist below to ensure that you
32 | get the most out of it. We recommend that you perform at least the
33 | first two steps, everything else is up to you.
34 |
35 | 0. [ ] **Use template**: Create a new repo from
36 | this template. Use the name that you want to give your filter
37 | as a repository name. E.g., a repository for filter
38 | `greetings.lua` should be named `greetings`.
39 | 1. [ ] **Clone your new repository**: Run `git clone` to fetch
40 | your new repository.
41 | 2. [ ] **Setup the filter**: the easiest way to setup the
42 | repository is to run
43 |
44 | ``` bash
45 | make setup
46 | ```
47 |
48 | This will update the README, remove the template-specific
49 | documentation, and rename the filter; the repository name is
50 | used to determine the new filter name.
51 |
52 | 3. [ ] **Update the README**: Describe your filter, so people
53 | will know what to expect. You may also want to update the URLs
54 | in the links above to match your repository.
55 |
56 | 4. [ ] (optional) **Choose default test output formats**. Replace
57 | the `FORMAT=native` line in Makefile with your desired default
58 | output formats for tests, e.g. `FORMAT=html latex`. These must
59 | be possible values of Pandoc's `--to` option.
60 |
61 | 4. [ ] (optional) **Setup Quarto extension**: This step is
62 | recommended if you want to make it easy for [Quarto][] users to
63 | install and use your filter: Quarto expects the filter to be
64 | placed in the `_extensions` folder, packed together with a YAML
65 | file containing relevant metadata. Run
66 |
67 | ``` bash
68 | make quarto-extension
69 | ```
70 |
71 | to generate the necessary files and directories. You should
72 | commit the generated files to source control. See also the
73 | [`quarto-extension` documentation](quarto-extension) below.
74 |
75 | 5. [ ] (optional) **Tag a release**: The easiest way to create a
76 | new release is to run `make release VERSION=0.0.1`. This will
77 | update the Quarto extension, commit the changes, then tag the
78 | resulting commit with the given VERSION. This step is
79 | recommended if the filter is distributed as a Quarto extension.
80 |
81 | ### Development
82 |
83 | The repository comes with a `Makefile` intended to make developing
84 | a filter a pleasant experience. You may want to adjust some of the
85 | targets while keeping the general structure.
86 |
87 | Use the Makefile with `make ...`, where `...` denotes one of the
88 | targets listed in this section.
89 |
90 | #### `generate`
91 |
92 | (Re)generate test output files. This target runs your filter on the
93 | file `test/input.md` and generates one or more output files
94 | `test/expected.` (`native` by default).
95 |
96 | Change desired output formats by replacing the Makefile's `FORMAT=...`
97 | line with e.g. `FORMAT=html docx`. These must be possible values of
98 | Pandoc's `--to` option.
99 |
100 | You can also set `FORMAT` on the command line to regenerate files in
101 | specific output formats:
102 |
103 | ```bash
104 | make regenerate FORMAT=docx
105 | ```
106 |
107 | Files are generated using the Pandoc default options given in
108 | `test/test.yaml`. This file is provided by default but you may want
109 | to check it into source control and modify it as needed.
110 |
111 | #### `test`
112 |
113 | Tests the filter. This target runs your filter on the file
114 | `test/input.md` using Pandoc options `test/test.yaml` and compares
115 | the result with one or more `test/expected.` files
116 | (`native` by default).
117 |
118 | See the `regenerate` target on how to change default `FORMAT` values
119 | or passing it on the command lines.
120 |
121 | #### `quarto-extension`
122 |
123 | This target sets the repository up to be used as a [Quarto][]
124 | extension. The target will create the directory structure expected
125 | by quarto. It will also generate a `_extension.yml` metadata file.
126 | Invoking this target will move the main `.lua` file below the
127 | `_extensions` directory; the the original file will be replaced
128 | with a symlink.
129 |
130 | [Quarto]: https://quarto.org
131 |
132 | #### `release`
133 |
134 | Creates a new release for the given version. The version must be
135 | passed as a variable:
136 |
137 | ``` bash
138 | make release VERSION=1.0.0
139 | ```
140 |
141 | The `release` target depends on `quarto-extension`.
142 |
143 | #### `update-name`
144 |
145 | Run this target after renaming the filter file. It will update the
146 | name in all other files.
147 |
148 | #### `website`
149 |
150 | Generates a website for this filter. The website will contain the
151 | contents of this README, an example generated from the test input,
152 | as well as the full filter code. The page components are combined
153 | with the `.tools/docs.lua` filter.
154 |
155 | ### Website
156 |
157 | The repository template comes with a GitHub Action to publish a
158 | website via GitHub pages. It expects the new "GitHub Actions"
159 | source to be used for Pages.
160 |
161 | Remove the file `.github/workflows/website.yml` to disable this
162 | feature.
163 |
164 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
165 |
166 | Usage
167 | ------------------------------------------------------------------
168 |
169 | The filter modifies the internal document representation; it can
170 | be used with many publishing systems that are based on pandoc.
171 |
172 | ### Plain pandoc
173 |
174 | Pass the filter to pandoc via the `--lua-filter` (or `-L`) command
175 | line option.
176 |
177 | pandoc --lua-filter greetings.lua ...
178 |
179 | ### Quarto
180 |
181 | Users of Quarto can install this filter as an extension with
182 |
183 | quarto install extension tarleb/greetings
184 |
185 | and use it by adding `greetings` to the `filters` entry
186 | in their YAML header.
187 |
188 | ``` yaml
189 | ---
190 | filters:
191 | - greetings
192 | ---
193 | ```
194 |
195 | ### R Markdown
196 |
197 | Use `pandoc_args` to invoke the filter. See the [R Markdown
198 | Cookbook](https://bookdown.org/yihui/rmarkdown-cookbook/lua-filters.html)
199 | for details.
200 |
201 | ``` yaml
202 | ---
203 | output:
204 | word_document:
205 | pandoc_args: ['--lua-filter=greetings.lua']
206 | ---
207 | ```
208 |
209 | License
210 | ------------------------------------------------------------------
211 |
212 | This pandoc Lua filter is published under the MIT license, see
213 | file `LICENSE` for details.
214 |
--------------------------------------------------------------------------------
/greetings.lua:
--------------------------------------------------------------------------------
1 | --- greetings.lua – turns any document into a friendly greeting
2 | ---
3 | --- Copyright: © 2021–2022 Contributors
4 | --- License: MIT – see LICENSE for details
5 |
6 | -- Makes sure users know if their pandoc version is too old for this
7 | -- filter.
8 | PANDOC_VERSION:must_be_at_least '2.17'
9 |
10 | --- Amends the contents of a document with a simple greeting.
11 | local function say_hello (doc)
12 | doc.meta.subtitle = doc.meta.title -- demote title to subtitle
13 | doc.meta.title = pandoc.Inlines 'Greetings!' -- set new title
14 | doc.blocks:insert(1, pandoc.Para 'Hello from the Lua filter!')
15 | return doc
16 | end
17 |
18 | return {
19 | -- Apply the `say_hello` function to the main Pandoc document.
20 | { Pandoc = say_hello }
21 | }
22 |
--------------------------------------------------------------------------------
/test/expected.native:
--------------------------------------------------------------------------------
1 | Pandoc
2 | Meta
3 | { unMeta =
4 | fromList
5 | [ ( "author" , MetaInlines [ Str "Nullus" ] )
6 | , ( "subtitle"
7 | , MetaInlines [ Str "Lorem" , Space , Str "ipsum" ]
8 | )
9 | , ( "title" , MetaInlines [ Str "Greetings!" ] )
10 | ]
11 | }
12 | [ Para
13 | [ Str "Hello"
14 | , Space
15 | , Str "from"
16 | , Space
17 | , Str "the"
18 | , Space
19 | , Str "Lua"
20 | , Space
21 | , Str "filter!"
22 | ]
23 | , Para
24 | [ Str "Lorem"
25 | , Space
26 | , Str "ipsum"
27 | , Space
28 | , Str "dolor"
29 | , Space
30 | , Str "sit"
31 | , Space
32 | , Str "amet,"
33 | , Space
34 | , Str "consectetuer"
35 | , Space
36 | , Str "adipiscing"
37 | , Space
38 | , Str "elit."
39 | , Space
40 | , Str "Donec"
41 | , SoftBreak
42 | , Str "hendrerit"
43 | , Space
44 | , Str "tempor"
45 | , Space
46 | , Str "tellus."
47 | , Space
48 | , Str "Donec"
49 | , Space
50 | , Str "pretium"
51 | , Space
52 | , Str "posuere"
53 | , Space
54 | , Str "tellus."
55 | , Space
56 | , Str "Proin"
57 | , Space
58 | , Str "quam"
59 | , SoftBreak
60 | , Str "nisl,"
61 | , Space
62 | , Str "tincidunt"
63 | , Space
64 | , Str "et,"
65 | , Space
66 | , Str "mattis"
67 | , Space
68 | , Str "eget,"
69 | , Space
70 | , Str "convallis"
71 | , Space
72 | , Str "nec,"
73 | , Space
74 | , Str "purus."
75 | ]
76 | ]
77 |
--------------------------------------------------------------------------------
/test/input.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Lorem ipsum
3 | author: Nullus
4 | ---
5 |
6 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec
7 | hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam
8 | nisl, tincidunt et, mattis eget, convallis nec, purus.
9 |
--------------------------------------------------------------------------------
/test/test.yaml:
--------------------------------------------------------------------------------
1 | input-files: ["test/input.md"]
2 | standalone: true
3 | filters:
4 | - {type: lua, path: greetings.lua}
5 |
--------------------------------------------------------------------------------