pandoc-md-slides: A pandoc filter to convert markdown notes to markdown slides

[ mit, program, text ] [ Propose Tags ] [ Report a vulnerability ]

A pandoc filter to convert markdown notes to markdown slides. Splits long slides and resolves image target paths


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 1.0.0.0, 1.1.0.0, 1.1.1.0, 1.1.2.0
Change log CHANGELOG.md
Dependencies aeson (>=2.3.2 && <2.4), base (>=4.18.3 && <4.21), filepath (>=1.5.0 && <1.6), optparse-applicative (>=0.19.0 && <0.20), pandoc-types (>=1.23.1 && <1.24), path (>=0.9.0 && <0.10), path-io (>=1.8.0 && <1.9), pcre2 (>=2.3.0 && <2.4), regex-tdfa (>=1.3.2 && <1.4), text (>=2.1.4 && <2.2), yaml (>=0.11.11 && <0.12) [details]
Tested with ghc ==9.6.7, ghc ==9.8.4, ghc ==9.10.3
License MIT
Author Rubelito Abella
Maintainer bbadoodles@gmail.com
Uploaded by rrabella at 2026-09-23T11:30:30Z
Category Text
Source repo head: git clone https://github.com/HowDoIGitHelp/autoslides-pandocfilter.git
Distributions
Executables remarkjs, md-slides
Downloads 12 total (12 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
Last success reported on 2026-09-23 [all 1 reports]

Readme for pandoc-md-slides-1.1.2.0

[back to package description]

pandoc-md-slides

A Pandoc filter to convert markdown notes to markdown slides

This pandoc filter converts markdown notes (written in plain prose) into summarized slides. The filter automatically splits long slides and resolves image target paths to new paths. You can also configure the filter to change slide split behavior, change paragraph transformation behavior, set source and output directories for image target replacement, add optional transformations.

Installing using cabal

You can install the package using cabal install pandoc-md-slides, it will install the binary md-slides

Basic Usage

pandoc test.md --filter md-slides -o outputs/output.md

Transformations

Paragraph Blocks

Paragraph blocks are split based on newlines and summarized into a BulletList. The resulting list will only keep important sentences (i.e. sentences with emphasized words and/or strong words).

Separate paragraphs will be placed in separate slides. Only top-level paragraph blocks are transformed into lists.

## Header

This is a paragraph block.
That contains **important sentences**.
And unimportant sentences.
It will keep the *important ones*.
The header will be used as a *slide header*.

Separate Paragraphs will be placed in *separate slides*.
Like *this one*.
Paragraphs with no headers will use the *most recent* headers as slide headers.
# Header

- That contains **important sentences**.
- It will keep the *important ones*.
- The header will be used as a *slide header*.

---

# Header

- Separate Paragraphs will be placed in *separate slides*.
- Like *this one*.
- Paragraphs with no headers will use the *most recent* headers as slide
  headers.

Splitting slides

Long slides are split into multiple slides, if the blocks can be split. Blocks that can be split are, bullet lists (including the transformed summarized paragraphs), ordered lists, display math blocks, code, table.

You can configure the split behavior by controlling the slide lines (-l) and line width (-w) arguments. A slide is split if it exceeds the slide lines. The number of lines of a slide is calculated based on the slide type and line width argument.

pandoc -t json test.md | \
    md-filter -l 6 -w 60 | \
    pandoc -f json \
    -t markdown-simple_tables-multiline_tables-grid_tables \
    -o outputs/output.md

The following default values will be used if the arguments are not set.

  • slide lines (-l) - 6
  • line width (-w) - 100
## Header

- item1
- item2
- item3
- item4
- item5
- item6
- item7
- item8
- item9
- item10
- item11
- item12
- item13
## Header

- item1
- item2
- item3
- item4
- item5
- item6

---

## Header

- item7
- item8
- item9
- item10

---

## Header

- item11
- item12
- item13

Math

When display math blocks are split, the display math is split based on math newlines (\\), ignoring newlines on matrix and bmatrix environments.

If the entire display math block are in an aligned environment, the split slides will inherit the aligned environment.

## Header

$$
\begin{aligned}
{n \choose r-1}+{n \choose r}&=\frac{n!}{(r-1)!(n-(r-1))!}+\frac{n!}{r!(n-r)!}\\
&=\frac{n!}{(r-1)!(n-r+1)!}+\frac{n!}{r!(n-r)!}\\
&=\frac{n!r}{r!(n-r+1)!}+\frac{n!(n-r+1)}{r!(n-r+1)!}\\
&=\frac{n!r+n!(n-r+1)}{r!(n-r+1)!}\\
&=\frac{n!(n+1)}{r!(n+1-r)!}\\
&=\frac{(n+1)!}{r!(n+1-r)!}\\
{n \choose r-1}+{n \choose r}&={n+1 \choose r}
\end{aligned}
$$
## Header

$$
\begin{aligned}
{n \choose r-1}+{n \choose r}&=\frac{n!}{(r-1)!(n-(r-1))!}+\frac{n!}{r!(n-r)!}\\
&=\frac{n!}{(r-1)!(n-r+1)!}+\frac{n!}{r!(n-r)!}\\
&=\frac{n!r}{r!(n-r+1)!}+\frac{n!(n-r+1)}{r!(n-r+1)!}\\
&=\frac{n!r+n!(n-r+1)}{r!(n-r+1)!}
\end{aligned}
$$

---

## Header

$$
\begin{aligned}
&=\frac{n!(n+1)}{r!(n+1-r)!}\\
&=\frac{(n+1)!}{r!(n+1-r)!}\\
{n \choose r-1}+{n \choose r}&={n+1 \choose r}
\end{aligned}
$$

Image target replacement

You can pass two arguments in the filter, input file directory, and output file directory. When used this way, the filter will replace image target paths with new paths resolved based on the output file directory. If a path cannot be resolved based on the output file directory, then the said path is considered an external url or absolute path.

Here's an example of applying arguments to the filter. To pass arguments to the filter, you must apply the filter directly on the AST. In the example below, the markdown document is converted to json using pandoc and the resulting json is piped to the filter with arguments. The transformed json is then piped to a pandoc transformation back to the format markdown-simple_tables-multiline_tables-grid_tables.

pandoc -t json test.md | \
    md-filter -s "." -o "outputs/" | \
    pandoc -f json \
    -t markdown-simple_tables-multiline_tables-grid_tables \
    -o outputs/output.md

Here's an example Makefile that you can use to automatically resolve the directories of the source and the output.

INPUTDIR ?= $(dir $(SOURCE))
OUTPUTDIR ?= $(dir $(OUTPUT))

$(OUTPUT): $(SOURCE)
	pandoc -t json $(SOURCE) | \
		md-slides -s $(INPUTDIR) -o $(OUTPUTDIR) | \
		remarkjs | \
		pandoc -f json \
		-t markdown-simple_tables-multiline_tables-grid_tables \
        -o $(OUTPUT)

Extra configuration options

You can optionally create a slides.yaml in the directory you are running the filter. This file can contain your configuration for maxSlideLines, maxLineWidth, sourceDirectory, outputDirectory. Program arguments applied to the filter will override the yaml configuration.

It also contains the following extra configurations that are currently only possible through slides.yaml:

keptSentences

This is a list of strings that will be converted to a list of predicates that will be used to choose which sentences are kept in the Para to BulletList transformation. Predicates that are available are:

  • all: matches sentences
  • important: matches sentences that contain either Strong or Emph. This is the default behavior if keptSentences is not used.
  • code: matches sentences that contain inline Code
  • math: matches sentences that contain inline Math
  • lastColon: matches sentences that are positioned last in the paragraph and ends with :.
  • none: overrides the default, and matches no sentence.
  • 1,2, 3 ...: matches the first, second, third or nth sentence

You can include multiple predicates. These predicates will be combined through disjunction.

keptSentences:
  - code
  - math
  - important

Note that, for none to properly function as a predicate, there must be no other predicates added to the list.

unOrphanDisplayBlocks

This is a boolean option when enabled, will use an optional transformation (applied last) that is applied on pairs of slides with the following characteristics:

  • The first slide contains a plain BulletList.
  • The last item in the BulletList is a sentence that ends with :.
  • The second slide contains a DisplayBlock (DisplayMath, CodeBlock, Figure, Table, BulletList, OrderedList).

When this transformation is applied the last item from the first slide's list is transferred to the second slide.

Below we can see an example of this transformation applied after the other transformations.

## Variables

- Apply universal instantiation to $\forall X q(X)$:

## Variables

$$
\begin{aligned}
q(a) \land \\
\neg q(a)
\end{aligned}
$$
## Variables

- Apply universal instantiation to $\forall X q(X)$:

$$
\begin{aligned}
q(a) \land \\
\neg q(a)
\end{aligned}
$$

When enabling this option, you can make sure that colon ending sentences are not filtered out by the paragraph transformation by adding the lastColon predicate in keptSentences.