#!/bin/bash
-cd "$(dirname "$0")"
+cd "$(dirname "$0")" || exit
set -C
+: "${DEBUGGING:=0}"
+
function note() {
- echo "$fname:$((lidx + 1)): note: $@"
+ echo "$fname:$((lidx + 1)): note: $*"
}
function warn() {
- echo "$fname:$((lidx + 1)): warning: $@" >&2
+ echo "$fname:$((lidx + 1)): warning: $*" >&2
}
function fatal() {
- echo "$fname:$((lidx + 1)): fatal: $@" >&2
+ echo "$fname:$((lidx + 1)): fatal: $*" >&2
exit 1
}
line="${lines[++lidx]}"
}
+function prev_line() {
+ line="${lines[--lidx]}"
+}
+
function skip_comments() {
while [[ "$line" =~ ^"<!--" ]]; do
next_line
done
}
+function write_file() {
+ local f="$1" parent
+ parent="$(dirname "$f")"
+ shift
+ if ((DEBUGGING)); then
+ echo $'\x1b[32;45;1m'"$f"$'\x1b[m'
+ printf "%s\n" "$@"
+ else
+ mkdir -p "$parent" || fatal "failed to create directory $parent"
+ printf "%s\n" "$@" > "$f.tmp" || fatal "failed to write to $f.tmp"
+ mv -v --backup=t "$f.tmp" "$f" || fatal "mv failed"
+ fi
+}
+
function parse_file() {
mapfile -t lines < "$fname"
- local split_ranges=() start_lidx end_lidx insn_fname
+ local group_output=() group_start=0
+ local insn_output=() insn_start=0 insn_fname=""
+ local code_output=() code_start=0 code_fname=""
lidx=-1
next_line
- until hit_eof; do
+ while :; do
+ group_start="$lidx"
skip_comments_and_blanks
if hit_eof; then
break
fi
+ group_output+=("${lines[@]:group_start:lidx-group_start}")
+ group_start="$lidx"
+ insn_output=()
+ code_output=()
+ insn_start="$lidx"
[[ "$line" =~ ^"#" ]] || fatal 'missing `#` header line'
next_line
skip_comments_and_blanks
next_line
skip_comments_and_blanks
insn_fname=""
+ code_fname=""
while :; do
[[ "$line" =~ ^"* "([a-zA-Z0-9.]+)(" "|$) ]] || \
fatal 'missing/invalid instruction syntax line'
if [[ "$insn_fname" == "" ]]; then
insn_fname="${fname%.mdwn}/${BASH_REMATCH[1]}.mdwn"
+ code_fname="${fname%.mdwn}/${BASH_REMATCH[1]}_code.mdwn"
fi
next_line
if [[ "$line" == "" ]]; then
while [[ "$line" =~ ^"<!--" ]]; do
next_line
done
- start_lidx="$lidx"
+ insn_output+=("${lines[@]:insn_start:lidx-insn_start}")
+ insn_output+=(\
+ "[[!inline pagenames=\"${code_fname%.mdwn}\" raw=\"yes\"]]")
+ code_start="$lidx"
while [[ "$line" =~ ^"<!--"|^" " ]]; do
next_line
done
- end_lidx="$lidx"
- if [[ "$line" =~ ^"[[!inline" ]]; then
- ((start_lidx == end_lidx)) || \
- warn "[[!inline]] directive can't be used with other content"
- note "skipping existing [[!inline]] directive"
- else
- [[ "$line" == "" ]] || fatal 'missing blank line after content'
- split_ranges+=("$start_lidx:$end_lidx $insn_fname")
- fi
+ code_output+=("${lines[@]:code_start:lidx-code_start}")
+ insn_start="$lidx"
+ [[ "$line" == "" ]] || fatal 'missing blank line after content'
+ # split_ranges+=("$start_lidx:$end_lidx $insn_fname")
until hit_eof || [[ "$line" =~ ^"#" ]]; do
next_line
done
- done
- if ((${#split_ranges[@]} == 0)); then
- return
- fi
- local split_range output_lines=()
- lidx=-1
- next_line
- for split_range in "${split_ranges[@]}"; do
- [[ "$split_range" =~ ^([0-9]+)':'([0-9]+)' '(.*)$ ]] || \
- fatal "failed to parse split_range=$split_range"
- start_lidx="${BASH_REMATCH[1]}"
- end_lidx="${BASH_REMATCH[2]}"
- insn_fname="${BASH_REMATCH[3]}"
- while ((lidx < start_lidx)); do
- output_lines+=("$line")
- next_line
- done
- mkdir -p "$(dirname "$insn_fname")"
- while ((lidx < end_lidx)); do
- echo "$line"
- next_line
- done > "$insn_fname" || fatal "failed to write to $insn_fname"
- output_lines+=(\
+ hit_eof || prev_line
+ insn_output+=("${lines[@]:insn_start:lidx-insn_start}")
+ write_file "$insn_fname" "${insn_output[@]}"
+ write_file "$code_fname" "${code_output[@]}"
+ group_output+=(\
"[[!inline pagenames=\"${insn_fname%.mdwn}\" raw=\"yes\"]]")
done
- until hit_eof; do
- output_lines+=("$line")
- next_line
- done
- printf "%s\n" "${output_lines[@]}" > "$fname.tmp" || \
- fatal "failed to write to $fname.tmp"
- mv -v --backup=t "$fname.tmp" "$fname" || fatal "mv failed"
+ write_file "$fname" "${group_output[@]}"
}
function main() {