Giter Site home page Giter Site logo

nelsie's Introduction

Nelsie

Build

Nelsie allows you to create slides programmatically using Python. It is a library with a Python API and a renderer written in Rust. The output is a PDF file or a set of SVG/PNG files.

There is no DSL or GUI; presentations created with Nelsie are fully programmed in Python. We believe that creating presentations in a programmable way makes the process of creating slides smoother and more reliable.

Nelsie focuses on controlling what the audience sees, so you can continuously reveal fragments of the slide, or simply manage which parts are highlighted.

Quick links

Installation

$ pip install nelsie

Hello world

from nelsie import SlideDeck

deck = SlideDeck()

@deck.slide()
def hello_world(slide):
    slide.text("Hello world!")

deck.render("slides.pdf")

Steps revealing

Nelsie allows you to easily reveal parts of slides:

@deck.slide()
def steps_demo(slide):
    semaphore = slide.box(width=100, height=300, bg_color="gray")
    semaphore.box(
        y=InSteps([20, 110, 210]),  # Set "y" coordinate for each step
        width=80,
        height=80,
        bg_color=InSteps(["red", "orange", "green"]),  # Set color for each step
    )

    slide.code(
        """
fn main() {
    // Print text to the console.
    println!()"Hello World!");
}
""",
        "Rust",
        show=4,  # Show in 4. step
        m_top=80,
    )

The code generates four PDF pages:

nelsie's People

Contributors

spirali avatar fgelm01 avatar galenseilis avatar

Stargazers

 avatar Marek Pšenka avatar David Brownman avatar Nikolai Skvortsov avatar zurgl avatar Marc G avatar 29 avatar  avatar  avatar Mike Tang avatar Sven avatar Alexander Clausen avatar  avatar A Dinesh avatar Muhammad Rafay Awan avatar Vyomkesh  avatar Erlend Sogge Heggen avatar Gerrit Proessl avatar Nicolas Boisseau avatar Rhys Evans avatar  avatar Benoit de Chezelles avatar Dominik Kundra avatar Jan Bednář avatar  avatar Ondrej Telka avatar Jerry avatar  avatar Juraj Michálek avatar  avatar Vladislav Mamon avatar Kamil Sindi avatar  avatar houseme avatar  avatar Damien Mannion avatar Vojtech Kral avatar Benoît Laurent avatar Martin Šurkovský avatar Ben Chuanlong Du avatar Jakub Beránek avatar

Watchers

 avatar Martin Šurkovský avatar  avatar  avatar

nelsie's Issues

Text with inline styles disappears from pdf.

When using text, certain combinations of inline styles and text contents cause the text to not appear in the generated pdf file.

I can't discern a pattern in what strings cause this, but it doesn't happen when parse_styles=False.

Here's a minimal example:

import nelsie

deck = nelsie.SlideDeck(width=320, height=240)

@deck.slide()
def _(slide: nelsie.Slide) -> None:
    s = "~monospace{s} specifi"
    slide.text(s, parse_styles=False, bg_color="#fa8080")
    slide.text(s, parse_styles=True, bg_color="#80fa80")

deck.render("repro", "svg")

0-0-1

The cut-off is expected due to slide deck dimensions being small. But the second line looks very strange in the .svg and doesn't appear at all in the .pdf.

This is using version 0.6.0

Support responsive scaling

It is useful to have the ability to re-scale the whole slide deck to a different resolution and/or ratio (e.g. 4:3, 16:9, etc.). While this can be done manually in the Python code, e.g. like this:

foo.box(width=scale_width(500), height=scale_height(500))

The way I do it is that I have some reference resolution (e.g. FullHD), against which I code the contents of my slides, and then some actual resolution, which is rendered by elsie. Before rendering, I recompute all of the values essentially just by dividing FullHD with the actual resolution, to get the final scaled value. In this way I can modify the target render resolution with a one-line change, without modifying the contents of the slides.

