2016-09-24 09:23:28 +03:00
|
|
|
patat
|
|
|
|
=====
|
|
|
|
|
2016-10-19 21:21:31 +03:00
|
|
|
[![Build Status](https://img.shields.io/travis/jaspervdj/patat.svg)](https://travis-ci.org/jaspervdj/patat) [![Hackage](https://img.shields.io/hackage/v/patat.svg)](https://hackage.haskell.org/package/patat) [![GitHub tag](https://img.shields.io/github/tag/jaspervdj/patat.svg)]()
|
2016-10-02 07:39:49 +03:00
|
|
|
|
2016-10-13 12:00:03 +03:00
|
|
|
`patat` (**P**resentations **A**top **T**he **A**NSI **T**erminal) is a small
|
2016-09-24 09:51:17 +03:00
|
|
|
tool that allows you to show presentations using only an ANSI terminal. It does
|
|
|
|
not require `ncurses`.
|
|
|
|
|
2016-10-14 12:25:26 +03:00
|
|
|
Features:
|
|
|
|
|
|
|
|
- Leverages the great [Pandoc] library to support many input formats including
|
|
|
|
[Literate Haskell].
|
|
|
|
- Supports [smart slide splitting](#input-format).
|
2016-11-15 15:28:58 +03:00
|
|
|
- Slides can be split up into [multiple fragments](#fragmented-slides)
|
2016-10-14 12:25:26 +03:00
|
|
|
- There is a [live reload](#running) mode.
|
|
|
|
- [Theming](#theming) support.
|
2016-11-15 15:28:58 +03:00
|
|
|
- [Auto advancing](#auto-advancing) with configurable delay.
|
2016-10-14 12:25:26 +03:00
|
|
|
- Optionally [re-wrapping](#configuration) text to terminal width with proper
|
|
|
|
indentation.
|
2016-10-17 14:03:02 +03:00
|
|
|
- Syntax highlighting for nearly one hundred languages generated from [Kate]
|
|
|
|
syntax files.
|
2016-10-14 12:25:26 +03:00
|
|
|
- Written in [Haskell].
|
2016-09-24 09:23:28 +03:00
|
|
|
|
2016-10-14 12:25:26 +03:00
|
|
|
![screenshot](extra/screenshot.png?raw=true)
|
2016-09-24 09:23:28 +03:00
|
|
|
|
2016-10-17 14:03:02 +03:00
|
|
|
[Kate]: https://kate-editor.org/
|
2016-09-24 09:23:28 +03:00
|
|
|
[Haskell]: http://haskell.org/
|
|
|
|
[Pandoc]: http://pandoc.org/
|
2016-09-24 09:45:00 +03:00
|
|
|
|
2016-09-24 10:49:29 +03:00
|
|
|
Table of Contents
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
- [Installation](#installation)
|
2016-10-13 14:26:53 +03:00
|
|
|
- [Using stack](#using-stack)
|
|
|
|
- [Using cabal](#using-cabal)
|
2016-09-24 10:49:29 +03:00
|
|
|
- [Running](#running)
|
|
|
|
- [Input format](#input-format)
|
2016-10-13 14:26:53 +03:00
|
|
|
- [Configuration](#configuration)
|
2016-11-15 15:11:31 +03:00
|
|
|
- [Auto advancing](#auto-advancing)
|
2016-11-14 14:55:24 +03:00
|
|
|
- [Fragmented slides](#fragmented-slides)
|
2016-10-13 14:26:53 +03:00
|
|
|
- [Theming](#theming)
|
2016-10-17 14:03:02 +03:00
|
|
|
- [Syntax Highlighting](#syntax-highlighting)
|
2016-09-24 10:49:29 +03:00
|
|
|
- [Trivia](#trivia)
|
|
|
|
|
2016-09-24 10:42:33 +03:00
|
|
|
Installation
|
|
|
|
------------
|
|
|
|
|
|
|
|
You can build from source using `stack install` or `cabal install`. `patat` is
|
|
|
|
also available from [Hackage].
|
|
|
|
|
|
|
|
[Hackage]: https://hackage.haskell.org/package/patat
|
|
|
|
|
2016-10-06 11:28:14 +03:00
|
|
|
For people unfamiliar with the Haskell ecosystem, this means you can do either
|
|
|
|
of the following:
|
|
|
|
|
|
|
|
### Using stack
|
|
|
|
|
|
|
|
1. Install [stack] for your platform.
|
|
|
|
2. Clone this repository.
|
|
|
|
3. Run `stack setup` (if you're running stack for the first time) and
|
|
|
|
`stack install`.
|
|
|
|
4. Make sure `$HOME/.local/bin` is in your `$PATH`.
|
|
|
|
|
|
|
|
[stack]: https://docs.haskellstack.org/en/stable/README/
|
|
|
|
|
|
|
|
### Using cabal
|
|
|
|
|
|
|
|
1. Install [cabal] for your platform.
|
|
|
|
2. Run `cabal install patat`.
|
|
|
|
3. Make sure `$HOME/.cabal/bin` is in your `$PATH`.
|
|
|
|
|
|
|
|
[cabal]: https://www.haskell.org/cabal/
|
|
|
|
|
2016-09-24 10:42:33 +03:00
|
|
|
Running
|
|
|
|
-------
|
|
|
|
|
2016-09-25 12:08:46 +03:00
|
|
|
patat [--watch] presentation.md
|
2016-09-24 10:42:33 +03:00
|
|
|
|
2016-09-24 11:28:57 +03:00
|
|
|
Controls:
|
|
|
|
|
|
|
|
- **Next slide**: `space`, `enter`, `l`, `→`
|
|
|
|
- **Previous slide**: `backspace`, `h`, `←`
|
|
|
|
- **Go forward 10 slides**: `j`, `↓`
|
|
|
|
- **Go backward 10 slides**: `k`, `↑`
|
|
|
|
- **First slide**: `0`
|
|
|
|
- **Last slide**: `G`
|
|
|
|
- **Reload file**: `r`
|
|
|
|
- **Quit**: `q`
|
|
|
|
|
2016-09-25 12:08:46 +03:00
|
|
|
The `r` key is very useful since it allows you to preview your slides while you
|
|
|
|
are writing them. You can also use this to fix artifacts when the terminal is
|
|
|
|
resized.
|
|
|
|
|
|
|
|
If you provide the `--watch` flag, `patat` will watch the presentation file for
|
|
|
|
changes and reload automatically. This is very useful when you are writing the
|
|
|
|
presentation.
|
|
|
|
|
2016-09-24 10:42:33 +03:00
|
|
|
Input format
|
|
|
|
------------
|
|
|
|
|
|
|
|
The input format can be anything that Pandoc supports. Plain markdown is
|
|
|
|
usually the most simple solution:
|
|
|
|
|
|
|
|
---
|
|
|
|
title: This is my presentation
|
|
|
|
author: Jane Doe
|
|
|
|
...
|
|
|
|
|
|
|
|
# This is a slide
|
|
|
|
|
|
|
|
Slide contents. Yay.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
# Important title
|
|
|
|
|
|
|
|
Things I like:
|
|
|
|
|
|
|
|
- Markdown
|
|
|
|
- Haskell
|
|
|
|
- Pandoc
|
|
|
|
|
|
|
|
Horizontal rulers (`---`) are used to split slides.
|
|
|
|
|
|
|
|
However, if you prefer not use these since they are a bit intrusive in the
|
|
|
|
markdown, you can also start every slide with an `h1` header. In that case, the
|
|
|
|
file should not contain a single horizontal ruler.
|
|
|
|
|
|
|
|
This means the following document is equivalent:
|
|
|
|
|
|
|
|
---
|
|
|
|
title: This is my presentation
|
|
|
|
author: Jane Doe
|
|
|
|
...
|
|
|
|
|
|
|
|
# This is a slide
|
|
|
|
|
|
|
|
Slide contents. Yay.
|
|
|
|
|
|
|
|
# Important title
|
|
|
|
|
|
|
|
Things I like:
|
|
|
|
|
|
|
|
- Markdown
|
|
|
|
- Haskell
|
|
|
|
- Pandoc
|
|
|
|
|
2016-10-13 14:26:53 +03:00
|
|
|
Configuration
|
|
|
|
-------------
|
|
|
|
|
|
|
|
`patat` is fairly configurable. The configuration is done using [YAML]. There
|
|
|
|
are two places where you can put your configuration:
|
|
|
|
|
|
|
|
1. In the presentation file itself, using the [Pandoc metadata header].
|
|
|
|
2. In `$HOME/.patat.yaml`
|
|
|
|
|
|
|
|
[YAML]: http://yaml.org/
|
|
|
|
[Pandoc metadata header]: http://pandoc.org/MANUAL.html#extension-yaml_metadata_block
|
|
|
|
|
|
|
|
For example, we can turn on line wrapping by using the following file:
|
|
|
|
|
|
|
|
---
|
|
|
|
title: Presentation with wrapping
|
|
|
|
author: John Doe
|
|
|
|
patat:
|
|
|
|
wrap: true
|
|
|
|
...
|
|
|
|
|
|
|
|
This is a split
|
|
|
|
line which should
|
|
|
|
be re-wrapped.
|
|
|
|
|
|
|
|
Or we can use a normal presentation and have the following `$HOME/.patat.yaml`:
|
|
|
|
|
|
|
|
wrap: true
|
|
|
|
|
2016-11-15 15:11:31 +03:00
|
|
|
### Auto advancing
|
|
|
|
|
|
|
|
By setting `autoAdvanceDelay` to a number of seconds, `patat` will automatically
|
|
|
|
advance to the next slide.
|
|
|
|
|
|
|
|
---
|
|
|
|
title: Auto-advance, yes please
|
|
|
|
author: John Doe
|
|
|
|
patat:
|
|
|
|
autoAdvanceDelay: 2
|
|
|
|
...
|
|
|
|
|
|
|
|
Hello World!
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
This slide will be shown two seconds after the presentation starts.
|
|
|
|
|
2016-11-14 14:55:24 +03:00
|
|
|
### Fragmented slides
|
|
|
|
|
|
|
|
By default, slides are always displayed "all at once". If you want to display
|
|
|
|
them fragment by fragment, there are two ways to do that. The most common
|
|
|
|
case is that lists should be displayed incrementally.
|
|
|
|
|
|
|
|
This can be configured by settings `incrementalLists` to `true` in the metadata
|
|
|
|
block:
|
|
|
|
|
|
|
|
---
|
|
|
|
title: Presentation with incremental lists
|
|
|
|
author: John Doe
|
|
|
|
patat:
|
|
|
|
incrementalLists: true
|
|
|
|
...
|
|
|
|
|
|
|
|
- This list
|
|
|
|
- is displayed
|
|
|
|
- item by item
|
|
|
|
|
|
|
|
Setting `incrementalLists` works on _all_ lists in the presentation. To flip
|
|
|
|
the setting for a specific list, wrap it in a block quote. This will make the
|
|
|
|
list incremental if `incrementalLists` is not set, and it will display the list
|
|
|
|
all at once if `incrementalLists` is set to `true`.
|
|
|
|
|
|
|
|
This example contains a sublist which is also displayed incrementally, and then
|
|
|
|
a sublist which is displayed all at once (by merit of the block quote).
|
|
|
|
|
|
|
|
---
|
|
|
|
title: Presentation with incremental lists
|
|
|
|
author: John Doe
|
|
|
|
patat:
|
|
|
|
incrementalLists: true
|
|
|
|
...
|
|
|
|
|
|
|
|
- This list
|
|
|
|
- is displayed
|
|
|
|
|
|
|
|
* item
|
|
|
|
* by item
|
|
|
|
|
|
|
|
- Or sometimes
|
|
|
|
|
|
|
|
> * all at
|
|
|
|
> * once
|
|
|
|
|
|
|
|
Another way to break up slides is to use a pagraph only containing three dots
|
|
|
|
separated by spaces. For example, this slide has two pauses:
|
|
|
|
|
|
|
|
Legen
|
|
|
|
|
|
|
|
. . .
|
|
|
|
|
|
|
|
wait for it
|
|
|
|
|
|
|
|
. . .
|
|
|
|
|
|
|
|
Dary!
|
|
|
|
|
2016-10-13 14:26:53 +03:00
|
|
|
### Theming
|
|
|
|
|
|
|
|
Colors and other properties can also be changed using this configuration. For
|
|
|
|
example, we can have:
|
|
|
|
|
|
|
|
---
|
|
|
|
author: 'Jasper Van der Jeugt'
|
|
|
|
title: 'This is a test'
|
|
|
|
patat:
|
|
|
|
wrap: true
|
|
|
|
theme:
|
|
|
|
emph: [vividBlue, onVividBlack, bold]
|
|
|
|
imageTarget: [onDullWhite, vividRed]
|
|
|
|
...
|
|
|
|
|
|
|
|
# This is a presentation
|
|
|
|
|
|
|
|
This is _emph_ text.
|
|
|
|
|
|
|
|
![Hello](foo.png)
|
|
|
|
|
|
|
|
The properties that can be given a list of styles are:
|
|
|
|
|
2016-11-04 22:25:13 +03:00
|
|
|
- `blockQuote`
|
2016-10-13 14:26:53 +03:00
|
|
|
- `borders`
|
|
|
|
- `bulletList`
|
2016-11-04 22:25:13 +03:00
|
|
|
- `codeBlock`
|
|
|
|
- `code`
|
2016-10-13 14:26:53 +03:00
|
|
|
- `definitionList`
|
2016-11-04 22:25:13 +03:00
|
|
|
- `definitionTerm`
|
2016-10-13 14:26:53 +03:00
|
|
|
- `emph`
|
2016-11-04 22:25:13 +03:00
|
|
|
- `header`
|
|
|
|
- `imageTarget`
|
|
|
|
- `imageText`
|
2016-10-13 14:26:53 +03:00
|
|
|
- `linkTarget`
|
2016-11-04 22:25:13 +03:00
|
|
|
- `linkText`
|
2016-10-13 14:26:53 +03:00
|
|
|
- `math`
|
2016-11-04 22:25:13 +03:00
|
|
|
- `orderedList`
|
|
|
|
- `quoted`
|
|
|
|
- `strikeout`
|
|
|
|
- `strong`
|
|
|
|
- `tableHeader`
|
|
|
|
- `tableSeparator`
|
2016-10-13 14:26:53 +03:00
|
|
|
|
|
|
|
The accepted styles are:
|
|
|
|
|
|
|
|
- `bold`
|
|
|
|
- `dullBlack`
|
|
|
|
- `dullBlue`
|
|
|
|
- `dullCyan`
|
|
|
|
- `dullGreen`
|
|
|
|
- `dullMagenta`
|
|
|
|
- `dullRed`
|
|
|
|
- `dullWhite`
|
|
|
|
- `dullYellow`
|
|
|
|
- `onDullBlack`
|
|
|
|
- `onDullBlue`
|
|
|
|
- `onDullCyan`
|
|
|
|
- `onDullGreen`
|
|
|
|
- `onDullMagenta`
|
|
|
|
- `onDullRed`
|
|
|
|
- `onDullWhite`
|
|
|
|
- `onDullYellow`
|
|
|
|
- `onVividBlack`
|
|
|
|
- `onVividBlue`
|
|
|
|
- `onVividCyan`
|
|
|
|
- `onVividGreen`
|
|
|
|
- `onVividMagenta`
|
|
|
|
- `onVividRed`
|
|
|
|
- `onVividWhite`
|
|
|
|
- `onVividYellow`
|
|
|
|
- `underline`
|
|
|
|
- `vividBlack`
|
|
|
|
- `vividBlue`
|
|
|
|
- `vividCyan`
|
|
|
|
- `vividGreen`
|
|
|
|
- `vividMagenta`
|
|
|
|
- `vividRed`
|
|
|
|
- `vividWhite`
|
|
|
|
- `vividYellow`
|
|
|
|
|
2016-10-17 14:03:02 +03:00
|
|
|
### Syntax Highlighting
|
|
|
|
|
|
|
|
As part of theming, syntax highlighting is also configurable. This can be
|
|
|
|
configured like this:
|
|
|
|
|
|
|
|
---
|
|
|
|
patat:
|
|
|
|
theme:
|
|
|
|
syntaxHighlighting:
|
|
|
|
decVal: [bold, onDullRed]
|
|
|
|
...
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
`decVal` refers to "decimal values". This is known as a "token type". For a
|
|
|
|
full list of token types, see [this list] -- the names are derived from there in
|
|
|
|
an obvious way.
|
|
|
|
|
|
|
|
[this list]: https://hackage.haskell.org/package/highlighting-kate-0.6.3/docs/Text-Highlighting-Kate-Types.html#t:TokenType
|
|
|
|
|
2016-09-24 10:33:02 +03:00
|
|
|
Trivia
|
|
|
|
------
|
|
|
|
|
2016-09-24 09:45:00 +03:00
|
|
|
_"Patat"_ is the Flemish word for a simple potato. Dutch people also use it to
|
|
|
|
refer to French Fries but I don't really do that -- in Belgium we just call
|
|
|
|
fries _"Frieten"_.
|
2016-09-24 10:33:02 +03:00
|
|
|
|
|
|
|
The idea of `patat` is largely based upon [MDP] which is in turn based upon
|
|
|
|
[VTMC]. I wanted to write a clone using Pandoc because I ran into a markdown
|
|
|
|
parsing bug in MDP which I could not work around. A second reason to do a
|
|
|
|
Pandoc-based tool was that I would be able to use [Literate Haskell] as well.
|
2016-09-24 10:42:33 +03:00
|
|
|
Lastly, I also prefer not to install Node.js on my machine if I can avoid it.
|
2016-09-24 10:33:02 +03:00
|
|
|
|
|
|
|
[MDP]: https://github.com/visit1985/mdp
|
|
|
|
[VTMC]: https://github.com/jclulow/vtmc
|
|
|
|
[Literate Haskell]: https://wiki.haskell.org/Literate_programming
|