diff --git a/CHANGELOG.md b/CHANGELOG.md index d3188d65..9cac32e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,52 @@ +# v0.8.0 - 2024-07-29 + +## Breaking changes + +* Force users to explicitly enable snippet execution ([#276](https://github.com/mfontanini/presenterm/issues/276)) ([#281](https://github.com/mfontanini/presenterm/issues/281)). + +## New features + +* Code snippet execution for various programming languages ([#253](https://github.com/mfontanini/presenterm/issues/253)) ([#255](https://github.com/mfontanini/presenterm/issues/255)) ([#256](https://github.com/mfontanini/presenterm/issues/256)) ([#258](https://github.com/mfontanini/presenterm/issues/258)) ([#282](https://github.com/mfontanini/presenterm/issues/282)). +* Allow executing compiled snippets in windows ([#303](https://github.com/mfontanini/presenterm/issues/303)). +* Add support for hidden lines in code snippets ([#283](https://github.com/mfontanini/presenterm/issues/283)) ([#254](https://github.com/mfontanini/presenterm/issues/254)) - thanks @dmackdev. +* Support [mermaid](https://mermaid.js.org/) snippet rendering to image via `+render` attribute ([#268](https://github.com/mfontanini/presenterm/issues/268)). +* Allow scaling images dynamically based on terminal size ([#288](https://github.com/mfontanini/presenterm/issues/288)) ([#291](https://github.com/mfontanini/presenterm/issues/291)). +* Allow scaling images generated via `+render` code blocks (mermaid, typst, latex) ([#290](https://github.com/mfontanini/presenterm/issues/290)). +* Show `stderr` output from code execution ([#252](https://github.com/mfontanini/presenterm/issues/252)) - thanks @dmackdev. +* Wait for code execution process to exit completely ([#250](https://github.com/mfontanini/presenterm/issues/250)) - thanks @dmackdev. +* Generate images in `+render` code snippets asynchronously ([#273](https://github.com/mfontanini/presenterm/issues/273)) ([#293](https://github.com/mfontanini/presenterm/issues/293)) ([#284](https://github.com/mfontanini/presenterm/issues/284)) ([#279](https://github.com/mfontanini/presenterm/issues/279)). +* Dim non highlighted code snippet lines ([#287](https://github.com/mfontanini/presenterm/issues/287)). +* Shrink snippet execution to match code block width ([#286](https://github.com/mfontanini/presenterm/issues/286)). +* Include code snippet execution output in generated PDF ([#295](https://github.com/mfontanini/presenterm/issues/295)). +* Cache `+render` block images ([#270](https://github.com/mfontanini/presenterm/issues/270)). +* Add kotlin script executor ([#257](https://github.com/mfontanini/presenterm/issues/257)) - thanks @dmackdev. +* Add nushell code execution ([#274](https://github.com/mfontanini/presenterm/issues/274)) ([#275](https://github.com/mfontanini/presenterm/issues/275)) - thanks @PitiBouchon. +* Add rust-script as a new code executor ([#269](https://github.com/mfontanini/presenterm/issues/269)) - @ZhangHanDong. +* Allow custom themes to extend others ([#265](https://github.com/mfontanini/presenterm/issues/265)). +* Allow jumping fast between slides ([#244](https://github.com/mfontanini/presenterm/issues/244)). +* Allow explicitly disabling footer in certain slides ([#239](https://github.com/mfontanini/presenterm/issues/239)). +* Allow using image paths in typst ([#235](https://github.com/mfontanini/presenterm/issues/235)). +* Add JSON schema for validation,completion,documentation ([#228](https://github.com/mfontanini/presenterm/issues/228)) ([#236](https://github.com/mfontanini/presenterm/issues/236)) - thanks @mikavilpas. +* Allow having multiple authors ([#227](https://github.com/mfontanini/presenterm/issues/227)). + +## Fixes + +* Avoid re-rendering code output and auto rendered blocks ([#280](https://github.com/mfontanini/presenterm/issues/280)). +* Use unicode width to calculate execution output's line len ([#261](https://github.com/mfontanini/presenterm/issues/261)). +* Display background color behind '\t' in code exec output ([#245](https://github.com/mfontanini/presenterm/issues/245)). +* Close child process stdin by default ([#297](https://github.com/mfontanini/presenterm/issues/297)). + +## Improvements + +* Update install instructions for Arch Linux ([#248](https://github.com/mfontanini/presenterm/issues/248)) - thanks @orhun. +* Fix all clippy warnings ([#231](https://github.com/mfontanini/presenterm/issues/231)) - thanks @mikavilpas. +* Include strict `_front_matter_parsing` in default config ([#229](https://github.com/mfontanini/presenterm/issues/229)) - thanks @mikavilpas. +* `CHANGELOG.md` contains clickable links to issues ([#230](https://github.com/mfontanini/presenterm/issues/230)) - thanks @mikavilpas. +* Add Support for Ruby Code Highlighting ([#226](https://github.com/mfontanini/presenterm/issues/226)) - thanks @pranavrao145. +* Use ".presenterm" as prefix for tmp files ([#306](https://github.com/mfontanini/presenterm/issues/306)). +* Add more descriptive error message when loading image fails ([#298](https://github.com/mfontanini/presenterm/issues/298)). +* Align all error messages to left ([#301](https://github.com/mfontanini/presenterm/issues/301)). + # v0.7.0 - 2024-03-02 ## New features diff --git a/Cargo.lock b/Cargo.lock index 53da1b3a..dd7a6574 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,7 +868,7 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "presenterm" -version = "0.7.0" +version = "0.8.0" dependencies = [ "base64", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 26c4d6d2..39f7f2c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ authors = ["Matias Fontanini"] description = "A terminal slideshow presentation tool" repository = "https://github.com/mfontanini/presenterm" license = "BSD-2-Clause" -version = "0.7.0" +version = "0.8.0" edition = "2021" [dependencies] diff --git a/README.md b/README.md index d7bebefe..7ba9bd62 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,11 @@ Visit the [documentation][guide-introduction] to get started. * Code highlighting for a [wide list of programming languages][guide-code-highlight]. * [Selective/dynamic][guide-selective-highlight] code highlighting that only highlights portions of code at a time. * [Column layouts][guide-layout]. +* [mermaid graph rendering](guide-mermaid). * [_LaTeX_ and _typst_ formula rendering][guide-latex]. * [Introduction slide][guide-intro-slide] that displays the presentation title and your name. * [Slide titles][guide-slide-titles]. -* [Shell code execution][guide-code-execute]. +* [Snippet execution][guide-code-execute] for various programming languages. * [Export presentations to PDF][guide-pdf-export]. * [Pause][guide-pauses] portions of your slides. * [Custom key bindings][guide-key-bindings]. @@ -63,6 +64,7 @@ See the [introduction page][guide-introduction] to learn more. [guide-code-execute]: https://mfontanini.github.io/presenterm/guides/code-highlight.html#executing-code [guide-selective-highlight]: https://mfontanini.github.io/presenterm/guides/code-highlight.html#selective-highlighting [guide-layout]: https://mfontanini.github.io/presenterm/guides/layout.html +[guide-mermaid]: https://mfontanini.github.io/presenterm/guides/mermaid.html [guide-latex]: https://mfontanini.github.io/presenterm/guides/latex.html [guide-pdf-export]: https://mfontanini.github.io/presenterm/guides/pdf-export.html [guide-key-bindings]: https://mfontanini.github.io/presenterm/guides/configuration.html#key-bindings diff --git a/config.sample.yaml b/config.sample.yaml index 101f5768..afcbb79d 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -13,6 +13,10 @@ typst: # the pixels per inch when rendering latex/typst formulas. ppi: 300 +mermaid: + # the scale parameter passed to the mermaid CLI (mmdc). + scale: 2 + options: # whether slides are automatically terminated when a slide title is found. implicit_slide_ends: false @@ -31,6 +35,15 @@ options: # whether to treat a thematic break as a slide end. end_slide_shorthand: false +snippet: + exec: + # enable code snippet execution. Use at your own risk! + enable: true + + render: + # the number of threads to use when rendering `+render` code snippets. + threads: 2 + bindings: # the keys that cause the presentation to move forwards. next: ["l", "j", "", "", "", " "] diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index b74410fe..40ae8b1f 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -11,6 +11,7 @@ - [Configuration](./guides/configuration.md) - [Code highlighting](./guides/code-highlight.md) - [PDF export](./guides/pdf-export.md) +- [Mermaid](./guides/mermaid.md) - [LaTeX and typst](./guides/latex.md) # Internals diff --git a/docs/src/guides/basics.md b/docs/src/guides/basics.md index 213a49cc..b68bfb7b 100644 --- a/docs/src/guides/basics.md +++ b/docs/src/guides/basics.md @@ -53,13 +53,25 @@ cargo build --release --features sixel Things you should know when using image tags in your presentation's markdown are: * Image paths are relative to your presentation path. That is a tag like `![](food/potato.png)` will be looked up at `$PRESENTATION_DIRECTORY/food/potato.png`. -* Images will be rendered in their original size. That is, if your terminal is 300x200px and your image is 200x100px, it - will take up 66% of your horizontal space and 50% of your vertical space. +* Images will be rendered by default in their original size. That is, if your terminal is 300x200px and your image is +200x100px, it will take up 66% of your horizontal space and 50% of your vertical space. * The exception to the point above is if the image does not fit in your terminal, it will be resized accordingly while preserving the aspect ratio. * If your terminal does not support any of the graphics protocol above, images will be rendered using ascii blocks. It ain't great but it's something! +#### Image size + +The size of each image can be set by using the `image:width` or `image:w` attributes in the image tag. For example, the +following will cause the image to take up 50% of the terminal width: + +```markdown +![image:width:50%](image.png) +``` + +The image will always be scaled to preserve its aspect ratio and it will not be allowed to overflow vertically nor +horizontally. + #### Protocol detection By default the image protocol to be used will be automatically detected. In cases where this detection fails (e.g. when diff --git a/docs/src/guides/code-highlight.md b/docs/src/guides/code-highlight.md index 7d14de24..9d989de3 100644 --- a/docs/src/guides/code-highlight.md +++ b/docs/src/guides/code-highlight.md @@ -59,7 +59,7 @@ Code highlighting is supported for the following languages: If you would like line numbers to be shown on the left of a code block use the `+line_numbers` switch after specifying the language in a code block: -~~~ +~~~markdown ```rust +line_numbers fn hello_world() { println!("Hello world"); @@ -72,7 +72,7 @@ the language in a code block: By default, the entire code block will be syntax-highlighted. If instead you only wanted a subset of it to be highlighted, you can use braces and a list of either individual lines, or line ranges that you'd want to highlight. -~~~ +~~~markdown ```rust {1,3,5-7} fn potato() -> u32 { // 1: highlighted // 2: not highlighted @@ -91,7 +91,7 @@ code block are highlighted every time you move to the next/previous slide. This is achieved by using the separator `|` to indicate what sections of the code will be highlighted at a given time. -~~~ +~~~markdown ```rust {1,3|5-7} fn potato() -> u32 { @@ -109,26 +109,85 @@ presentations where you can display sections of the code to explain something sp See this real example of how this looks like. -[![asciicast](https://asciinema.org/a/dpXDXJoJRRX4mQ7V6LdR3rO2z.svg)](https://asciinema.org/a/dpXDXJoJRRX4mQ7V6LdR3rO2z) +[![asciicast](https://asciinema.org/a/iCf4f6how1Ux3H8GNzksFUczI.svg)](https://asciinema.org/a/iCf4f6how1Ux3H8GNzksFUczI) -### Executing code +### Executing code blocks -Annotating a shell code block with a `+exec` switch will make it executable. Once you're in a slide that contains an +Annotating a code block with a `+exec` attribute will make it executable. Once you're in a slide that contains an executable block, press `control+e` to execute it. The output of the execution will be displayed on a box below the code. The code execution is stateful so if you switch to another slide and then go back, you will still see the output. -~~~ +~~~markdown ```bash +exec echo hello world ``` ~~~ -Note that using `bash`, `zsh`, `fish`, etc, will end up using that specific shell to execute your script. +Code execution **must be explicitly enabled** by using either: -[![asciicast](https://asciinema.org/a/gnzjXpVSOwOiyUqQvhi0AaHG7.svg)](https://asciinema.org/a/gnzjXpVSOwOiyUqQvhi0AaHG7) +* The `-x` command line parameter when running _presenterm_. +* Setting the `snippet.exec.enable` property to `true` in your [_presenterm_ config +file](configuration.html#snippet-execution). + +--- + +The list of languages that support execution are: + +* bash +* c++ +* c +* fish +* go +* java +* js +* kotlin +* lua +* nushell +* perl +* python +* ruby +* rust-script +* rust +* sh +* zsh + +If there's a language that is not in this list and you would like it to be supported, please [create an +issue](https://github.com/mfontanini/presenterm/issues/new) providing details on how to compile (if necessary) and run +snippets for that language. You can also configure how to run code snippet for a language locally in your [config +file](configuration.html#custom-snippet-executors). + +[![asciicast](https://asciinema.org/a/BbAY817esxagCgPtnKUwgYnHr.svg)](https://asciinema.org/a/BbAY817esxagCgPtnKUwgYnHr) > **Note**: because this is spawning a process and executing code, you should use this at your own risk. +### Hiding code lines + +When you mark a code snippet as executable via the `+exec` flag, you may not be interested in showing _all the lines_ to +your audience, as some of them may not be necessary to convey your point. For example, you may want to hide imports, +non-essential functions, initialization of certain variables, etc. For this purpose, _presenterm_ supports a prefix +under certain programming languages that let you indicate a line should be executed when running the code but should not +be displayed in the presentation. + +For example, in the following code snippet only the print statement will be displayed but the entire snippet will be +ran: + +~~~markdown +```rust +# fn main() { +println!("Hello world!"); +# } +``` +~~~ + +Rather than blindly relying on a prefix that may have a meaning in a language, prefixes are chosen on a per language +basis. The languages that are supported and their prefix is: + +* rust: `# `. +* python/bash/fish/shell/zsh/kotlin/java/javascript/typescript/c/c++/go: `/// `. + +This means that any line in a rust code snippet that starts with `# ` will be hidden, whereas all lines in, say, a +golang code snippet that starts with a `/// ` will be hidden. + ### Pre-rendering Some languages support pre-rendering. This means the code block is transformed into something else when the presentation @@ -136,4 +195,4 @@ is loaded. The languages that currently support this are _LaTeX_ and _typst_ whe transformed into an image, allowing you to define formulas as text in your presentation. This can be done by using the `+render` attribute on a code block. -See the [LaTeX and typst docs](latex.html) for more information. +See the [LaTeX and typst](latex.html) and [mermaid](mermaid.html) docs for more information. diff --git a/docs/src/guides/configuration.md b/docs/src/guides/configuration.md index cf4cdd3e..e2ad127f 100644 --- a/docs/src/guides/configuration.md +++ b/docs/src/guides/configuration.md @@ -151,6 +151,21 @@ potato: 42 # Hi ``` +### image_attributes_prefix + +The [image size](basics.html#image-size) prefix (by default `image:`) can be configured to be anything you would want in +case you don't like the default one. For example, if you'd like to set the image size by simply doing +`![width:50%](path.png)` you would need to set: + +``` +--- +options: + image_attributes_prefix: "" +--- + +![width:50%](path.png) +``` + ## Defaults Defaults **can only be configured via the configuration file**. @@ -243,3 +258,78 @@ bindings: You can choose to override any of them. Keep in mind these are overrides so if for example you change `next`, the default won't apply anymore and only what you've defined will be used. + +## Snippet configurations + +### Snippet execution + +Snippet execution is disabled by default for security reasons. Besides passing in the `-x` command line parameter every +time you run _presenterm_, you can also configure this globally for all presentations by setting: + +```yaml +snippet: + exec: + enable: true +``` + +**Use this at your own risk**, especially if you're running someone else's presentations! + +### Custom snippet executors + +If _presenterm_ doesn't support executing code snippets for your language of choice, please [create an +issue](https://github.com/mfontanini/presenterm/issues/new)! Alternatively, you can configure this locally yourself by +setting: + +```yaml +snippet: + exec: + custom: + # The keys should be the language identifier you'd use in a code block. + c++: + # The name of the file that will be created with your snippet's contents. + filename: "snippet.cpp" + + # A list of environment variables that should be set before building/running your code. + environment: + MY_FAVORITE_ENVIRONMENT_VAR: foo + + # A list of commands that will be ran one by one in the same directory as the snippet is in. + commands: + # Compile if first + - ["g++", "-std=c++20", "snippet.cpp", "-o", "snippet"] + # Now run it + - ["./snippet"] +``` + +The output of all commands will be included in the code snippet execution output so if a command (like the `g++` +invocation) was to emit any output, make sure to use whatever flags are needed to mute its output. + +Also note that you can override built-in executors in case you want to run them differently (e.g. use `c++23` in the +example above). + +See more examples in the [executors.yaml](https://github.com/mfontanini/presenterm/blob/master/executors.yaml) file +which defines all of the built-in executors. + +### Snippet rendering threads + +Because some `+render` code blocks can take some time to be rendered into an image, especially if you're using +[mermaid](https://mermaid.js.org/) charts, this is run asychronously. The number of threads used to render these, which +defaults to 2, can be configured by setting: + +```yaml +snippet: + render: + threads: 2 +``` + +### Mermaid scaling + +[mermaid](https://mermaid.js.org/) graphs will use a default scaling of `2` when invoking the mermaid CLI. If you'd like +to change this use: + + +```yaml +mermaid: + scale: 2 +``` + diff --git a/docs/src/guides/latex.md b/docs/src/guides/latex.md index fd0c0461..185cb2f3 100644 --- a/docs/src/guides/latex.md +++ b/docs/src/guides/latex.md @@ -37,6 +37,17 @@ typst: The default is 300 so adjust it and see what works for you. +### Controlling the image size + +You can also set the generated image's size on a per code snippet basis by using the `+width` modifier which specifies +the width of the image as a percentage of the terminal size. + +~~~markdown +```typst +render +width:50% +$f(x) = x + 1$ +``` +~~~ + ### Customizations The colors and margin of the generated images can be defined in your theme: diff --git a/docs/src/guides/mermaid.md b/docs/src/guides/mermaid.md new file mode 100644 index 00000000..5b13aff6 --- /dev/null +++ b/docs/src/guides/mermaid.md @@ -0,0 +1,37 @@ +# Mermaid + +[mermaid](https://mermaid.js.org/) snippets can be converted into images automatically in any code snippet tagged with +the `mermaid` language and a `+render` tag: + +~~~markdown +```mermaid +render +sequenceDiagram + Mark --> Bob: Hello! + Bob --> Mark: Oh, hi mark! +``` +~~~ + +**This requires having [mermaid-cli](https://github.com/mermaid-js/mermaid-cli) installed**. + +Note that because the mermaid CLI will spin up a browser under the hood, this may not work in all environments and can +also be a bit slow (e.g. ~2 seconds to generate every image). Mermaid graphs are rendered asynchronously by a number of +threads that can be configured in the [configuration file](configuration.html#snippet-rendering-threads). This +configuration value currently defaults to 2. + +The size of the rendered image can be configured by changing: +* The `mermaid.scale` [configuration parameter](configuration.html#mermaid-scaling). +* Using the `+width:%` attribute in the code snippet. + +For example, this diagram will take up 50% of the width of the window and will preserve its aspect ratio: + +~~~markdown +```mermaid +render +width:50% +sequenceDiagram + Mark --> Bob: Hello! + Bob --> Mark: Oh, hi mark! +``` +~~~ + +It is recommended to change the `mermaid.scale` parameter until images look big enough and then adjust on an image by +image case if necessary using the `+width` attribute. Otherwise, using a small scale and then scaling via `+width` may +cause the image to become blurry. diff --git a/examples/code.md b/examples/code.md index 48bfff4f..45101e93 100644 --- a/examples/code.md +++ b/examples/code.md @@ -78,22 +78,21 @@ fn main() { -Code execution +Snippet execution === -Run commands from the presentation and display their output dynamically. +Run code snippets from the presentation and display their output dynamically. -```bash +exec -for i in $(seq 1 5) -do - echo "hi $i" - sleep 0.5 -done +```python +exec +/// import time +for i in range(0, 5): + print(f"count is {i}") + time.sleep(0.5) ``` -Code execution - `stderr` +Snippet execution - `stderr` === Output from `stderr` will also be shown as output. @@ -106,4 +105,4 @@ sleep 0.5 echo "This is a successful command again" sleep 0.5 man # Missing argument -``` \ No newline at end of file +``` diff --git a/examples/demo.md b/examples/demo.md index 2331a3be..7c8dd5f8 100644 --- a/examples/demo.md +++ b/examples/demo.md @@ -138,17 +138,26 @@ impl Person { -Shell code execution +Snippet execution --- -Run commands from the presentation and display their output dynamically. - -```bash +exec -for i in $(seq 1 5) -do - echo "hi $i" - sleep 0.5 -done +Code snippets can be executed: + +* For various languages, including compiled ones. +* Their output is shown in real time. +* Unimportant lines can be hidden so they don't clutter what you're trying to convey. +* By default by pressing ``. + +```rust +exec +# use std::thread::sleep; +# use std::time::Duration; +fn main() { + let names = ["Alice", "Bob", "Eve", "Mallory", "Trent"]; + for name in names { + println!("Hi {name}!"); + sleep(Duration::from_millis(500)); + } +} ```