Skip to content

Instantly share code, notes, and snippets.

@lelanthran
Last active August 17, 2023 06:43
Show Gist options
  • Save lelanthran/2634fc2508c93a437ba5ca511fafa99d to your computer and use it in GitHub Desktop.
Save lelanthran/2634fc2508c93a437ba5ca511fafa99d to your computer and use it in GitHub Desktop.
Generate html devlog from chap1/content.md, chap2/content.md, etc
#!/bin/bash
# Usage notes:
# 1. Make sure that pandoc is installed.
# 2. Place all your contents for each chapter of your devlog into
# `./chap1/content.md`, `./chap2/content.md`, etc.
# 3. This script will source a file in each chapter called METAINFO.inc. This
# file is optional and can contain two variable declarations:
# AUTHOR="Name Of Author"
# DATE="Date or publication"
# 4. Set the name of your devlog in the variable DEVLOG_NAME, and an image for
# the contents page in CONTENTS_IMAGE
export DEVLOG_NAME="Interesting things"
export CONTENTS_IMAGE="./c64.gif"
export CONTENTS_IMAGE_CAPTION="_"
# 5. Run this script in the directory containing all the chap[0-9]
# subdirectories.
export PANDOC="pandoc -c style.css -c ../style.css --from markdown+fenced_code_attributes+implicit_header_references+footnotes --to html5 --standalone --highlight-style=zenburn"
MIN=$1
MAX=$2
if [ -z "$MIN" ]; then
echo No minimum specified as first argument, using 1 as minimum.
MIN=1
fi
if [ -z "$MAX" ]; then
echo No maximum specified as second argument, using 300 as maximum.
MAX=300
fi
NAVCODE='
<script type="module" src="../components.js"></script>
<hr>
<div class=navbar>
<div class=nav-prev> <a href=PLINK>PTITLE</a> </div>
<div class=nav-up> <a href=../toc.html> Contents</a> </div>
<div class=nav-next> <a href=NLINK>NTITLE</a> </div>
</div>
<div> AUTHOR </div>
<div> </div>
<div> DATE </div>
'
# Before we do anything, we record our current directory, then switch
# to the directory holding the script. This lets us run devlog.sh from
# any directory; a useful thing when I am working in a chapter directory.
NEWDIR="`dirname $0`"
pushd $PWD &> /dev/null
cd $NEWDIR
echo Temporarily switched to $PWD
echo "% $DEVLOG_NAME" > toc.md
echo '% ' >> toc.md
echo '' >> toc.md
echo '| |' >> toc.md
echo '| :---: |' >> toc.md
echo "| ![$DEVLOG_NAME]($CONTENTS_IMAGE){class=image}|" >> toc.md
# echo "| *$CONTENTS_IMAGE_CAPTION* |" >> toc.md
# echo '| |' >> toc.md
echo '' >> toc.md
cat content-preamble.md >> toc.md
echo '# Blog Posts ' >> toc.md
echo '' >> toc.md
PREVIOUS=$(($MIN - 1))
NEXT=$(($MAX + 1))
for X in `seq $MAX -1 $MIN`; do
DIR="chap$X"
if [ ! -d $DIR ]; then
continue;
fi
. "chap$X/METAINFO.inc" &> /dev/null
if [ ! -z "$AUTHOR" ]; then
AUTHOR="Posted by $AUTHOR"
fi
PREVIOUS=$(($X - 1))
NEXT=$(($X + 1))
PREVIOUS_LINK=""
PREVIOUS_TITLE=""
NEXT_LINK=""
NEXT_TITLE=""
if [ $PREVIOUS -gt 0 ]; then
PREVIOUS_LINK="../chap$PREVIOUS/content.html"
PREVIOUS_TITLE="previous:<br>`head -n 1 chap$PREVIOUS/content.md | sed 's/% //g'`"
fi
if [ -f chap$NEXT/content.md ]; then
NEXT_LINK="../chap$NEXT/content.html"
NEXT_TITLE="next:<br>`head -n 1 chap$NEXT/content.md | sed 's/% //g'`"
fi
TOC_LINE1="<a class=tableOfContents href=./chap$X/content.html>"
TOC_LINE2="<div class=tableOfContentsItem>$DATE</div>"
TOC_LINE3="<div class=tableOfContentsItem>`head -n 1 ./chap$X/content.md | sed 's/% //g'` </div>"
TOC_LINE4="</a>"
echo $TOC_LINE1 >> toc.md
echo $TOC_LINE2 >> toc.md
echo $TOC_LINE3 >> toc.md
echo $TOC_LINE4 >> toc.md
NAV=`echo $NAVCODE | sed \
"s!PLINK!$PREVIOUS_LINK!g;
s!PTITLE!$PREVIOUS_TITLE!g;
s!NLINK!$NEXT_LINK!g;
s!NTITLE!$NEXT_TITLE!g;
s!AUTHOR!$AUTHOR!g;
s!DATE!$DATE!g;
"`
INPUT="chap$X/content.md"
OUTPUT="chap$X/content.html"
sed "s+XXX_NAVBAR_XXX+$NAV+g" < $INPUT > tmpfile
$PANDOC -o $OUTPUT tmpfile
echo "$INPUT -> $OUTPUT"
done
$PANDOC -o toc.html toc.md
echo Restoring original directory
popdir &> /dev/null
/* First, define all the colors */
:root {
--font-size: 10;
}
/* Set the values for dark/light preferences */
@media (prefers-color-scheme: dark) {
:root {
--header-logo-img-invert-10: 10%;
--header-logo-img-invert-20: 20%;
--header-logo-img-invert-30: 30%;
--color-bg-blockquote: #2b2b2b;
--color-border-blockquote: #bdbdbd;
--color-fg-blockquote: #bdbdbd;
--color-bg-content: #050005;
--color-fg-content: #ababab;
--color-bg-page: #080008;
--color-bg-table: var(--color-bg-content);
--color-bg-table-even: #0a000a;
--color-bg-table-odd: var(--color-bg-content);
--color-border-table: var(--color-fg-content);
--color-bg-thead: #150015;
--color-fg-thead: var(--color-fg-content);
--color-fg-link: #1ea0f1;
--color-fg-link-visited: #ffb8d1;
--color-border-link: var(--color-bg-content);
--color-border-link-active: #a593e0;
--color-border-link-hover: #a593e0;
--color-fg-code: #6fcf97;
--color-fg-header: #bdbdbd;
}
.light-mode-image {
display: none;
}
.dark-mode-image {
display: block;
}
}
@media (prefers-color-scheme: light) {
:root {
--header-logo-img-invert-10: 0%;
--header-logo-img-invert-20: 0%;
--header-logo-img-invert-30: 0%;
--color-bg-blockquote: #fbfbfb;
--color-border-blockquote: #2b2b2b;
--color-fg-blockquote: #2b2b2b;
--color-bg-content: #e9e9ff;
--color-fg-content: #4b4b4b;
--color-bg-page: #e0e0ff;
--color-bg-table: var(--color-bg-content);
--color-bg-table-even: #dfdfff;
--color-bg-table-odd: var(--color-bg-content);
--color-border-table: var(--color-fg-content);
--color-bg-thead: #c0c0f0;
--color-fg-thead: var(--color-fg-content);
--color-fg-link: #0e19e1;
--color-fg-link-visited: #df18b1;
--color-border-link: var(--color-bg-content);
--color-border-link-active: #a593e0;
--color-border-link-hover: #a593e0;
--color-fg-code: #0f8507;
--color-fg-header: #2b2b2b;
}
.light-mode-image {
display: block;
}
.dark-mode-image {
display: none;
}
}
/* Small Phones */
@media (max-width:359px) {
:root {
--toc-width: 100%;
--body-max-width: 100%;
--code-font-size: 12px;
--font-size: 14px;
--h1-font-size: 18px;
--h2-font-size: 17px;
--h3-font-size: 15px;
}
}
/* Large Phones */
@media (min-width:360px) and (max-width:599px) {
:root {
--toc-width: 100%;
--body-max-width: 100%;
--code-font-size: 14px;
--font-size: 16px;
--h1-font-size: 22px;
--h2-font-size: 20px;
--h3-font-size: 18px;
}
}
/* Portrait Tablet */
@media (min-width:600px) and (max-width:899px) {
:root {
--toc-width: 100%;
--body-max-width: 95%;
--code-font-size: 16px;
--font-size: 18px;
--h1-font-size: 24px;
--h2-font-size: 22px;
--h3-font-size: 20px;
}
}
/* Landscape Tablet */
@media (min-width:900px) and (max-width:1199px) {
:root {
--toc-width: 100%;
--body-max-width: 85%;
--code-font-size: 14px;
--font-size: 16px;
--h1-font-size: 22px;
--h2-font-size: 20px;
--h3-font-size: 18px;
}
}
/* Desktop */
@media (min-width:1200px) and (max-width:1920px) {
:root {
--toc-width: 100%;
--body-max-width: 72ch;
--code-font-size: 14px;
--font-size: 16px;
--h1-font-size: 22px;
--h2-font-size: 20px;
--h3-font-size: 18px;
}
}
/* 4K screen */
@media (min-width:1921px) {
:root {
--toc-width: 100%;
--body-max-width: 120ch;
--code-font-size: 18px;
--font-size: 20px;
--h1-font-size: 32px;
--h2-font-size: 28px;
--h3-font-size: 24px;
}
}
/* ************************************************ */
html {
margin: auto;
background-color: var(--color-bg-page);
}
body {
vertical-align: middle;
background-color: var(--color-bg-content);
color: var(--color-fg-content);
font-size: var(--font-size);
line-height: 1.5em;
font-family: sans-serif;
max-width: var(--body-max-width);
padding: 2em;
margin: 0 auto 0 auto;
box-shadow: 0px 0px 20px 0px #464646ff;
}
a:link {
color: var(--color-fg-link);
border-style: dashed;
border-width: 1px;
border-color: var(--color-border-link);
}
a:visited {
color: var(--color-fg-link-visited);
border-style: dashed;
border-width: 1px;
border-color: var(--color-border-link);
}
a:active {
border-style: dashed;
border-width: 1px;
border-color: var(--color-border-link-active);
}
a:hover {
border-style: dashed;
border-width: 1px;
border-color: var(--color-border-link-hover);
}
h1,
h2,
h3 {
font-size: var(--h1-font-size);
color: var(--color-fg-header);
padding-top: 1.5ex;
text-transform: lowercase;
}
h1 {
text-align: right;
text-transform: lowercase;
}
h2 {
font-size: var(--h2-font-size);
}
h3 {
font-size: var(--h3-font-size);
}
p {
text-indent: 1.5em;
}
li {
padding-bottom: 1.0ex;
}
.sourceCode {
font-size: var(--code-font-size);
overflow: scroll;
line-height: 1.25ex;
}
table {
margin-left: auto;
margin-right: auto;
border-style: solid;
border-width: 0px;
border-color: var(--color-border-table);
border-spacing: 0px;
background-color: var(--color-bg-table);
}
thead {
background-color: var(--color-bg-thead);
color: var(--color-fg-thead);
}
th,
td {
padding-bottom: 5px;
padding-left: 5px;
padding-right: 5px;
}
.odd {
background-color: var(--color-bg-table-odd);
}
.even {
background-color: var(--color-bg-table-even);
}
.navbar {
width: 100%;
font-size: smaller;
display: grid;
grid-template-columns: auto auto auto;
padding-bottom: 2ex;
padding-top: 2ex;
}
.nav-prev {
text-align: left;
}
.nav-up {
text-align: center;
}
.nav-next {
text-align: right;
}
code {
font-size: var(--font-size);
font-family: courier;
}
.tableOfContents {
width: var(--toc-width);
margin: 0 auto 0 auto;
font-size: larger;
text-transform: lowercase;
display: grid;
grid-template-columns: 15ch auto;
}
.tableOfContentsItem {
text-align: left;
padding: 0px 0px 15px 0px;
}
blockquote {
font-style: italic;
border-style: solid;
border-width: 1px;
border-color: var(--color-border-blockquote);
padding-left: 25px;
padding-right: 25px;
color: var(--color-fg-blockquote);
background-color: var(--color-bg-blockquote);
}
p > code, em > code, b > code {
font-size: var(--code-font-size);
color: var(--color-fg-code);
}
.filter--10 {
filter: invert(var(--header-logo-img-invert-10));
}
.filter--20 {
filter: invert(var(--header-logo-img-invert-20));
}
.filter--30 {
filter: invert(var(--header-logo-img-invert-30));
}
.no--border {
border-width: 0px;
}
.image {
max-width: 90%;
margin: 0 auto 0 auto;
text-align: center;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment