Skip to content

Instantly share code, notes, and snippets.

@markusfisch
Last active February 23, 2022 13:37
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save markusfisch/eff723d3445839fc4eb5 to your computer and use it in GitHub Desktop.
Save markusfisch/eff723d3445839fc4eb5 to your computer and use it in GitHub Desktop.
Convert Markdown files to simple web presentations

Markdown To Takahashi Presentation

BASH script to create a single file Takahashi web presentation from a Markdown document.

Dependencies

You'll need a Markdown converter named markdown in your path and BASH.

How does it work?

Every line with a H1, H2, H3, IMG or VIDEO element, and every PRE or UL block, becomes a slide.

Example

Run the script with this file:

./takahashi README.md > README.html

The idea is to show the HTML file on the big screen but keep the source document as a note while presenting.

#!/usr/bin/env bash
# Close slide
slide_close() {
cat <<EOF
</div>
EOF
((N - 2 > 0)) && cat <<EOF
<a href="#slide$((N - 2))" class="Prev">&#9664;</a>
EOF
[ "$1" ] || cat <<EOF
<a href="#slide$((N))" class="Next">&#9654;</a>
</li>
EOF
}
# Open slide
slide_open() {
cat <<EOF
<li class="Slide">
<a name="slide$N" class="Anchor">&nbsp;</a>
<div class="SlideContent">
EOF
}
# Open a new slide, close the previous one
slide_new() {
((N > 1)) && slide_close
slide_open
((++N))
echo "$REPLY"
}
# Generate slides from HTML
html_to_slides() {
local N=1 ECHO=0
while read -r
do
case $REPLY in
*\</pre\>*|*\</ul\>*)
ECHO=0
;;
*\<pre\>*|*\<ul\>*)
ECHO=1
slide_new
;;
*\<h[123]\>*|*\<video*|*\<img*\>*)
slide_new
;;
'')
((ECHO)) && echo "$REPLY"
;;
*)
((ECHO)) && echo "$REPLY"
;;
esac
done
((N > 1)) && slide_close true
}
# Print HTML frame
html() {
cat <<EOF
<!doctype html>
<html class="Background">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width"/>
<title>${TITLE}</title>
<style>
.Background {
background: #fff;
height: 100%;
margin: 0; padding: 0;
overflow: hidden;
font: 18pt sans-serif; color: #333;
font-weight: lighter;
letter-spacing: .05em;
line-height: 150%;
}
.Content {
margin: 0; padding: 0;
}
.Slides {
margin: 0; padding: 0;
list-style: none;
}
.Slide {
position: relative;
margin: 0; padding: 0;
height: 100vh;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.SlideContent {
position: absolute;
top: 50%;
left: 0; right: 0;
-webkit-transform: translateY( -50% );
transform: translateY( -50% );
max-width: 30em;
margin: 0 auto; padding: 0 1em;
text-align: center;
outline: 0;
}
.Prev,
.Next {
display: block;
position: absolute;
bottom: 0;
margin: 0; padding: 1em;
text-decoration: none;
color: #ddd;
font-weight: bolder;
}
.Prev {
left: 0;
}
.Next {
right: 0;
}
.Anchor {
display: block;
position: absolute;
left: 0; top: 0;
}
h1 {
margin-top: 0;
}
h1, h2, h3 {
line-height: 150%;
}
a {
color: #4080ff;
}
ul {
list-style: none;
}
pre {
font: 16pt monospace;
letter-spacing: normal;
text-align: left;
}
img,
video {
max-width: 100%;
max-height: 80vh;
}
@media screen and (max-width: 400px), screen and (max-height: 400px) {
.Background {
font-size: 8pt;
}
}
</style>
</head>
<body class="Content">
<ul class="Slides">
$(html_to_slides)
</ul>
</body>
</html>
EOF
}
# Generate a HTML5 presentation
#
# @param ... - Markdown files to convert into slides
generate() {
local FILE TITLE=$TITLE
if [ -z "$TITLE" ]
then
TITLE=${1##*/}
TITLE=${TITLE%.*}
TITLE=${TITLE//[_-]/ }
fi
for FILE
do
[ -r "$FILE" ] || {
echo "error: $FILE does NOT exist" >&2
continue
}
ruby << EOF
require 'commonmarker'
print CommonMarker.render_html(File.read("$FILE"), :UNSAFE)
EOF
done | html
}
if [ "${BASH_SOURCE[0]}" == "$0" ]
then
if (($# > 1))
then
echo "usage: ${0##*/} FILE..."
else
generate "$@"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment