Skip to content

Instantly share code, notes, and snippets.

@kellpossible
Last active March 20, 2024 01:05
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kellpossible/a6081e945d815560be630de322fb0a1f to your computer and use it in GitHub Desktop.
Save kellpossible/a6081e945d815560be630de322fb0a1f to your computer and use it in GitHub Desktop.
Capture the output of https://github.com/maaslalani/slides and produce a beamer PDF presentation
#!/bin/bash
# Copyright 2023 Luke Frisken
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the “Software”), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set -e # Exit on any error
pane_width=74
pane_height=24
font="FiraCode Nerd Font Mono"
font_size="10pt"
# Check if required tools are installed
check_tool() {
command -v "$1" >/dev/null 2>&1 || {
echo >&2 "The '$1' command is required but not installed. Please install it using:"
echo >&2 " sudo apt-get install $2"
exit 1
}
}
# Check if required LaTeX packages are installed
check_latex_package() {
kpsewhich "$1.sty" >/dev/null 2>&1 || {
echo >&2 "The '$1' LaTeX package is required but not installed. Please install it using:"
echo >&2 " sudo apt-get install $2"
exit 1
}
}
check_tool tmux tmux
check_tool ansifilter ansifilter
check_tool pandoc pandoc
check_tool xelatex texlive-xetex
check_latex_package fontspec texlive-fonts-extra
# Check if the input file is provided
if [ -z "$1" ]; then
echo "Usage: $0 input_file.md"
exit 1
fi
input_file="$1"
input_base_filename=$(basename "$input_file" .md)
output_prefix="slide"
output_directory="slides"
# Clean and create output directory
rm -rf "$output_directory"
mkdir -p "$output_directory"
slide_index=0
max_retries=100
# Start the TUI application in a new tmux session
tmux new-session -d -s slides -x "$pane_width" -y "$pane_height" "slides $input_file"
sleep 2 # Give some time for the slide to render
while true; do
slide_file="${output_prefix}_${slide_index}.txt"
# Capture the output of the slide
tmux capture-pane -t slides -e -J -p > "${output_directory}/${slide_file}"
echo "captured slide: \n$(cat "${output_directory}/${slide_file}")"
tmux send-keys -t slides 'Right' # Press the right arrow key to go to the next slide
sleep 0.2
# Check if we reached the last slide
if cmp -s "${output_directory}/${output_prefix}_$((slide_index - 1)).txt" "${output_directory}/${slide_file}"; then
echo "we reached the last slide"
rm "${output_directory}/${slide_file}"
break
fi
slide_index=$((slide_index + 1))
# Break the loop after max_retries to avoid infinite loops
if [ "$slide_index" -gt "$max_retries" ]; then
echo "Reached max retries, check your slides application"
break
fi
done
# Kill the tmux session
tmux kill-session -t slides
# Convert captured slides to LaTeX
for txt_file in ${output_directory}/${output_prefix}_*.txt; do
tex_file="${txt_file%.txt}.tex"
ansifilter -i "${txt_file}" -o "${tex_file}" --latex
done
# Create a main LaTeX file
main_tex_file="main.tex"
# Custom LaTeX header for using DejaVu Sans Mono font and defining the \ws command
latex_header="\\documentclass[$font_size,aspectratio=169]{beamer}
\\usepackage{fontspec}
\\setmonofont{$font}[Scale=1]
\\newfontfamily{\fallbackfont}{DejaVu Sans Mono}
\\DeclareTextFontCommand{\textfallback}{\fallbackfont}
\\usepackage{newunicodechar}
\\newunicodechar{⬢}{\textfallback{⬢}}
\\newunicodechar{✦}{\textfallback{✦}}
\\newunicodechar{⠿}{\textfallback{⠿}}
\\newunicodechar{☁}{\textfallback{☁}}
\\newunicodechar{❯}{\textfallback{❯}}
\\usepackage{color}
\\newcommand{\\ws}[1]{\\textcolor[rgb]{0,0,0}{#1}}
\\geometry{margin=0cm}
\\setbeamercolor{background canvas}{bg=black}
\\setbeamercolor{normal text}{fg=white}
\\setbeamertemplate{navigation symbols}{}
\\usepackage{setspace}
\\linespread{0.4}
\\setlength{\\parskip}{0pt} % Remove extra vertical space between paragraphs
\\setlength{\\baselineskip}{0pt} % Remove extra vertical space between lines
\\setlength{\\parindent}{0pt} % Remove paragraph indentation
\\setlength{\lineskiplimit}{0pt}
\\setlength{\lineskip}{0pt}
"
cat > "$main_tex_file" <<EOL
$latex_header
\begin{document}
EOL
# Include each slide as a frame in the main LaTeX file
for tex_file in $(ls ${output_directory}/${output_prefix}_*.tex | sort -V); do
echo "\\begin{frame}[fragile]" >> "$main_tex_file"
# Remove the first 7 lines and the last 2 lines, and add the slide content to the main LaTeX file
total_lines=$(wc -l < "$tex_file")
content_lines=$((total_lines - 9))
tail -n +8 "$tex_file" | head -n "$content_lines" >> "$main_tex_file"
echo "\\end{frame}" >> "$main_tex_file"
done
# End the main LaTeX file
echo "\end{document}" >> "$main_tex_file"
# Compile the main LaTeX file with xelatex
xelatex -interaction=nonstopmode -halt-on-error -output-directory="$output_directory" "$main_tex_file"
# Move the final PDF to the current directory
mv "${output_directory}/main.pdf" "$input_base_filename.pdf"
# Cleanup
rm -rf "$output_directory"
rm "$main_tex_file"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment