Lists#
Lists of items are very common in presentations, and they come in all sorts of forms and shapes. That makes it quite difficult to find a general abstraction that could be used to create an arbitrary list. At the same time, often you just want a quick way to create a simple list, without bells and whistles.
For that reason, Elsie does not provide direct list support in its core, but it provides a set of
helper utilities for creating lists. They are located in the elsie.ext
module, which
contains opinionated extensions on top of the Elsie core. If the helper utilities fit your needs,
feel free to use them. If not, you can just implement your own functions for creating lists in
your presentations.
Creating lists#
To create a list, you can use either the unordered_list
or the ordered_list
function. Simply pass it a parent box which
will contain the list and then use the returned object to create new list items with the
item
method:
from elsie.ext import unordered_list
lst = unordered_list(slide.box())
lst.item().text("Item 1")
lst.item().text("Item 2")
lst.item().text("Item 3")
You can also pass several useful options to these functions:
indent
: Default horizontal gap between individual indentation levelslabel_padding
: Horizontal padding between the item label and its contentlabel
: Either a string or a function that will be used to render the label of each item.start
(only forordered_list
): The sequence number at which will the ordered list start.- Any additional keyword arguments passed to these functions will be passed to the box created for each list item.
The only difference between ordered and unordered lists is the render function of their label. By
default, unordered lists have a constant bullet point used as a label (•
). The label of an
ordered list is rendered as a sequence of arabic numbers joined with a dot (e.g. 1.3.2
). You
can change the label with the label
parameter.
Nesting lists#
Both unordered_list
and ordered_list
return an object which holds a list of counter values, one
for each nesting level. Each call of the item
method will create a new item in the list and
increment the value of the last counter in the list.
A top level list is not nested, so it only has a single counter.
You can call the ul
or ol
method to create an unordered, respectively ordered nested (indented) sublist. By default, the
last counter value if the new sublist will start at 1
, but you can override this with the
start
parameter for ordered lists.
from elsie.ext import ordered_list
lst = ordered_list(slide.box())
lst.item().text("Item 1") # Counters of lst = [1]
l2 = lst.ol() # Counters of l2 = [1, 1]
l2.item().text("Nested item 1") # Counters of l2 = [1, 2]
l2.item().text("Nested item 2")
l3 = l2.ol(start=4) # Counters of l3 = [1, 2, 4]
l3.item().text("Nested item 3")
lst.item().text("Item 2") # Counters of lst = [2]
If you use a function to render the label of your list items, it will be passed a Box which should be filled with the label content and also a list of counter values for the specific list item. This is especially useful for ordered lists:
from elsie.ext import ordered_list
def render_label(box, counters):
style = elsie.TextStyle()
if len(counters) == 1: # Top-level label
style.bold = True
box.text(".".join(str(c) for c in counters), style=style)
lst = ordered_list(slide.box(), label=render_label)
lst.item().text("Item 1")
l2 = lst.ol(label=render_label)
l2.item().text("Nested item 1")
l2.item().text("Nested item 2")
lst.item().text("Item 2")
You can also pass additional parameters to the ul
and ol
methods to override the default
properties of the sublist (such as its label). Note that the label is not inherited by the sublist
from the parent. For convenience, you can also use (sub)lists with the with
keyword to create
visually indented blocks (this is purely visual, it does not change the behaviour of the list in
any way):
from elsie.ext import unordered_list
lst = unordered_list(slide.box())
lst.item().text("Item 1")
with lst.ul(label="-") as l2:
l2.item().text("Nested item 1")
l2.ul().item().text("Nested item 2") # The label here is not inherited
lst.item().text("Item 2")
Revealing#
Using revealing, you can easily create a list of items that will
be revealed gradually. If you do not set the show
key in the default box arguments for a list,
it will use show="last+"
, which is handy for showing indented items at the same time as their
parent item:
from elsie.ext import unordered_list
lst = unordered_list(slide.box())
lst.item().text("Appears in fragment 1")
lst.item(show="next+").text("Appears in fragment 2")
lst.ul().item().text("(nested) Appears in fragment 2")
lst.item(show="next+").text("Appears in fragment 3")