pdssg

[sh] Bodged Pandoc static site generator
git clone https://git.torresjrjr.com/pdssg.git
Log | Files | Refs | README | LICENSE

pdssg (5741B)


      1 #!/bin/sh
      2 # pdssg - pandoc static site generator
      3 # Makes a static site with Atom feeds.
      4 
      5 main() {
      6 	echo "### Begin compiling ###"
      7 	date
      8 
      9 	prepare_dst "$1"
     10 	find_feeds
     11 
     12 	for post_dir in ${POSTS_DIRS}
     13 	do cache_posts_metadata ${post_dir}
     14 	done
     15 
     16 	process_files ${MD_FILES}
     17 
     18 	for post_dir in ${POSTS_DIRS}
     19 	do make_atom_feed ${post_dir}
     20 	done
     21 
     22 	clearup_files ${MD_FILES}
     23 	finish
     24 
     25 	echo
     26 	echo "### End compiling ###"
     27 	date
     28 }
     29 
     30 
     31 # main functions
     32 
     33 prepare_dst() {
     34 	NOW_DATETIME="$(date -uIs)"
     35 	
     36 	ROOTDIR="$1"
     37 	cd "$ROOTDIR"
     38 
     39 	echo
     40 	echo "# Preparing ./dst/ directory"
     41 
     42 	[ -d ./src/ ] || {
     43 		echo "No  ./src/  directory, exiting"
     44 		exit
     45 	}
     46 
     47 	echo "Copying from  ./src/  to  ./dst/"
     48 	copiable=$(
     49 		find ./src/ \
     50 			-maxdepth 1 \
     51 			-regex '\./src/_.*'
     52 		find ./src/ \
     53 			-maxdepth 1 \
     54 			-regex '\./src/[^._].*' \
     55 			-newer ./src/.last_build
     56 	)
     57 	[ -n "$copiable" ] && cp -rv $copiable ./dst
     58 
     59 	cd ./dst/
     60 
     61 	echo "Preparing temporary directory for cache"
     62 	# NOTE: POPF (Point Of Potential Failure)
     63 	TMP_DIR="./_tmp"
     64 	[ -d ${TMP_DIR} ] || mkdir ${TMP_DIR}
     65 
     66 	echo "Gathering unignored Markdown files"
     67 	IGNORE_MD_FILE="_ignore"
     68 	touch ${IGNORE_MD_FILE}
     69 	MD_FILES=$(
     70 		find . -regex '.*\.md'  \
     71 		| grep -v '.*/_.*'  \
     72 		| grep -v -F -f ${IGNORE_MD_FILE}
     73 	)
     74 	rm ${IGNORE_MD_FILE}
     75 
     76 	ASSETS_DIR="./ast" # No ending slash!
     77 	echo "Finding CSS files in assets directory ${ASSETS_DIR}"
     78 	stylesheets=$(
     79 		find ${ASSETS_DIR} \
     80 			-regex ".*/[^.]*\.css" \
     81 			-newer ../src/.last_build \
     82 	)
     83 	for stylesheet in ${stylesheets}
     84 	do
     85 		echo "Minifying ${stylesheet}"
     86 		min_stylesheet="${stylesheet%.css}.min.css"
     87 		cat ${stylesheet} | tr -d '\n' | sed '
     88 			s|\s*\([:;,{}()]\)\s*|\1|g
     89 			s|;\}|\}|g
     90 			s|\t||g
     91 			s/\/\*\|\*\//\t/g
     92 			s|\t[^\t]*\t||g
     93 		' > ${min_stylesheet}
     94 	done
     95 
     96 	touch ../src/.last_build
     97 }
     98 
     99 find_feeds() {
    100 	echo
    101 	echo "# Finding feed gen directories"
    102 
    103 	#ATOM_SEEDS=$(find -type f  -path '*.feed.md' | sed 's|index\.feed\.md$||')
    104 	#POSTS_DIRS=$(echo "${ATOM_SEEDS}" | sed -e "s|^${FEEDS_DIR}|.|" -e 's|\.md$||')
    105 	POSTS_DIRS=$(find -type f  -path '*.feed.md' | sed 's|index\.feed\.md$||')
    106 
    107 	echo ${ATOM_SEEDS}
    108 
    109 	for posts_dir in ${POSTS_DIRS}
    110 	do
    111 		[ -d ${posts_dir} ] || {
    112 			echo "ERROR:"
    113 			echo "Atom seed ${FEEDS_DIR}/${posts_dir}.md has no corresponding"
    114 			echo "Directory ${posts_dir}. Exiting."
    115 			exit 1
    116 		}
    117 
    118 		echo "${posts_dir} exists"
    119 	done
    120 }
    121 
    122 cache_posts_metadata() {
    123 	echo
    124 	echo "# Caching post metadata" "($1)"
    125 
    126 	posts_dir=$1
    127 	cache_file="${TMP_DIR}/${posts_dir}/meta.yaml"
    128 
    129 	env printf 'Preparing cache file: %s\n' "${cache_file}"
    130 
    131 	mkdir -p $(dirname ${cache_file})
    132 	echo "log:" > ${cache_file}
    133 
    134 	for post in ${posts_dir}/*/index.md
    135 	do
    136 		env printf 'Caching: %s\n' "${post}"
    137 
    138 		post_yaml="$(_get_yaml_block ${post})"
    139 		slug=$(basename $(dirname ${post}))
    140 		slug_attr="slug: ${slug}"
    141 		yaml_block="$(
    142 			env printf '%s\n' "${post_yaml}" "${slug_attr}" \
    143 			| sed 's/^/    /'
    144 		)"
    145 
    146 		echo "  -"         >> ${cache_file}
    147 		echo "${yaml_block}" >> ${cache_file}
    148 	done
    149 
    150 	echo "Cache file done"
    151 }
    152 
    153 process_files() {
    154 	echo
    155 	echo "# Processing Markdown files"
    156 	echo
    157 	pandoc --version
    158 	echo
    159 
    160 	for md_file in $@
    161 	do
    162 		env printf 'Processing: %s\n' "${md_file}"
    163 
    164 		### prepare flags for pandoc conversion ###
    165 		new_filepath=${md_file%.md}.html
    166 
    167 		block="$( _get_yaml_block "${md_file}" )"
    168 		bool_toc="$(_get_safe_slug toc "${block}")"
    169 		[ -n "${bool_toc}" ] && flag_toc="--toc"
    170 
    171 		### feed gen directory test ###
    172 		cache_file="${TMP_DIR}/${md_file%index.md}meta.yaml"
    173 		[ -f "${cache_file}" ] && {
    174 			flag_metadata_file="--metadata-file=${cache_file}"
    175 		}
    176 
    177 		[ "$md_file" = ./index.md ] && {
    178 			flag_metadata_file="--metadata-file=$TMP_DIR/archive/meta.yaml"
    179 		}
    180 
    181 		### article test ###
    182 		cache_file="${TMP_DIR}/$(dirname $(dirname ${md_file}))/meta.yaml" 
    183 		[ -f "${cache_file}" ] && {
    184 			flag_is_article="-M is_article:true"
    185 		}
    186 
    187 		### create full HTML page ###
    188 		pandoc  \
    189 			-f markdown  -t html  \
    190 			${md_file}  -o ${new_filepath}  \
    191 			-M lang:en  \
    192 			-M document-css=false  \
    193 			--standalone  \
    194 			--wrap=none \
    195 			--preserve-tabs \
    196 			--template=./_templates/main.html  \
    197 			-H ./_includes/meta.html  \
    198 			-B ./_includes/header.html  \
    199 			-A ./_includes/footer.html  \
    200 			--email-obfuscation=references  \
    201 			--highlight-style=breezedark  \
    202 			--webtex='https://latex.codecogs.com/svg.latex?'  \
    203 			${flag_toc}  \
    204 			${flag_metadata_file}  \
    205 			${flag_is_article}  \
    206 
    207 		### prepare for next md file
    208 		unset flag_toc
    209 		unset flag_metadata_file
    210 		unset flag_is_article
    211 	done
    212 }
    213 
    214 make_atom_feed() {
    215 	echo
    216 	echo "# Making atom feed" "($1)"
    217 	echo "Making base feed document"
    218 
    219 	posts_dir="$1"
    220 	cache_file="${TMP_DIR}/${posts_dir}/meta.yaml"
    221 	atom_seed="${posts_dir}/index.feed.md"
    222 	atom_out="${posts_dir}/index.xml"
    223 
    224 	pandoc  \
    225 		-f markdown  -t html  \
    226 		${atom_seed}  -o ${atom_out}  \
    227 		--metadata-file=${cache_file}  \
    228 		-M "date:${NOW_DATETIME}" \
    229 		-M lang:en  \
    230 		--standalone  \
    231 		--template=./_templates/atom.xml
    232 
    233 	rm -v ${atom_seed}
    234 	cat ${atom_out}  > ${TMP_DIR}/atom.xml
    235 
    236 	echo "Finishing feed"
    237 	cat ${TMP_DIR}/atom.xml  > ${atom_out}
    238 }
    239 
    240 clearup_files() {
    241 	echo
    242 	echo "# Clearing up Markdown files"
    243 
    244 	[ $# -gt 0 ] && rm -v "$@"
    245 	rm -rv $( find . -regex '.*/_.*' | sort -r )
    246 }
    247 
    248 finish() {
    249 	echo
    250 	echo "# Finished compiling"
    251 
    252 	cd ..
    253 	echo "Finished"
    254 }
    255 
    256 
    257 # util functions
    258 
    259 _get_yaml_block() {
    260 	md_file="$1"
    261 	block="$(sed -n -e '1,/---/p' ${md_file} | grep -v '\-\-\-')"
    262 	echo "${block}"
    263 }
    264 
    265 _get_safe_slug() {
    266 	key="$1"
    267 	block="$2"
    268 
    269 	line=$(echo "${block}" | grep "^${key}\s*:\s*")
    270 	title=$(echo ${line} | sed -e "s/^${key}\s*:\s*//")
    271 	slug=$(echo ${title} | sed -e 's/\s*$//' -e 's/\s\+/-/g')
    272 	safe_slug=$(
    273 		echo ${slug}  \
    274 		| tr '[:upper:]' '[:lower:]'  \
    275 		| tr -cd "[:alpha:][:digit:]-"
    276 	)
    277 	echo ${safe_slug}
    278 }
    279 
    280 
    281 # main
    282 
    283 main "$@"
    284