mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-02 11:32:42 +00:00
151 lines
5.6 KiB
Fish
151 lines
5.6 KiB
Fish
function gh-wiki --description "Clone a GitHub wiki and build one PDF from its Markdown pages"
|
|
# Usage: gh-wiki <WIKI URL> [-o OUTPUT.pdf] [-t TEMPLATE] [-d] [-k]
|
|
argparse 'h/help' 'o/output=' 't/template=' 'd/docker' 'k/keep' -- $argv
|
|
or return 1
|
|
|
|
if set -q _flag_help; or test (count $argv) -eq 0
|
|
echo "Usage: gh-wiki <WIKI URL> [-o OUTPUT.pdf] [-t TEMPLATE] [-d] [-k]"
|
|
echo " -o Output PDF path (default: <repo>-wiki.pdf in the current directory)"
|
|
echo " -t Pandoc template (default: eisvogel, from ~/.local/share/pandoc/templates)"
|
|
echo " -d Use the pandoc/extra Docker image instead of the local pandoc"
|
|
echo " -k Keep the clone in /tmp"
|
|
return 0
|
|
end
|
|
|
|
# --- Check dependencies ---------------------------------------------
|
|
set -l deps git gum
|
|
set -l engine
|
|
if set -q _flag_docker
|
|
set -a deps docker
|
|
else
|
|
set -a deps pandoc
|
|
# Eisvogel needs a XeTeX engine; tectonic is a self-contained one.
|
|
for e in xelatex tectonic
|
|
command -q $e; and set engine $e; and break
|
|
end
|
|
if test -z "$engine"
|
|
echo "gh-wiki: install xelatex or tectonic, or pass -d to use Docker" >&2
|
|
return 1
|
|
end
|
|
end
|
|
for bin in $deps
|
|
if not command -q $bin
|
|
echo "gh-wiki: '$bin' is not installed" >&2
|
|
return 1
|
|
end
|
|
end
|
|
|
|
set -l url $argv[1]
|
|
|
|
# Accept a plain repo URL and turn it into the wiki URL.
|
|
if not string match -q '*.wiki.git' $url
|
|
set url (string replace -r '(\.git)?/?$' '.wiki.git' $url)
|
|
end
|
|
|
|
# Repo name: https://github.com/user/repo.wiki.git -> repo
|
|
set -l repo (string replace -r '\.wiki\.git$' '' (basename $url))
|
|
set -l clone_dir (mktemp -d /tmp/gh-wiki-$repo-XXXXXX)
|
|
set -l out "$repo-wiki.pdf"
|
|
set -q _flag_output; and set out $_flag_output
|
|
|
|
# --- Clone ----------------------------------------------------------
|
|
gum spin --show-error --spinner dot --title "Cloning $url" -- \
|
|
git clone --quiet --depth 1 $url $clone_dir
|
|
or begin
|
|
gum log --level error "Clone failed: $url"
|
|
rm -rf $clone_dir
|
|
return 1
|
|
end
|
|
|
|
# --- Collect pages --------------------------------------------------
|
|
# Home first, then the rest in alphabetical order. Skip wiki chrome.
|
|
set -l pages
|
|
test -f $clone_dir/Home.md; and set -a pages $clone_dir/Home.md
|
|
for f in (find $clone_dir -maxdepth 1 -name '*.md' | sort)
|
|
set -l name (basename $f)
|
|
string match -q 'Home.md' $name; and continue
|
|
string match -q '_*' $name; and continue
|
|
set -a pages $f
|
|
end
|
|
|
|
if test (count $pages) -eq 0
|
|
gum log --level error "No Markdown pages found in $url"
|
|
rm -rf $clone_dir
|
|
return 1
|
|
end
|
|
gum log --level info "Found "(count $pages)" pages"
|
|
|
|
# --- Build one Markdown source --------------------------------------
|
|
# Each page becomes a chapter. Its own headings move one level down.
|
|
set -l src_name _combined.md
|
|
set -l src $clone_dir/$src_name
|
|
for f in $pages
|
|
set -l title (string replace -a -- '-' ' ' (basename $f .md))
|
|
printf '\n# %s\n\n' "$title" >> $src
|
|
cat $f >> $src
|
|
printf '\n\n' >> $src
|
|
end
|
|
|
|
# --- Shared pandoc options ------------------------------------------
|
|
set -l template eisvogel
|
|
set -q _flag_template; and set template $_flag_template
|
|
set -l common_args \
|
|
--from gfm \
|
|
--shift-heading-level-by=1 \
|
|
--toc --toc-depth=2 \
|
|
--number-sections \
|
|
-M title="$repo Wiki" \
|
|
-M date=(date +%Y-%m-%d) \
|
|
-V titlepage=true \
|
|
-V toc-own-page=true
|
|
|
|
# --- Render ---------------------------------------------------------
|
|
set -l status_code 0
|
|
if set -q _flag_docker
|
|
# pandoc/extra ships pandoc, LaTeX and Eisvogel. Mount the clone as
|
|
# /data, write the PDF there, then move it to the requested path.
|
|
set -l tmp_pdf _out.pdf
|
|
gum spin --show-error --spinner line --title "Rendering $out" -- \
|
|
docker run --rm \
|
|
--volume "$clone_dir:/data" \
|
|
--user (id -u):(id -g) \
|
|
pandoc/extra $src_name -o $tmp_pdf \
|
|
--resource-path /data \
|
|
--template $template --pdf-engine xelatex \
|
|
$common_args
|
|
set status_code $status
|
|
test $status_code -eq 0; and mv $clone_dir/$tmp_pdf $out
|
|
else
|
|
set -l pandoc_args --pdf-engine $engine
|
|
# Tectonic's bundle lacks Eisvogel's default sourcesans/sourcecodepro
|
|
# packages; naming system fonts makes the template skip them.
|
|
test $engine = tectonic; and set -a pandoc_args \
|
|
-V mainfont="Noto Sans" -V monofont="JetBrains Mono"
|
|
set -l data_dir (pandoc --version | string match -r 'User data directory: (.*)' | tail -n1)
|
|
if test -f "$data_dir/templates/$template.latex"; or test -f "$template"
|
|
set -a pandoc_args --template $template
|
|
else
|
|
gum log --level warn "Template '$template' not found; using the pandoc default"
|
|
end
|
|
gum spin --show-error --spinner line --title "Rendering $out" -- \
|
|
pandoc $src -o $out \
|
|
--resource-path $clone_dir \
|
|
$pandoc_args \
|
|
$common_args
|
|
set status_code $status
|
|
end
|
|
|
|
# --- Clean up -------------------------------------------------------
|
|
if set -q _flag_keep
|
|
gum log --level info "Clone kept at $clone_dir"
|
|
else
|
|
rm -rf $clone_dir
|
|
end
|
|
|
|
if test $status_code -ne 0
|
|
gum log --level error "pandoc failed"
|
|
return $status_code
|
|
end
|
|
gum log --level info "Wrote $out"
|
|
end
|