kslides is a Kotlin DSL for the awesome reveal.js presentation framework. It is meant for people who prefer working with an IDE rather than PowerPoint. It works particularly well for presentations with code snippets and HTML animations. Slides are authored in Markdown, HTML, or the Kotlin HTML DSL.
This presentation is served statically from Netlify and GitHub Pages. It is also running dynamically on Heroku.
To create a kslides presentation, generate a new repository using the kslides-template repo as a template.
The kslides-template README.md describes how to generate and publish slide content once you have created and updated your new kslides repo.
A presentation is created using a Kotlin DSL. Defining a presentation requires a minimal knowledge of Kotlin. If you are comfortable with Python, Javascript or Java, you will have no problem with the Kotlin code.
The following kslides definition generates this presentation.
kslides {
output {
// Write the presentations to a file
enableFileSystem = true
// Do not serve up the presentations via HTTP
enableHttp = false
}
presentationConfig {
// Default config values for all presentations
}
presentation {
// Make this presentation available at helloworld.html
path = "helloworld.html"
// Specify css styles as a string
css +=
"""
.htmlslide h2 {
color: yellow;
}
"""
// or use the Kotlin CSS DSL
css {
rule("#mdslide h2") {
color = Color.green
}
}
presentationConfig {
// Default config values for this presentation
transition = Transition.FADE
topLeftHref = "" // Turn off top left href
topRightHref = "" // Turn off top right href
slideConfig {
backgroundColor = "#2A9EEE"
}
}
// Slide that uses Markdown content
markdownSlide {
id = "mdslide"
content {
"""
# Markdown
## Hello World
"""
}
}
verticalSlides {
// Slide that uses HTML content
htmlSlide {
classes = "htmlslide"
// Slide-specific config values
slideConfig {
backgroundColor = "red"
}
content {
"""
<h1>HTML</h1>
<h2>Hello World</h2>
"""
}
}
// Slide that uses Kotlin HTML DSL content
dslSlide {
content {
h1 { +"DSL" }
h2 { +"Hello World" }
}
}
}
}
}
A kslides{}
block (example)
contains configuration values, output directives, presentation configuration defaults,
css defaults, and presentation definitions. The child blocks can be declared in any order.
Name | Default | Description |
---|---|---|
css | "" | String alternative to the css{} block |
kslides {
kslidesConfig {} // Optional
presentationConfig {} // Optional
output {} // Optional
css {} // Zero or more css blocks
presentation {} // One or more presentations
}
-
A
kslidesConfig{}
block (example) specifies the kslides configuration for all presentations and has these options. -
A
presentationConfig{}
block (example) specifies the default presentation configuration values for all presentations and has these options. -
An
output{}
block (example) specifies how and where presentation slides are published and has these options. -
A
css{}
block (example) applies to all presentations and uses Kotlin CSS DSL calls. Presentation CSS can also be specified using multi-line strings example. A combination of the two approaches is also allowed. -
A
presentation{}
block (example) includes one or more slide descriptions. There are 3 types of slides: MarkdownSlide, HtmlSlide and DslSlide.
presentationConfig { // Optional
menuConfig {} // Optional
copyCodeConfig {} // Optional
playgroundConfig { // Optional
css{} // Optional
}
plotlyIframeConfig {} // Optional
slideConfig {} // Optional
}
-
A
menuConfig{}
block (example) specifies the configuration for the reveal.js Menu plugin and has these options. -
A
copyCodeConfig{}
block specifies the configuration for the reveal.js CopyCode plugin and has these options. -
A
playgroundConfig{}
block (example) specifies the default attributes for Kotlin Playground iframes and has these options.- The
css{}
block inside theplaygroundConfig{}
block specifies the css for the playground content that is displayed in the iframe. It is usually used to control the font-size of the code. The css values can be specified via multi-line strings or using the CSS DSL.
- The
-
A
plotlyIframeConfig{}
block specifies the default attributes for plotly-kt iframes and has these options. -
A
slideConfig{}
block specifies the default slide configuration values for all slides and has these options.
Multiple presentations can be defined using multiple presentation{}
blocks, each with
a different path
value.
Name | Default | Description | Usage |
---|---|---|---|
path | "/" | Presentation directory or filename | example |
css | kslides.css value | String alternative to the css{} block | example |
cssFiles | kslides.kslidesConfig.cssFiles value | List for including additional css files | |
jsFiles | kslides.kslidesConfig.jsFiles value | List for including additional js files |
presentation {
presentationConfig {} // Optional
css {} // Zero or more css blocks
markdownSlide {} // One or more slides
htmlSlide {}
dslSLide {}
verticalSlide {
htmlSlide {}
dslSLide {}
}
}
-
A
presentationConfig{}
block specifies presentation-specific configuration values and has these options. This block overrides the values specified in kslides.presentationConfig{}. -
A
css{}
block applies to this specific presentation and uses Kotlin CSS DSL calls. Presentation CSS can also be specified using raw CSS strings. A combination of the two approaches is also allowed.
Unlike CSS values in HTML files, which must be specified in the head, css{}
blocks can be placed
throughout a presentation in kslides. It is convenient to have the CSS values near code in the slides where
they are referenced.
Name | Default | Description |
---|---|---|
classes | "" | class value for underlying html tag |
id | "" | id value for underlying html tag |
style | "" | style value for underlying html tag |
hidden | false | Details |
uncounted | false | Details |
autoAnimate | false | Details |
autoAnimateRestart | false | Details |
Name | Default | Description |
---|---|---|
filename | false | Details |
markdownSlide {
slideConfig {} // Optional
content {} // Required
}
htmlSlide {
slideConfig {} // Optional
content {} // Required
}
dslSlide {
slideConfig {} // Optional
content {} // Required
}
A slideConfig{}
block specifies slide-specific configuration values and has these
options
.
This block overrides the values specified in kslides.presentationConfig.slideConfig{} and
kslides.presentation.presentationConfig.slideConfig{}.
content{}
block contents vary by the type of the slide:
MarkdownSlide.content{}
blocks contain a String with MarkdownHtmlSlide.content{}
blocks contain a String with HTMLDslSlide.content{}
block contains calls to the Kotlin HTML DSLverticalSlides{}
block contains other slides
A verticalSlides{}
block (exammple)
contains one or more slides and presents them vertically.
Name | Default | Description |
---|---|---|
classes | "" | class value for underlying html tag |
id | "" | id value for underlying html tag |
style | "" | style value for underlying html tag |
verticalSlides {
dslSLide {} // One or more slides
markdownSlide {}
htmlSlide {}
}
These functions are defined here. Examples of their usage can be found here.
Function name | Context | Description | Usage |
---|---|---|---|
slideBackground() |
MarkdownSlides | ||
fragment() |
MarkdownSlides | example | |
HTMLTag.rawHtml() |
DslSlides | Allows embedding of raw HTML in a DslSlide | |
List<T>.permuteBy() |
Animations | example | |
String.toLinePatterns() |
Animations | example | |
githubRawUrl() |
include() calls | Returns URL for raw github content | example |
include() |
All Slides | Preferred to embedding raw code in slides | example |
The include()
call accepts a filename or a URL src argument. A filename value is relative to the root of the repo
and a URL value requires an http:// or https:// prefix.
DslSlide-specific functions are defined here. Examples of their usage can be found here.
Function name | Description | Usage |
---|---|---|
DslSlide.codeSnippet{} |
Embeds a code snippet | example |
DslSlide.playground{} |
Embeds a Kotlin Playground | example |
DslSlide.plotly{} |
Embeds a plotly-kt figure | example |
DslSlide.diagram{} |
Embeds a diagram | example |
FlowContent.unorderedList{} |
Generates an unordered list | example |
FlowContent.orderedList{} |
Generates an ordered list | example |
LI.listHref() |
Generates a list href | example |
THEAD.headRow() |
Generates a table header row | example |
TBODY.bodyRow() |
Generates a table body row | example |
kslides requires some Kotlin-specific knowledge:
This plugin makes it much easier to work with
HTML. Just copy some HTML into your copy buffer, and when you paste it, the plugin will give you
the option to convert it into Kotlin HTML DSL code. Install it in IntelliJ by going to
"Plugins" and searching for HTML to kotlinx.html
in "Marketplace"
Disable the IntelliJ Reformat code
and Rearrange code
options when you commit to git.
The code in the presentation html files are space-sensitive and might not work if they are reformatted.
CSS values can be specified in a css{} blocks in a presentation, but they also can be specified in
the src/main/resources/slides.css
file. The contents of that file are embedded directly into
the presentation HTML files. Make sure to run ./gradlew clean build
after making changes to slides.css.
Presentations served by HTTP load static content from /src/main/resources/public
, whereas
filesystem presentations load static content from /docs
.
Make sure to run ./gradlew clean build
after making changes to /src/main/resources/public
.
Rather than embedding code directly in MarkdownSlides, it is much better to use the
include()
call. You are likely to have formatting issues if you embed code directly
in the slide.
If you choose to embed code directly in the slide, remove indentation in the content{}
block.
Speaker Notes do not work properly when running locally. They will work from GitHub, Netlify, or Heroku though.
A DslSlide embeds Playground content with an iframe.
If output.enableFileSystem
is true, each playground()
call generates
an html file in docs/playground
.
Playground code using dataTargetPlatform = JUNIT
should not have a package
decl.
A DslSlide embeds plotly-kt content with an iframe.
If output.enableFileSystem
is true, each plotly()
call generates an html file in docs/plotly
.
The plotly()
iframeConfig args are the attributes for the iframe referencing the plotly-kt content.
The plotly()
dimensions are automatically added as the width and height values
in a Plot.layout{}
block, thus controlling the dimensions of the plotly-kt content.
The dimensions and the iframeConfig args must be synchronized. Specifically, the dimensions.width value must work with the width value in the iframeConfig.style, and the dimensions.height value must work with the iframeConfig.height value.
Adding border: 1px solid black;
to iframeConfig.style makes it easier to synchronize the dimension values.
Once the iframe and content width and height values are correct, you can remove the border.
If additional space is required for plotly output, you can adjust the slide presentation space with the PresentationConfig.width and PresentationConfig.height values. More details can be found here.
KSlides supports using Kroki to generate diagrams. Kroki supports a wide variety of diagram types. Example diagrams can be seen here and here.
Each diagram type has its own set of configuration options. The options are specified with an options
value.
The options values are specified as a map and the possible option values are listed in
the Kroki documentation.
The outputType
value specifies the image type and defaults to DiagramOutputType.SVG
. As indicated in the
Kroki docs, not all output types apply to all diagram types.
The style
value specifies the CSS style for the image.
The content
value specifies the diagram content.
Niolesk is a great tool for generating Kroki diagrams.
Go to your Heroku dashboard, choose your kslides app and click
on Settings->Reveal Config Vars and add a config var: GRADLE_TASK=-Pprod=true uberjar
When a markdownSlide
is in a verticalSlides{}
block and references an external file, the string "---"
is interpreted as a vertical page separator and "--- " (with a space suffix) is rendered as a markdown horizontal
line.
If you want to move slide content into a function, be aware that there are two versions of
dslSlide{}
, markdownSlide{}
, and htmlSlides{}
. Each version has different contexts, depending on whether it
is in a VerticalSlidesContext
context. Examples of both versions
are here.