However, it is a bit annoying if we have to scale all the values of presentations with my own functions everywhere.

It would be nice if there was some was to hook into nelsie, so that we could automatically rescale all values, like X, Y, width, height etc., before rendering, or if nelsie had this built-in, so that you could specify a source (logical) resolution, and a target render resolution.

A related alternative is to allow specifying all values as relative, e.g. as percentages.

Allow specifying a default resource directory

It would be nice to allow specifying a default directory where e.g. images will be searched (potentially even multiple directories, with a priority, but one should be enough). Essentially the equivalent of the LaTex \graphicspath{{}} command. It should help to avoid repeating e.g. imgs or images in all image paths.

[Feature Request] : Helper to build tables with separators?

As a data scientist, I often need to give tables of values in my presentations.

I looked at some related issues and documentation:

I tried this example (migrated to Nelsie from the Elsie documentation):

@deck.slide()
def another_table(slide):
    row_count = 2
    column_count = 3

    for r in range(row_count):
        row = slide.box(row=True, p_bottom=10)
        for c in range(column_count):
            box = row.box(width=100, height=100, p_right=10)
            box.text(f"({r}, {c})", TextStyle(color="black"))

It created a grid of entries, which is a good start!

image

I would like it to be relatively easy to make something like this (image taken from Google images):
image

Similar to tabular in LaTeX, it is possible to declare where line separators exist among the rows and columns.

I'm not sure what the Nelsie-idiomatic way to do this is.

Would it be possible to implement a function that assists in putting together tables with separators?

Variable-weight fonts not always working

It seems that for some variable-weight fonts, weight argument is ignored.
At first sight, it is some upstream crate problem. As it also hints "Karla" font used in bigdemo, #51 added static weight fonts for bigdemo. However it may also be the root cause of the font problem in #32.

Need more investigation.

Hyperlink support

Thank you for creating Nelsie. It's very useful and fast.

Please, could you give a hint how to create a hyperlink?
I was searching the documentation for keyboards like: link, href, hyperlink.
Could you provide snippet of code with link to https?

List counting trough multiple pages

There is (afaik) no way to continue numbered lists across multiple pages.

When using "counters" parameter q_lst = ListBox(b, list_type="1", counters=[0]) , there is weird behaviour with appending [0] to the end of counters. Which results in counting restart.
First i thought it has something with nesting lists, but it does not seem to be the case.

Is there a propper way to continue list on next slide (not show part) ? Or even better, an option to set starting number when using numbered lists ?

flex_grow not working as expected inside nested boxes.

When using flex_grow=1 on a nested box, that box does not grow to take up remaining space. Instead it is sized just large enough to fit its content, or completely invisible if there is no content.

Consider this example:

from nelsie import Slide, SlideDeck

slides = SlideDeck(width=100, height=100)


@slides.slide()
def slide1(slide: Slide) -> None:
    slide.box(width=40, height=25, bg_color="#ff0000")
    slide.box(width=40, flex_grow=1, bg_color="#00ff00")
    slide.box(width=40, height=25, bg_color="#0000ff")

I expect a red box sized 40x25, a green box sized 40x50, and a blue box sized 40x25. That's exactly what happens.
0-1

But not when I try to do the same thing in a more deeply nested box:

@slides.slide()
def slide2(slide: Slide) -> None:
    parent = slide.box(row=True)

    left = parent.box()
    right = parent.box()

    left.box(width=40, height=25, bg_color="#ff6060")
    left.box(width=40, flex_grow=1, bg_color="#60ff60")
    left.box(width=40, height=25, bg_color="#6060ff")

    right.box(width=40, height=25, bg_color="#df4040")
    right.box(width=40, flex_grow=1, bg_color="#40df40")
    right.box(width=40, height=25, bg_color="#4040df")

I expect two versions of the same arrangement as above, side by side. But that's not what happens.
1-1

