Abdul Saboor1
Aug 01, 2025
1My University is somewhere in the middle of nowhere
section`Introduction`
```multicol .block-green
toc[True]`## Table of contents`
+++
### This is summary of current section
Oh we can use inline columns stack`Column A || Column B` here and what not!
%{btn}
```
(extensions=[], **settings)
Interactive Slides in IPython Notebook. Only one instance can exist. settings
are passed to Slides.settings()
if you like to set during initialization. You
can also edit file .ipyslides-assets/settings.json to make settings persistent across sessions
and load/sync them via GUI in sidepanel.
To suppress unwanted print from other libraries/functions, use:
with slides.suppress_stdout():
some_function_that_prints() # This will not be printed
print('This will not be printed either')
display('Something') # This will be printed
The traitlets callables under settings returns settings back to enable chaining
without extra typing, like Slides.settings.logo().layout()...
.
Slides.instance()
class method to keep older settings. Slides()
apply default settings every time.slides.demo()
to see a demo of some features.slides.docs()
to see documentation.Slides.create
is much faster than adding them one by one.Create New View for Output
for optimized display.Windowing mode
in Notebook settings to defer
or none
.Slides.xmd_syntax
for extended markdown syntax, especially variables formatting.Slides.fmt
to pick variables from local scope.Slides
can be indexed same way as list for sorted final indices. For indexing slides with given number, use comma as Slides[number,] -> Slide
or access many via list as Slides[[n1,n2,..]] -> tuple[Slide]
. Use indexing with given number to apply persistent effects such as CSS.
(label, back_label=None, icon=None, back_icon=None)
Create a link to jump to another slide. Use label
for link text
and back_label
for the optional text on the target slide if need to jump back.
link.origin
to create a link to jump to target slide where link.target
is placed.link.target
will be able to jump back to the link.origin
.%{link.origin}
and %{link.target}
to display links.
skipper = self.link('Skip to dynamic content', 'Back to link info', icon='arrow', back_icon='arrowl')
skipper.origin.display() # skipper.target is set later somewhere, can do backward jump too
Besides function below, you can add slides with %%slide number [-m]
magic as well.
(slide_number, /, content=None)
Build slides with a single unified command in three ways:
slides.build(number, callable)
to create a slide from a callable(slide)
immediately, e.g. lambda s: slides.write(1,2,3)
or as a decorator.with slides.build(number):
creates single slide. Equivalent to %%slide number
magic.fsep()
from top import or Slides.fsep()
to split content into frames.for item in fsep.iter(iterable):
block to automatically add frame separator.fsep(True)
/ fsep.iter(...,stack=True)
to join content of frames incrementally.slides.build(number, str | fmt)
creates many slides with markdown content. Equivalent to %%slide number -m
magic in case of one slide.--
and slides separator is triple dashes ---
. Same applies to Slides.sync_with_file
too.%++
to join content of frames incrementally.multicol
before --
creates incremental columns if %++
is provided.slides.xmd_syntax
for extended markdown usage.Slides.sync_with_file
too.var
in notebook.fmt(str, **kwargs)
, varaiables are picked from kwargs
or local scope and can't be changed later. Useful in python scripts.number
could be used as -1
.integer in px
in markdown or Slides.this.yoffset(integer)
to make all frames align vertically to avoid jumps in increments.build_(...)
(with underscore at end) in python file instead of build(-1,...)
.(start_slide_number, /, path, interval=500)
Auto update slides when content of markdown file changes. You can stop syncing using Slides.unsync
function.
interval is in milliseconds, 500 ms default. Read Slides.build
docs about content of file.
The variables inserted in file content are used from top scope.
You can add files inside linked file using include\`file_path.md\` syntax, which are also watched for changes.
This helps modularity of content, and even you can link a citation file in markdown format as shown below. Read more in Slides.xmd_syntax
about it.
```citations footnote
@key1: Saboor et. al., 2025
@key2: A citations can span multiple lines, but key should start on new line
<!-- Or put this content in a file 'bib.md' and then inside citations block use include`bib.md` -->
```
To debug the linked file or included file, use EOF on its own line to keep editing and clearing errors.
Use slide handle or Slides[number,]
to apply these methods becuase index can change on new builds.
(value)
Set yoffset (in percent) for frames to have equal height in incremental content. Set global yoffset in layout settings.
(this=None, main=None, frame=None)
Set animation of this slide. Provide None if need to stop animation. Use main
and frame
to set animation to all slides.
(src=None, opacity=1, filter=None, contain=False)
Adds background image to this slide. src
can be a url or a local image path or an svg str.
filter is a CSS filter like blur(5px), grayscale() etc.
This function enables you to add a slide purely with an image, possibly with opacity=1
and contain = True
.
(go_there=True)
Update display of this slides including reloading citations, widgets etc.
(name=None, height='400px', **kwargs)
Return source code of this slide, markdwon or python or None if no source exists. kwargs are passed to Slides.code.from_string
.
()
Show this slide in cell.
(this: dict = None, overall: dict = None)
Attributes at the root level of the dictionary are only picked if they are related to background. Each call will reset previous call if props given explicitly, otherwise not.
Slides.css_syntax
for information on how to write CSS dictionary.slides.html('style',props)
, you can set CSS variables at top level here including theme variables
--fg[1,2,3]-color
,--bg[1,2,3]-color
and --[accent, pointer]-color
to tweek appearance of individual or all slides.CSS is formatted using a props
nested dictionary to simplify the process.
There are few special rules in props
:
'.A': {'.B': ... }
becomes .A .B {...}
in CSS.'.A': {'^:hover': ...}
becomes .A:hover {...}
in CSS. You can also use '.A:hover'
directly but it will restrict other nested keys to hover only.'.A': {'font-size': ('20px','2em')}
becomes .A {font-size: 20px; font-size: 2em;}
in CSS.Read about specificity of CSS selectors here.
props = {
".A": {
"z-index": "2",
".B": {
"font-size": [
"24px",
"2em"
],
"^:hover": {
"opacity": "1"
}
},
"> h1": {
"padding": "0",
"@media screen and (min-width: 650px)": {
"padding": "2em"
}
},
".C p": {
"font-size": "14px"
}
},
".D": {
"transform": "translate(-2px,1px)",
"^, h1": {
"background": "red",
"span, i": {
"color": "whitemoke",
"@keyframes animation-name": {
"from": {
"opacity": 0
},
"to": {
"opacity": 1
}
}
}
}
}
}
Output of html('style',props)
, set_css(props)
etc. functions. Top selector would be different based on where it is called.
<style>
.SlideArea .A {
z-index : 2;
}
.SlideArea .A .B {
font-size : 24px;
font-size : 2em;
}
.SlideArea .A .B:hover {
opacity : 1;
}
.SlideArea .A > h1 {
padding : 0;
}
@media screen and (min-width: 650px) {
.SlideArea .A > h1 {
padding : 2em;
}
}
.SlideArea .A .C p {
font-size : 14px;
}
.SlideArea .D {
transform : translate(-2px,1px);
}
.SlideArea .D,
.SlideArea .D h1 {
background : red;
}
.SlideArea .D span,
.SlideArea .D i,
.SlideArea .D h1 span,
.SlideArea .D h1 i {
color : whitemoke;
}
@keyframes animation-name {
from {
opacity : 0;
}
to {
opacity : 1;
}
}
</style>
Extended syntax on top of Python-Markdown supports almost full presentation from Markdown.
Presentation Structure
---
is used to split text in slides inside markdown content of Slides.build
function or markdown file.
Double dashes --
is used to split text in frames. Alongwith this `` can be used to increment text on framed slide.Slides.docs()
for creating a TOC
accompanied by section summary.Slides.sync_with_file
.Slides.set_citations
function (or see below).Slides.refs
to add citations anywhere on slide. If ncol_refs
is not given, it will be picked from layout settings.Slides.sync_with_file
, you can add citations with block sytnax: ::: citations [inline or footnote]
@key1: Saboor et. al., 2025
@key2: A citations can span multiple lines, but key should start on new line
Content Blocks
The general block syntax is ::: type-or-classes [args] attributes
.
/
to divide css properties from node attributes such as ::: note-info border="1px solid red" / id="mynote" dir="ltr"
. Node attributes come after /
.|
in header (only takes effect if body is empty), such as ::: block-red | text
will create a block with red background and text inside.|
and /
can be escaped in header by backslah to interpret them as literal characters instead of block body and attributes splitters respectively. :
at start of each line. This multiline header is not available in ``` blocks.fg1=red bg2=black
upto 3, can be assigned for each block to tweak look and feel of content.:::
at start of line, such as ::: block-red
will not be parsed as block.::: block
nested inside ``` block at same indentation level but otherwise must be correctly indented.Block Syntax | Description |
---|---|
::: raw/pre |
Raw text or preformatted text, no markdown parsing. Use raw or pre as first word in block. |
::: code |
Code block with syntax highlighting, parameters are passed to highlight function. |
::: tag or classes |
tags are block level elements such as p , details , summary , table , center , etc. |
::: columns/multicol [widths] |
Create columns with relative widths, e.g. columns 4 6 for 40% and 60% width. Use +++ separator to reveal content incrementally/make display columns. |
::: md-[pos] |
Parse markdown in the block, with showing source code at pos=[before,after,left,right] . Add -c to collapse code and show on click. |
::: table [col widths] |
Create a table with optional column widths, e.g. ::: table 1 2 for 33% and 66% width. Use caption-side=top/bottom to place caption on top/bottom. |
::: citations [inline or footnote] |
Add citations in the block, with inline or footnote mode. Use @key: value syntax to add citations in block. |
Layouts
|
with |
to use it as text inside stack. See at end how to nest such stacking.::: columns
or ::: multicol
syntax.
Column separator is triple plus +++
if intended in display mode.
::: columns 6 1 4 block-blue
: border="1px dashed red"
::: block-red
- `::: columns/muticol` with a +++ separator act like `write` command and reveal content incrementally when `` is used
- children inside `columns` picks relative width from parent's `columns` block evem if '+++' is not used.
In thise children should be visually blocks themselves like headings, paragraphs, lists etc or wrapped in `::: block` to make them obvious blocks like this one.
- CSS classes and attributes can be used to style columns besides relative widths.
::: block-blue border="1px solid red" | alert`inline` color`block` text
::: block-yellow border="2px solid orange" padding="10px"
- Top level `columns` is necessary to create columns or use simple block with `display=flex`.
and frame speactor is used at end of block.
- Indentation is important, so use tabs or spaces consistently.
::: columns/muticol
with a +++ separator act like write
command and reveal content incrementally when `` is usedcolumns
picks relative width from parent's columns
block evem if '+++' is not used.
In thise children should be visually blocks themselves like headings, paragraphs, lists etc or wrapped in ::: block
to make them obvious blocks like this one.inline block text
columns
is necessary to create columns or use simple block with display=flex
.
and frame speactor is used at end of block.Code Display
print('Hello')
.::: code
blocks for syntax highlighting.
```python
print('Hello, I was highlighted from a code block!')
```
::: code language=bash name=Shell lineno=False style=vim
echo "Hello, I was highlighted from a code block!"
ls -l | grep ".py" | wc -l
print('Hello, I was highlighted from a code block!')
echo "Hello, I was highlighted from a code block!"
ls -l | grep ".py" | wc -l
::: code
block, you need to set parameters that are passed to highlight
function, such as language
, name
, lineno
, css_class
, etc.Variables Substitution
Variables from Python code can be embedded directly into Markdown.
str.format
method.Slides.serializer
to define their HTML representation, which allows them to be displayed correctly in place with such as %{fig}
.
Using %{fig:nb}
might show the object at the end of the slide.Slides.fmt(content, **kwargs)
.Slide[number,].rebuild(**kwargs)
. This is also useful for setting unique variable values on different slides.%{var.attr}
or %{var['key']}
, the output will only update if the base variable var
itself is reassigned.:nb
are only displayed correctly in the first level of nested blocks.:nb
format spec. str.format
method, so f-string like literal expressions are not supported.Inline Python Functions
Functions (that can also take extra args [python code as strings] as func[arg1,x=2,y=A]`arg0`) include:
Upto 4 level nesting is parsed in inline functions using (level + 1) number of / (at least two) within backticks in functions given below.
stack[(6,4),css_class="block-blue"]`////
This always parse markdown in `returns=True` mode. ||
stack[css_class="info"]`/// B ||
color["skyblue"]`//alert`Alerted Text` Colored Text //`
///`
////`
This always parse markdown in returns=True
mode.
B
Alerted Text Colored Text
General Syntax
Slides.link
for more details.| cell text \{: rowspan="2" colspan="1"}|
inside a cell, should be a space bewteen text and attributes._`sub`
and ^`sup`
for subscript and superscript respectively, e.g. H2O, E = mc2.
Item 1 Header
: Item 1 details ^`1`
Item 1 Header
: Item 1 details _`2`
Extending Syntax
Slides.extender
to extend additional syntax using Markdown extensions such as
markdown extensions and
PyMdown-Extensions.['tables', 'footnotes', 'attr_list', 'md_in_html', 'def_list']
.Slides.serializer
function. Having a
__format__
method in your class enables to use {obj} syntax in python formatting and %{obj} in extended Markdown.Besides functions below, you can add content to slides with %%xmd
,%xmd
as well.
(*objs, widths=None, css_class=None)
Write objs
to slides in columns. To create rows in a column, wrap objects in a list or tuple.
You can optionally specify widths
as a list of percentages for each column.
css_class
can have multiple classes separated by space, works only for multiple columns.
Write any object that can be displayed in a cell with some additional features:
Slides.hold(func,...)
. Only body of the function will be displayed/printed. Return value will be ignored.ipywidgets
or ipyvolume
by passing them directly.matplotlib
, plotly
altair
, bokeh
etc. by passing them directly.Slides.code
API.Slides.alt
function to display obj/widget on slides and alternative content/screenshot of widgets in exported slides.ipywidgets.[HTML, Output, Box]
and their subclasses will be displayed as Slides.alt(html_converter_func, widget)
. The value of exported HTML will be most recent.ipyslides.utils
module that are also linked to Slides
object.API. IPython's
display` automatically takes care of such objects on export to html.IPython.core.formatters
API for third party libraries.Slides.frozen
to avoid display formatting and markdown parsing over objects in write
and for some kind of objects in display
too.write
is a robust command that can handle most of the cases. If nothing works, repr(obj)
will be displayed.repr(obj)
by Slides.hold(func, ...)
e.g. Slides.hold(plt.show)
. This can also be used to delay display until it is captured in a column.display(obj, metadata = {'text/html': 'html repr by user'})
for any object to display object as it is and export its HTML representation in metadata.write
is equivalent to parse
command.Slides.stack
, but content type is limited in that case.multicol/columns
block syntax is similar to write
command if +++
separartor is used there.(xmd, returns=False)
Parse extended markdown and display immediately.
If you need output html, use returns = True
but that won't display variables.
Example
# Normal Markdown
```multicol 40 60
# First column is 40% width
If 40 60 was not given, all columns will be of equal width, this paragraph will be inside info block due to class at bottom
{.info}
+++
# Second column is 60% wide
This \%{var_name} (or legacy \`{var_name}\`) can be substituted with `fmt` function or from notebook if whole slide is built with markdown.
```
```python
# This will not be executed, only shown
```
stack`Inline-column A || Inline-column B`
python .friendly
or multicol .Sucess.info
.python .friendly
will be highlighted with friendly theme from pygments.multicol
.::: class_type
syntax accepts extra classes in quotes, for example ::: multicol "Success" "info"
.jupyter-only
and export-only
that control appearance of content in different modes.Nested blocks are supported via indentation in md-[before,after,left,right]
and multicol
, but may be broken in display contexts.
Slides.xmd_syntax
.Slides.extender
or ipyslides.xmd.extender
to add markdown extensions.(obj)
Convert supported (almost any) obj to html format.
(tag, children=None, css_class=None, **node_attrs)
Returns html node with given children and node attributes like style, id etc. If an ttribute needs '-' in its name, replace it with '_'.
tag
can be any valid html tag name. A tag
that ends with /
will be self closing e.g. hr/
will be <hr/>
. Empty tag gives unwrapped children.
children
expects:
slides[number,].set_css
otherwise. See Slides.css_syntax
to learn about requirements of styles in dict.Example:
html('img',src='ir_uv.jpg') #Returns IPython.display.HTML("<img src='ir_uv.jpg'></img>") and displas image if last line in notebook's cell.
To keep an image persistently embeded, use ipyslides.utils.imge
function instead of just an html tag.
You can use alert
in markdown.
This is experimental feature, and may not work as expected.
()
(content)
Add notes to current slide. Content could be any object except javascript and interactive widgets.
In markdown, you can use notes`notes content`.
In markdown, the block md-[before,after,left,right] [-c]
parses and displays source as well.
(obj, language='python', name=None, css_class=None, style='default', color=None, background=None, hover_color='var(--bg3-color)', lineno=True, height='400px')
Highlight code (any python object that has a source or str of code) with given language and style.
pygments.styles.get_all_styles()
, then style will be applied immediately.obj
is a file-like object, it's read
method will be accessed to get source code.If you want plain inline syntax highlighting, use Slides.hl
.
(returns=False, **kwargs)
Execute and displays source code in the context manager. kwargs
are passed to Slides.highlight
function.
Useful when source is written inside context manager itself.
If returns
is False (by default), then source is displayed before the output of code. Otherwise you can assign the source to a variable and display it later anywhere.
Usage:
with source.context(returns = True) as s:
do_something()
write(s) # or s.display(), write(s)
#s.raw, s.value are accesible attributes.
#s.focus_lines, s.show_lines are methods that are used to show selective lines.
(file, language=None, name=None, **kwargs)
Returns source object with show_lines
and focus_lines
methods. name
is alternate used name for language.
kwargs
are passed to Slides.highlight
.
It tries to auto detect lanaguage from filename extension, if language
is not given.
(obj, **kwargs)
Returns source code from a given obj [class,function,module,method etc.] with show_lines
and focus_lines
methods. kwargs
are passed to Slides.highlight
(text, language='python', name=None, **kwargs)
Creates source object from string. name
is alternate used name for language. kwargs
are passed to Slides.highlight
.
Apply settings to slides programatically. Fewer settings are available as widgets.
Settings can be nested or individual attributes as set as well. For example:
Slides.settings(layout = {"aspect": 16/10}) # Top
Slides.settings.layout(aspect = 16/10) # Individual
Slides.settings.layout.aspect = 16/10 # Attribute
All settings calls including top level returns settings instance to apply method chaining.
e.g. Slides.settings.layout(aspect = 16/10).footer(text="ABC").logo(...)
.
Set code block styles. background and color may be needed for some styles.
(path)
Dump the settings state to a json file. Use it once you have finalized a settings setup of slides.
Set fonts of text and code and size.
Set footer attributes of slides.
Set layout of slides.
(path)
Load settings from a json file. You may need to dump settings and then edit for correct usage.
Set logo for all slides. left and bottom take precedence over right and top respectively.
Set theme value. colors and code have their own nested traits.
Toggle ON/OFF checks in settings panel.
(exportable_data, obj)
Display obj
for slides and output of exportable_data
will be and displayed only in exported formats as HTML.
exportable_data
should be an html str or a callable to receive obj
as its only argument.obj
.
import ipywidgets as ipw
slides.alt(lambda w: f'<input type="range" min="{w.min}" max="{w.max}" value="{w.value}">', ipw.IntSlider()).display()
alt
many times for same type, you can use Slides.serializer.register
and then pass that type of widget without alt
.ipywidgets
's HTML
, Box
and Output
widgets and their subclasses directly give html representation if used inside write
command.(*, continuous_update=<traitlets.traitlets.Bool object at 0x000002A202AB5880>, cyclic=<traitlets.traitlets.Bool object at 0x000002A202AB58B0>, description=<traitlets.traitlets.Unicode object at 0x000002A202AB5760>, interval=<traitlets.traitlets.Float object at 0x000002A202AB5820>, loop=<traitlets.traitlets.Bool object at 0x000002A202AB57C0>, nframes=<traitlets.traitlets.CInt object at 0x000002A202AB57F0>, playing=<traitlets.traitlets.Bool object at 0x000002A202AB5850>, value=<traitlets.traitlets.CInt object at 0x000002A202AB5790>, **kwargs)
This is a simple slider widget that can be used to control the animation with an observer function.
You need to provide parameters like nframes
and interval
(milliseconds) to control the animation.
The value
trait can be observed to get the current frame index.
The cyclic
trait can be set to True
to make the animation cyclic and only works when loop mode is ON.
from plotly.graph_objects import FigureWidget
fig = FigureWidget()
fig.add_scatter(y=[1, 2, 3, 4, 5])
widget = slides.AnimationSlider() # assuming slides is the instance of Slides app
def on_change(change):
value = change['new']
fig.data[0].color = f'rgb({int(value/widget.nframes*100)}, 100, 100)' # change color based on frame index
widget.observe(on_change, names='value')
display(widget, fig) # display it in the notebook
This widget can be passed to ipywidgets.interactive
as keyword argument to create a dynamic control for the animation.
from ipywidgets import interact
@interact(frame=widget)
def show_frame(frame):
print(frame)
(text)
Alerts text!
(*objs, widths=None)
Format a block like in LATEX beamer with objs
in columns and immediately display it. Format rows by given an obj as list of objects.
block_<red,green,blue,yellow,cyan,magenta,gray>
.write
command for details of objs
and widths
.(bokeh_fig, title='')
Write bokeh figure as HTML string to use in ipyslide.utils.write
.
Parameters
(iterable, ordered=False, marker=None, css_class=None)
A powerful bullet list. iterable
could be list of anything that you can pass to write
command.
marker
could be a unicode charcter or string, only effects unordered list.
(text, fg='var(--accent-color, blue)', bg=None)
Colors text, fg
and bg
should be valid CSS colors
(obj, summary='Click to show content')
Show/Hide Content in collapsed html.
(obj, prepend_str=None, members=None, itself=True)
Returns documentation of an obj
. You can prepend a class/module name. members is True/List of attributes to show doc of.
(name, msg)
Add error without breaking execution.
(*args, **kwargs)
Markdown string wrapper that will be parsed with given kwargs lazily. If markdown contains variables not in kwargs, it will try to resolve them from local/global namespace and raise error if name is nowhere. Use inside python scripts when creating slides. In notebook, variables are automatically resolved, although you can still use it there.
Being as last expression of notebook cell or using self.parse() will parse markdown content.
(obj, metadata=None)
Display object as it it and export metadata if not str. A frozen object may not appear in exported html if metadata is not given.
Returned object has a display method, or can be directly passed to display/write commands.
(obj, language='python', name=None, css_class=None, style='default', color=None, background=None, hover_color='var(--bg3-color)', lineno=True, height='400px')
Highlight code (any python object that has a source or str of code) with given language and style.
pygments.styles.get_all_styles()
, then style will be applied immediately.obj
is a file-like object, it's read
method will be accessed to get source code.If you want plain inline syntax highlighting, use Slides.hl
.
(tag, children=None, css_class=None, **node_attrs)
Returns html node with given children and node attributes like style, id etc. If an ttribute needs '-' in its name, replace it with '_'.
tag
can be any valid html tag name. A tag
that ends with /
will be self closing e.g. hr/
will be <hr/>
. Empty tag gives unwrapped children.
children
expects:
slides[number,].set_css
otherwise. See Slides.css_syntax
to learn about requirements of styles in dict.Example:
html('img',src='ir_uv.jpg') #Returns IPython.display.HTML("<img src='ir_uv.jpg'></img>") and displas image if last line in notebook's cell.
To keep an image persistently embeded, use ipyslides.utils.imge
function instead of just an html tag.
(src, width='100%', height='auto', **kwargs)
Display src
in an iframe. kwrags
are passed to IPython.display.IFrame
(data=None, width='95%', caption=None, crop=None, css_props={}, **kwargs)
Displays PNG/JPEG files or image data etc, kwrags
are passed to IPython.display.Image.
crop
is a tuple of (left, top, right, bottom) in percentage of image size to crop the image.
css_props
are applied to figure
element, so you can control top layout and nested img tag.
You can provide following to data
parameter:
Slides.clips_dir
if not found.
Use 'clip:image.png' to pick image from Slides.clips_dir
directly if another file 'image.png' also exists in current directory.Returns an IMG
object which can be exported to other formats (if possible):
IMG.to_pil()
returns PIL.Image
or None.IMG.to_numpy()
returns image data as numpy array for use in plotting libraries or None.(content, timeout=5)
Send inside notifications for user to know whats happened on some button click. Send 'x' in content to clear previous notification immediately.
(plt_fig=None, transparent=True, width=None, caption=None, crop=None)
Write matplotib figure as HTML string to use in ipyslide.utils.write
.
Parameters
(text, css_class=None)
Keep shape of text as it is (but apply dedent), preserving whitespaces as well.
(path)
Context manager to set working directory to given path and return to previous working directory when done.
(callable, prepend_str=None)
Returns signature of a callable. You can prepend a class/module name.
(objs, sizes=None, vertical=False, css_class=None, **css_props)
Stacks given objects in a column or row with given sizes.
(obj, css_class=None, **css_props)
Add a class to a given object, whether a widget or html/IPYthon object. CSS inline style properties should be given with names including '-' replaced with '_' but values should not. Only a subset of inline properties take effect if obj is a widget.
Objects other than widgets will be wrapped in a 'div' tag. Use html
function if you need more flexibility.
(stdout=True)
Suppress output of a block of code. If stdout
is False, only display data is suppressed.
()
Suppress stdout in a block of code, especially unwanted print from functions in other modules.
(data=None, width=None, caption=None, crop=None, css_props={}, **kwargs)
Display svg file or svg string/bytes with additional customizations.
crop
is a tuple of (left, top, right, bottom) in percentage of image size to crop the image.
css_props
are applied to figure
element, so you can control top layout and nested svg tag.
kwrags
are passed to IPython.display.SVG. You can provide url/string/bytes/filepath for svg.
(data, headers=None, widths=None)
Creates a table of given data like DataFrame, but with rich elements.
data
should be a 2D matrix-like. headers
is a list of column names. widths
is a list of widths for each column.
Example:
import pandas as pd
df = pd.DataFrame({'A': [1,2,3], 'B': [4,5,6]})
slides.table(df.values, headers=df.columns, widths=[1,2])
slides.table([[1,2,3],[4,5,6]], headers=['A','B','C'], widths=[1,2,3])
(text, **css_props)
Formats text in a box for writing e.g. inline refrences. css_props
are applied to box and -
should be <sub> like </sub>font-size
-> font_size
.
text
is not parsed to general markdown i.e. only bold italic etc. applied, so if need markdown, parse it to html before. You can have common CSS for all textboxes using class text-box
.
(fmt='%b %d, %Y', fg='inherit')
Returns today's date in given format.
(em=1)
Returns html node with given height in em
.
(obj)
Wraps a given obj in a parent with 'zoom-child' class or add 'zoom-self' to widget, whether a widget or html/IPYthon object
Use syntax cite`key` / @key to add citations which should be already set by Slides.set_citations(data, mode)
method.
Citations are written on suitable place according to given mode. Number of columns in citations are determined by
Slides.settings.layout(..., ncol_refs = int)
. 1
Add sections in slides to separate content by section`text`. Corresponding table of contents can be added with toc`title`.
(data, mode='footnote')
Set citations from dictionary or string with content like @key: citation value
on their own lines,
key should be cited in markdown as cite`key` / @key, optionally comma separated keys.
mode
for citations should be one of ['inline', 'footnote']. Number of columns in citations are determined by Slides.settings.layout(..., ncol_refs=N)
.
set_citations({"key1":"value1","key2":"value2"})
set_citations('''
@key1: citation for key1
@key2: citation for key2
''')
with open("citations_file.md","r") as f:
set_citations(f.read()) # same content as string above
with open("citations_file.json","r") as f:
set_citations(json.load(f))
Slides.sync_with_file
's context.Citation A
(*funcs: List[Callable], auto_update: bool = True, app_layout: dict = None, grid_css: dict = {}, **kwargs) -> None
Enhanced interactive widget with multiple callbacks, grid layout and fullscreen support.
This function is used for quick dashboards. Subclass InteractBase
for complex applications.
Features:
Basic Usage:
from ipyslides.interaction import interactive, callback, monitor
import ipywidgets as ipw
import plotly.graph_objects as go
fig = go.FigureWidget()
@callback('out-plot', timeit=True) # check execution time
def update_plot(x, y, fig):
fig.data = []
fig.add_scatter(x=[0, x], y=[0, y])
def resize_fig(fig, fs):
fig.layout.autosize = False # double trigger
fig.layout.autosize = True # plotly's figurewidget always make trouble with sizing
# Above two functions can be merged since we can use changed detection
@monitor # check execution time
def respond(x, y, fig , fs, changed):
if 'fs' in changed: # or changed('fs')
fig.layout.autosize = False # double trigger
fig.layout.autosize = True
else:
fig.data = []
fig.add_scatter(x=[0, x], y=[0, y])
dashboard = interactive(
update_plot,
resize_fig, # responds to fullscreen change
# respond, instead of two functions
x = ipw.IntSlider(0, 0, 100),
y = ipw.FloatSlider(0, 1),
fig = ipw.fixed(fig),
changed = '.changed', # detect a change in parameter
fs = '.isfullscreen', # detect fullscreen change on instance itself
)
Parameters:
*funcs
: One or more callback functionsrelayout()
method for details:fullscreen
at root level of dict to apply styles in fullscreen mode[Button, ToggleButton(s)].add_class('content-width-button')
to fix button widths easily.**kwargs
: Widget parametersWidget Parameters:
changed = '.changed'
to detect which parameters of a callback changed by checking changed('param') -> Bool
in a callback.f(fig, v)
where v='fig.selected'
.ipywidgets.Button
for manual updates on callbacks besides global auto_update
. Add tooltip for info on button when not synced.btn.clicked
attribute to run code based on which button was clicked.Widget Updates:
@callback
.CSS Classes:
@callback
, and 'out-main' class.Notes:
Python dictionary to CSS
CSS is formatted using a props
nested dictionary to simplify the process.
There are few special rules in props
:
'.A': {'.B': ... }
becomes .A .B {...}
in CSS.'.A': {'^:hover': ...}
becomes .A:hover {...}
in CSS. You can also use '.A:hover'
directly but it will restrict other nested keys to hover only.'.A': {'font-size': ('20px','2em')}
becomes .A {font-size: 20px; font-size: 2em;}
in CSS.Read about specificity of CSS selectors here.
Tips:
write('First column', C2)
where C2 = Slides.hold(Slides.ei.interact, f, x = 5) or Slides.ei.interactive(f, x = 5)
.Slides.capture_content
to display later in a specific place.
import time
@self.ei.interact(auto_update=False, grid_css = dict({'.out-main': dict(height='2em')},background='var(--bg2-color)'), date = False) # self is Slides here
def update_time(date):
local_time = time.localtime()
objs = ['Time: {3}:{4}:{5}'.format(*local_time)] # Print time in HH:MM:SS format
if date:
objs.append('Date: {0}/{1}/{2}'.format(*local_time))
self.stack(objs).display()
Time: 17:22:11
import datetime
@self.on_load # self is Slides here
def push_toast(slide):
t = datetime.datetime.now()
time = t.strftime('%H:%M:%S')
self.notify(f'Notification at {time} form slide {slide.index} and frame {slide.indexf}', timeout=5)
(func)
Decorator for running a function when slide is loaded into view. No return value is required. Use this to e.g. notify during running presentation. func accepts single arguemnet, slide.
See Slides.docs()
for few examples.
You can style or colorize your content and text.
Provide CSS for that using Slides.html("style",...)
or use some of the available styles.
See these styles with Slides.css_styles
property as shown on right.
Use any or combination of these styles in markdown blocks or css_class
argument of writing functions:
css_class | Formatting Style |
---|---|
text-[value] |
[value] should be one of tiny, small, big, large, huge. |
align-[value] |
[value] should be one of center, left, right. |
rtl |
اردو، فارسی، عربی، ۔۔۔ |
info |
Blue text. Icon ℹ️ for note-info class. |
tip |
Blue text. Icon💡 for note-tip class. |
warning |
Orange text. Icon ⚠️ for note-warning class. |
success |
Green text. Icon ✅ for note-success class. |
error |
Red text. Icon⚡ for note-error class. |
note |
Text with note icon, can combine other classes as shown above. |
export-only |
Hidden on main slides, but will appear in exported slides. |
jupyter-only |
Hidden on exported slides, but will appear on main slides. |
block |
Block of text/objects |
block-[color] |
Block of text/objects with specific background color from red, green, blue, yellow, cyan, magenta and gray. |
raw-text |
Text will be shown as printed style. |
zoom-self |
Zooms object on hover, when Zoom is enabled. |
zoom-child |
Zooms child object on hover, when Zoom is enabled. |
no-zoom |
Disables zoom on object when it is child of 'zoom-child'. |
Besides these CSS classes, you always have Slide.set_css
, Slides.html('style',...)
functions at your disposal.
stack[(3,7)]`//
## Content Styling
You can **style**{.error} or **color["teal"]`colorize`** your *content*{: style="color:hotpink;"} and *color["hotpink","yellow"]`text`*.
Provide **CSS**{.info} for that using hl`Slides.html("style",...)` or use some of the available styles.
See these **styles**{.success} with `Slides.css_styles` property as shown on right.
|| %{self.css_styles}
//`
pygments is used for syntax highlighting 1.
You can highlight code using highlight
function 2 or within markdown using code blocks enclosed with three backticks:
import ipyslides as isd
import React, { Component } from "react";
Source code of slide can be embeded via variable too:
fmt("""
## Highlighting Code
[pygments](https://pygments.org/) is used for syntax highlighting cite`A`.
You can **highlight**{.error} code using `highlight` function cite`B` or within markdown using code blocks enclosed with three backticks:
```python
import ipyslides as isd
```
```javascript
import React, { Component } from "react";
```
Source code of slide can be embeded via variable too: %{self.this.source}
""",
self = '<Slides at 0x2a202645340>'
)
You can parse and view a markdown file. The output you can save by exporting notebook in other formats.
(start_slide_number, /, path, interval=500)
Auto update slides when content of markdown file changes. You can stop syncing using Slides.unsync
function.
interval is in milliseconds, 500 ms default. Read Slides.build
docs about content of file.
The variables inserted in file content are used from top scope.
You can add files inside linked file using include\`file_path.md\` syntax, which are also watched for changes.
This helps modularity of content, and even you can link a citation file in markdown format as shown below. Read more in Slides.xmd_syntax
about it.
```citations footnote
@key1: Saboor et. al., 2025
@key2: A citations can span multiple lines, but key should start on new line
<!-- Or put this content in a file 'bib.md' and then inside citations block use include`bib.md` -->
```
To debug the linked file or included file, use EOF on its own line to keep editing and clearing errors.
()
Demo slides with a variety of content.
()
Create presentation from docs of IPySlides.
(path='Slides.html', overwrite=False, progressbar=True)
Build html slides that you can print.
Save as PDF
option instead of Print PDF in browser to make links work in output PDF. Alsp enable background graphics in print dialog.
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
self.write('## Adding User defined Objects/Markdown Extensions')
self.write(
self.hold(display, self.html('h3','I will be on main slides',css_class='warning'),
metadata = {'text/html': '<h3 class="warning">I will be on exported slides</h3>'}
), # Can also do 'Slides.serilaizer.get_metadata(obj)' if registered
s.get_source(), widths = [1,3]
)
self.write(r'If you need to serialize your own or third party objects not serialized by this module, you can use `\@Slides.serializer.register` to serialize them to html.\n{.note .info}')
self.doc(self.serializer,'Slides.serializer', members = True, itself = False).display()
self.write('**You can also extend markdown syntax** using `markdown extensions`, ([See here](https://python-markdown.github.io/extensions/) and others to install, then use as below):')
self.doc(self.extender,'Slides.extender', members = True, itself = False).display()
If you need to serialize your own or third party objects not serialized by this module, you can use @Slides.serializer.register
to serialize them to html.\n{.note .info}
(obj_type)
Get serializer function for a type. Returns None if not found.
(obj_type)
Get html str of a registerd obj_type.
(obj_type)
Get metadata for a type to use in display(obj, metadata)
for export purpose. This take precedence over object's own html representation. Returns {} if not found.
(obj_type, verbose=True)
Decorator to register html serializer for an object type.
obj_type
and should return HTML string.Usage
class MyObject:
def __repr__(self):
return 'My object is awesome'
slides = ipyslides.Slides()
@slides.serializer.register(MyObject)
def parse_myobject(obj):
return f'<h1>{obj!r}</h1>'
my_object = MyObject()
slides.write(my_object) #This will write "My object is awesome" as main heading
parse_myobject(my_object) #This will return "<h1>My object is awesome</h1>"
#This is equivalent to above for custom objects(builtin objects can't be modified)
class MyObject:
def _repr_html_(self):
return '<h1>My object is awesome</h1>'
my_object = MyObject()
slides.write(my_object)
inside
writecommand for export purpose. Other commands such as
Slides.[cols,rows,...]` will pick oldest value only.display
function automatically take care of serialized objects.(obj_type)
Unregister all serializer handlers for a type.
()
Unregister all serializer handlers.
You can also extend markdown syntax using markdown extensions
, (See here and others to install, then use as below):
()
Clear all extensions and their configurations added by user.
(configs_dict)
Add configurations to the Markdown extensions. configs_dict is a dictionary like {'extension_name': config_dict}
(extensions_list)
Add list of extensions to the Markdown parser.
Z
key.zoom-self
, zoom-child
classes to an element. To prevent zooming under as zoom-child
class, use no-zoom
class.Z
key while mouse is over this part.Icons that apprear on buttons inslides (and their rotations) available to use in your slides as well besides standard ipywidgets icons.
import ipywidgets as ipw
btn = ipw.Button(description='Chevron-Down Icon',icon='chevrond')
self.write(btn)
Source code of this slide
with self.capture_content() as c:
with self.code.context():
import ipywidgets as ipw
btn = ipw.Button(description='Chevron-Down Icon',icon='chevrond')
self.write(btn)
group = zip(self.icon.available[::2], self.icon.available[1::2]) # make 4 columns table
self.write(['''
## SVG Icons
Icons that apprear on buttons inslides (and their rotations) available to use in your slides as well
besides standard ipywidgets icons.
''', *c.outputs, 'line`200`**Source code of this slide**',self.this.get_source()],
self.table([(f'`{j}`', self.icon(j,color='crimson').svg,f'`{k}`', self.icon(k,color='crimson').svg) for j, k in group],headers=['Name','Icon','Name','Icon']),
widths=[3,2])
Name
Icon
Name
Icon
arrow
arrowb
arrowbd
arrowbl
arrowbr
arrowbu
arrowd
arrowl
arrowr
arrowu
bars
camera
chevron
chevrond
chevronl
chevronr
chevronu
circle
close
code
columns
compress
dots
edit
expand
info
laser
loading
panel
pause
pencil
play
refresh
rows
search
settings
stop
win-maximize
win-restore
zoom-in
Use -1 as placeholder to update slide number automatically.
-1
.Slides.build<sub> instead of using </sub>-1
.Some kernels may not support auto slide numbering inside notebook.
def docs(self):
"Create presentation from docs of IPySlides."
self.close_view() # Close any previous view to speed up loading 10x faster on average
self.clear() # Clear previous content
self.create(range(31)) # Create slides faster
from ..core import Slides
self.set_citations({'A': 'Citation A', 'B': 'Citation B'}, mode = 'footnote')
self.settings.footer(text=self.get_logo("1em") + "IPySlides Documentation", date=None)
with self.build(0): # Title page
self.this.set_bg_image(self.get_logo(),0.25, filter='blur(10px)', contain=True)
self.write(f'## IPySlides {self.version} Documentation\n### Creating slides with IPySlides')
self.center(self.fmt('''
alert`Abdul Saboor` ^`1`
today``
{.text-small}
%{logo}
::: text-box
^`1`My University is somewhere in the middle of nowhere
''', logo = self.get_logo("4em"))).display()
self.build(-1, self.fmt('''
```md-after
section`Introduction`
```multicol .block-green
toc[True]`## Table of contents`
+++
### This is summary of current section
Oh we can use inline columns stack`Column A || Column B` here and what not!
%{btn}
```
```''', btn = self.draw_button))
with self.build(-1):
self.write('# Main App')
self.doc(Slides).display()
with self.build(-1):
self.write('# Jump between slides')
self.doc(self.link, 'Slides').display()
with self.code.context(returns=True) as c:
skipper = self.link('Skip to dynamic content', 'Back to link info', icon='arrow', back_icon='arrowl')
skipper.origin.display() # skipper.target is set later somewhere, can do backward jump too
c.display()
with self.build(-1):
self.write('## Adding Slides section`Adding Slides and Content`')
self.write('Besides function below, you can add slides with `%%slide number [-m]` magic as well.\n{.note .info}')
self.write([self.doc(self.build,'Slides'), self.doc(self.sync_with_file,'Slides')])
with self.build_():
self.write('''
## Important Methods on Slide
::: note-warning
Use slide handle or `Slides[number,]` to apply these methods becuase index can change on new builds.
''')
self.doc(self[0], members='yoffset set_animation set_bg_image update_display get_source show set_css'.split(), itself = False).display()
self.css_syntax.display()
self.build(-1, re.sub(r'^---\s*$', '---\n## Extended Markdown' ,_syntax.xmd_syntax, flags=re.MULTILINE))
with self.build(-1):
self.write('## Adding Content')
self.write('Besides functions below, you can add content to slides with `%%xmd`,`%xmd` as well.\n{.note .info}')
self.write(self.doc(self.write,'Slides'), [self.doc(self.parse,'Slides'),self.doc(self.as_html,'Slides'),self.doc(self.html,'Slides')])
with self.build(-1):
self.write('## Adding Speaker Notes')
self.write([rf'styled["note success"]`You can use alert`notes\`notes content\`` in markdown.`',
'This is experimental feature, and may not work as expected.\n{.note-error .error}'])
self.doc(self.notes,'Slides.notes', members = True, itself = False).display()
with self.build(-1):
self.write('## Displaying Source Code')
self.write('In markdown, the block `md-[before,after,left,right] [-c]` parses and displays source as well.')
self.doc(self.code,'Slides.code', members = True, itself = False).display()
self.build(-1, r'section`//Layout and color["yellow","black"]`Theme` Settings//` toc`### Contents`')
with self.build(-1) as s:
s.set_css({
'--bg1-color': 'linear-gradient(45deg, var(--bg3-color), var(--bg2-color), var(--bg3-color))',
'.highlight': {'background':'#8984'}
})
self.styled('## Layout and Theme Settings', 'info', border='1px solid red').display()
self.doc(self.settings,'Slides', members=True,itself = True).display()
with self.build(-1):
self.write('## Useful Functions for Rich Content section`//Useful Functions for alert`Rich Content`//`')
self.doc(self.alt,'Slides').display()
members = sorted((
'AnimationSlider alert block bokeh2html bullets styled fmt color details doc '
'today error zoomable highlight html iframe image frozen notify plt2html '
'raw set_dir sig stack table textbox suppress_output suppress_stdout svg vspace'
).split())
self.doc(self, 'Slides', members = members, itself = False).display()
with self.build(-1):
self.write(r'''
## Citations and Sections
Use syntax alert`cite\`key\`` / alert`\@key` to add citations which should be already set by hl`Slides.set_citations(data, mode)` method.
Citations are written on suitable place according to given mode. Number of columns in citations are determined by
hl`Slides.settings.layout(..., ncol_refs = int)`. @A
Add sections in slides to separate content by alert`section\`text\``. Corresponding table of contents
can be added with alert`toc\`title\``.
''')
self.doc(self, 'Slides', members = ['set_citations'], itself = False).display()
with self.build(-1):
skipper.target.display() # Set target for skip button
self.write('## Dynamic Content')
with self.capture_content() as cap, self.code.context():
import time
@self.ei.interact(auto_update=False, grid_css = dict({'.out-main': dict(height='2em')},background='var(--bg2-color)'), date = False) # self is Slides here
def update_time(date):
local_time = time.localtime()
objs = ['Time: {3}:{4}:{5}'.format(*local_time)] # Print time in HH:MM:SS format
if date:
objs.append('Date: {0}/{1}/{2}'.format(*local_time))
self.stack(objs).display()
with self.code.context(returns=True) as c:
import datetime
@self.on_load # self is Slides here
def push_toast(slide):
t = datetime.datetime.now()
time = t.strftime('%H:%M:%S')
self.notify(f'Notification at {time} form slide {slide.index} and frame {slide.indexf}', timeout=5)
self.write(
[self.doc(self.ei.interact,'Slides.ei')],
[*cap.outputs, c, self.doc(self.on_load,'Slides')],
)
self.build(-1, fmt("""
```md-after -c
stack[(3,7)]`//
## Content Styling
You can **style**{.error} or **color["teal"]`colorize`** your *content*{: style="color:hotpink;"} and *color["hotpink","yellow"]`text`*.
Provide **CSS**{.info} for that using hl`Slides.html("style",...)` or use some of the available styles.
See these **styles**{.success} with `Slides.css_styles` property as shown on right.
|| %{self.css_styles}
//`
```
"""))
self.build(-1, self.fmt('''
## Highlighting Code
[pygments](https://pygments.org/) is used for syntax highlighting cite`A`.
You can **highlight**{.error} code using `highlight` function cite`B` or within markdown using code blocks enclosed with three backticks:
```python
import ipyslides as isd
```
```javascript
import React, { Component } from "react";
```
Source code of slide can be embeded via variable too: %{self.this.source}
''', self=self))
with self.build(-1):
self.write('## Loading from File/Exporting to HTML section`Loading from File/Exporting to HTML`')
self.write('You can parse and view a markdown file. The output you can save by exporting notebook in other formats.\n{.note .info}')
self.write([self.doc(attr,'Slides') for attr in (self.sync_with_file,self.demo,self.docs,self.export_html)])
self.build(-1, 'section`Advanced Functionality` toc`### Contents`')
with self.build_() as s:
self.write("## Adding content on frames incrementally yoffset`0`")
self.frozen(widget := (code := s.get_source()).as_widget()).display()
self.fsep(stack=True) # frozen in above line get oldest metadata for export
def highlight_code(slide): widget.value = code.focus_lines(range(slide.indexf + 1)).value
self.on_load(highlight_code)
for ws, cols in self.fsep.iter(zip([None, (2,3),None], [(0,1),(2,3),(4,5,6,7)])):
cols = [self.html('h1', f"{c}",style="background:var(--bg3-color);margin-block:0.05em !important;") for c in cols]
self.write(*cols, widths=ws)
with self.build(-1) as s:
self.write('## Adding User defined Objects/Markdown Extensions')
self.write(
self.hold(display, self.html('h3','I will be on main slides',css_class='warning'),
metadata = {'text/html': '<h3 class="warning">I will be on exported slides</h3>'}
), # Can also do 'Slides.serilaizer.get_metadata(obj)' if registered
s.get_source(), widths = [1,3]
)
self.write(r'If you need to serialize your own or third party objects not serialized by this module, you can use `\@Slides.serializer.register` to serialize them to html.\n{.note .info}')
self.doc(self.serializer,'Slides.serializer', members = True, itself = False).display()
self.write('**You can also extend markdown syntax** using `markdown extensions`, ([See here](https://python-markdown.github.io/extensions/) and others to install, then use as below):')
self.doc(self.extender,'Slides.extender', members = True, itself = False).display()
with self.build(-1):
self.write(r'''
## Focus on what matters
- There is a zoom button on top bar which enables zooming of certain elements. This can be toggled by `Z` key.
- Most of supported elements are zoomable by default like images, matplotlib, bokeh, PIL image, altair plotly, dataframe, etc.
- You can also enable zooming for an object/widget by wrapping it inside \`Slide.zoomable\` function conveniently.
- You can also enable by manully adding `zoom-self`, `zoom-child` classes to an element. To prevent zooming under as `zoom-child` class, use `no-zoom` class.
::: zoom-self block-red
### Focus on Me 😎
- If zoom button is enabled, you can hover here to zoom in this part!
- You can also zoom in this part by pressing `Z` key while mouse is over this part.
''')
with self.build(-1):
with self.capture_content() as c:
with self.code.context():
import ipywidgets as ipw
btn = ipw.Button(description='Chevron-Down Icon',icon='chevrond')
self.write(btn)
group = zip(self.icon.available[::2], self.icon.available[1::2]) # make 4 columns table
self.write(['''
## SVG Icons
Icons that apprear on buttons inslides (and their rotations) available to use in your slides as well
besides standard ipywidgets icons.
''', *c.outputs, 'line`200`**Source code of this slide**',self.this.get_source()],
self.table([(f'`{j}`', self.icon(j,color='crimson').svg,f'`{k}`', self.icon(k,color='crimson').svg) for j, k in group],headers=['Name','Icon','Name','Icon']),
widths=[3,2])
with self.build_():
self.write("""
# Auto Slide Numbering
Use alert`-1` as placeholder to update slide number automatically.
- In Jupyter notebook, this will be updated to current slide number.
- In python file, it stays same.
- You need to run cell twice if creating slides inside a for loop while using `-1`.
- Additionally, in python file, you can use `Slides.build_` instead of using `-1`.
::: note-warning
Some kernels may not support auto slide numbering inside notebook.
""")
self.build(-1, lambda s: self.write(['## Presentation Code section`Presentation Code`',self.docs]))
self.navigate_to(0) # Go to title
return self
IPySlides Documentation