[Feature Request] Mathjax or equivalent

I often use Beamer (LaTeX) for producing slides, but this is somewhat disjoint from my work with Python. Of course I can write Python which generates strings so some amount of automation has been possible on that front, but I would prefer something like Nelsie if it could simply part of the source code of my projects to generate slides where all the instructions I write are within Python.

Is there any plausibility to having something roughly equivalent to LaTeX's math or MathJAX implemented in Nelsie?

SVG files with DTD schema cannot be loaded

SVG images exported from DrawIO cannot be used in nelsie because of DTD shema.
Its probably an issue within some upstream packages ?

Resulting: error
Traceback (most recent call last):
File "C:\School\bachelor_mics\presentation\main.py", line 115, in
@deck.slide()
^^^^^^^^^^^^
File "C:\School\bachelor_mics\presentation\venv\Lib\site-packages\nelsie\slidedeck.py", line 181, in helper
fn(slide)
File "C:\School\bachelor_mics\presentation\main.py", line 120, in applicationStructure_2
b.image("img/frontend_1.drawio.svg", enable_steps=True, width="100%")
File "C:\School\bachelor_mics\presentation\venv\Lib\site-packages\nelsie\box.py", line 107, in image
return self.box(_content=image, **box_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\School\bachelor_mics\presentation\venv\Lib\site-packages\nelsie\box.py", line 307, in box
box_id, node_id = deck._deck.new_box(
^^^^^^^^^^^^^^^^^^^
Exception: Image 'C:\School\bachelor_mics\presentation\img\frontend_1.drawio.svg' load error: XML with DTD detected

Easy, but surely not correct fix is to remove !Doctype tag from svg file.

Grid Layout for Images - Box size inheritance not working?

Hi,
I am trying to produce something like the attached image (Fig. 1) essentially a slide with a 3x3 grid of images, with a title. I say this in case there is a much easier way to obtain this layout, and the issue I am experiencing is not an issue at all!

As a test, I am trying to create a 2x2 grid, using nested boxes:

@deck.slide() 
def test(slide): 
  row1 = slide.box(row=True) 
  row2 = slide.box(row=True) 
  row1.image("image/path.png") 
  row1.image("image/path.png")
  row2.image("image/path.png") 
  row2.image("image/path.png")

This produces the output in Fig. 2, where the images are aligned in a grid but only a small portion is showing.

If I try to fix the heights, even very small ones, the images overlap as seen in Fig. 3.

@deck.slide() 
def test(slide): 
  row1 = slide.box(row=True, height=100) 
  row2 = slide.box(row=True, height=100) 
  row1.image("image/path.png") 
  row1.image("image/path.png")
  row2.image("image/path.png") 
  row2.image("image/path.png")

If I individually set the height and width to "50%" for all the .image() lines, then the slide is completely blank!

My questions are:

  1. Is there an easier way to do this that I am missing?
  2. Within the current boxes-within-boxes setup, how do I get it so that the images are all arranged evenly on the slide, or is there an error somewhere like the child boxes are not properly inheriting the total size from the parent?
  3. In the future, is there the possibility of having a set grid layout e.g. akin to matplotlib's subplot where you can create and populate a grid of boxes?

Fig. 1 - Intended Output:
example

Fig. 2 - Slide without heights specified:
image

Fig. 3 - Slide with heights specified:
image

[Question]: How should I compare Nelsie to Elsie?

I notice that there is another package you have created called "Elsie" that seems to have similar goals/scope but with different rendering dependencies.

I happen to like Python and Rust, so either seems good to me... But how should I compare these two packages? What do the use cases look like under one vs the other?

PDF size increased between v0.6 and v0.8

The size of the generated PDF for the same input increased between version 0.6 and 0.8. With 0.6, the pdf size was 12MB. With 0.8, it is 19MB.

I also noticed that some fonts look different now.

v0.6:
image
v0.8:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.