@@ -96,24 +96,21 @@ parse_markdown() {
9696 close_list()
9797 }
9898
99- # Handle nesting or same-level list items
99+ # Handle nesting, de-denting, or same-level list items.
100+ # This rewritten function is simpler and more robust.
100101 function handle_list(type, indent) {
101- if (list_depth > 0) {
102- if (indent > list_indent[list_depth]) {
103- open_list(type, indent)
104- } else {
105- while (list_depth > 0 &&
106- (list_indent[list_depth] > indent ||
107- (list_indent[list_depth] == indent &&
108- list_type[list_depth] != type))) {
109- close_list()
110- }
111- if (list_depth == 0 ||
112- list_indent[list_depth] < indent) {
113- open_list(type, indent)
114- }
115- }
116- } else {
102+ # First, close any lists that are more deeply indented than the
103+ # current item, or lists of a different type at the same level.
104+ while (list_depth > 0 &&
105+ (list_indent[list_depth] > indent ||
106+ (list_indent[list_depth] == indent &&
107+ list_type[list_depth] != type))) {
108+ close_list()
109+ }
110+
111+ # Now, open a new list if we are not in one, or if the current
112+ # item is more indented than the current list level.
113+ if (list_depth == 0 || list_indent[list_depth] < indent) {
117114 open_list(type, indent)
118115 }
119116 }
@@ -257,17 +254,31 @@ parse_markdown() {
257254
258255 # Template passthrough
259256 /^\{\{[[:space:]]*include-block:/ {
260- close_para(); in_template = 1; print; next
257+ close_para()
258+ in_template = 1
259+ print
260+ next
261261 }
262- /^\{\{[[:space:]]*endinclude[[:space:]]*\}\}$/ {
263- close_para(); print; in_template = 0; next
262+ # If we are in a template and see the end tag, print the line,
263+ # turn off template mode, and move to the next line.
264+ # This MUST come before the general "in_template" rule.
265+ in_template && /\{\{[[:space:]]*endinclude[[:space:]]*\}\}/ {
266+ print
267+ in_template = 0
268+ next
269+ }
270+ # For any other line while in a template, just print it.
271+ in_template {
272+ print
273+ next
264274 }
265- in_template { print; next }
266275
267- # Raw HTML
268- /^[[:space:]]*<[^>]+>.*<\/[^>]+>[[:space:]]*$/ {
269- close_para(); close_blocks(); close_lists_to(0)
270- print; next
276+ # Raw HTML passthrough.
277+ /^[[:space:]]*<\/?([a-zA-Z])/ {
278+ close_para()
279+ close_list()
280+ print
281+ next
271282 }
272283
273284 # Blank lines do NOT close lists under CommonMark
@@ -752,7 +763,7 @@ render_posts() {
752763 printf ' <li class="%s">\n' " $lcls "
753764 if [ " $show " = " true" ] && [ -n " $img " ]; then
754765 case " $img " in http://* |https://* |//* ) src=" $img " ;;
755- * ) src=" /${img#*/ } " ;;
766+ * ) src=" /static/ ${img#*/ } " ;;
756767 esac
757768 printf ' <img class="%s" src="%s" alt="%s">\n' " $icls " " $src " " $title "
758769 fi
@@ -835,8 +846,10 @@ process_post_directives() {
835846
836847# Full pipeline for each source file
837848process_file () {
838- file=" $1 " ; ext=" ${file##* .} "
839- rel=" ${file# src/ } " ; out=" dist/${rel% .* } .html"
849+ file=" $1 "
850+ ext=" ${file##* .} "
851+ rel=" ${file# src/ } "
852+ out=" dist/${rel% .* } .html"
840853 mkdir -p " $( dirname " $out " ) "
841854 log_verbose " Processing $file -> $out "
842855
@@ -866,53 +879,85 @@ process_file() {
866879 log_info " Created $out "
867880}
868881
869- copy_static_assets () {
870- mkdir -p dist/static
871- if [ -d " src/static" ]; then
872- log_info " Copying src/static → dist/static/"
873- # Use cp -a if available for better attribute preservation, fall back to -r
874- if cp -a src/static/. dist/static/ 2> /dev/null; then
875- :
876- else
877- cp -r src/static/. dist/static/
878- fi
879- fi
880- }
881882
882883# Orchestrate full build and asset copy
883884build_site () {
884- log_info " Starting build..."
885- rm -rf dist; mkdir -p dist
886- jobs=0
887- find src \( -path src/includes -o -name template.html -o -path src/static \) -prune -o \
888- -type f \( -name ' *.md' -o -name ' *.html' \) -print |
889- while IFS= read -r f; do
890- process_file " $f " & jobs=$(( jobs+ 1 ))
891- [ " $jobs " -ge " $MAX_JOBS " ] && wait && jobs=0
885+ log_verbose " Starting build..."
886+
887+ # Clean output and copy static assets
888+ rm -rf dist
889+ mkdir -p dist/static
890+ if [ -d src/static ]; then
891+ log_info " Copying src/static -> dist/static/"
892+ # Try POSIX-cp -R, fallback to -r
893+ if cp -R src/static/. dist/static/ > /dev/null 2>&1 ; then
894+ :
895+ else
896+ cp -r src/static/. dist/static/
897+ fi
898+ fi
899+
900+ # Gather the list of files (split on newline only)
901+ OLD_IFS=$IFS
902+ IFS='
903+ '
904+ files=$( find src \
905+ \( -path src/includes -o -name template.html -o -path src/static \) -prune \
906+ -o -type f \( -name ' *.md' -o -name ' *.html' \) -print)
907+ IFS=$OLD_IFS
908+
909+ pids=" "
910+ count=0
911+
912+ for f in $files ; do
913+ process_file " $f " &
914+ pid=$!
915+ # accumulate PIDs in a space-separated string
916+ if [ -z " $pids " ]; then
917+ pids=" $pid "
918+ else
919+ pids=" $pids $pid "
920+ fi
921+ count=$(( count + 1 ))
922+
923+ # throttle if we've launched $MAX_JOBS
924+ if [ " $count " -ge " $MAX_JOBS " ]; then
925+ for wp in $pids ; do
926+ wait " $wp "
927+ done
928+ pids=" "
929+ count=0
930+ fi
892931 done
893- wait
894932
895- copy_static_assets
933+ # wait for any remaining workers
934+ if [ -n " $pids " ]; then
935+ for wp in $pids ; do
936+ wait " $wp "
937+ done
938+ fi
896939
897940 log_info " ${GREEN} Build complete!${NC} "
898941}
899942
900943# Choose the correct Mongoose binary for the current OS and launch it,
901944# serving the dist/ directory at http://localhost:8000.
902945start_server () {
903- case " $( uname -s) " in
904- CYGWIN* |MINGW* |MSYS* ) MONGOOSE_BIN=" ./mongoose/mongoose_windows.exe" ;;
905- Linux* ) MONGOOSE_BIN=" ./mongoose/mongoose_linux" ;;
906- Darwin* ) MONGOOSE_BIN=" ./mongoose/mongoose_mac" ;;
907- * ) MONGOOSE_BIN=" ./mongoose/mongoose_linux" ;;
908- esac
909- if [ ! -x " $MONGOOSE_BIN " ]; then
910- log_error " Mongoose binary not found or not executable."
911- exit 1
912- fi
913- log_info " Starting server at http://localhost:8000"
914- " $MONGOOSE_BIN " -d dist/ -v 0 &
915- SERVER_PID=$!
946+ case " $( uname -s) " in
947+ CYGWIN* |MINGW* |MSYS* ) MONGOOSE_BIN=" ./mongoose/mongoose_windows.exe" ;;
948+ Linux* ) MONGOOSE_BIN=" ./mongoose/mongoose_linux" ;;
949+ Darwin* ) MONGOOSE_BIN=" ./mongoose/mongoose_mac" ;;
950+ * ) MONGOOSE_BIN=" ./mongoose/mongoose_linux" ;;
951+ esac
952+
953+ if [ ! -x " $MONGOOSE_BIN " ]; then
954+ log_error " Mongoose binary not found or not executable."
955+ exit 1
956+ fi
957+
958+ " $MONGOOSE_BIN " -d dist/ -v 0 &
959+ SERVER_PID=$!
960+ log_info " Server started at http://localhost:8000 (press Ctrl+C to stop)"
916961}
917962
918963# Open the default web browser to http://localhost:8000, depending on OS.
@@ -1047,29 +1092,37 @@ fi
10471092# Ensure the Mongoose server (if started) is killed when the script exits.
10481093trap ' if [ -n "$SERVER_PID" ]; then kill "$SERVER_PID"; fi' EXIT
10491094
1095+ get_src_hash () {
1096+ find src -type f -exec md5sum {} + 2> /dev/null | md5sum | awk ' {print $1}'
1097+ }
1098+
10501099if [ " $WATCH " -eq 1 ]; then
10511100 build_site
1101+ last_hash=$( get_src_hash)
1102+
10521103 if [ " $SERVE " -eq 1 ]; then
10531104 start_server
1054- [ " $OPEN_BROWSER " -eq 1 ] && open_browser
1105+ if [ " $OPEN_BROWSER " -eq 1 ]; then
1106+ open_browser
1107+ fi
10551108 fi
10561109
1057- last_hash= $( find src -type f -exec cksum {} + | cksum )
1110+ log_verbose " Watching for file changes in src/... "
10581111 while true ; do
1059- sleep 1
1060- current_hash=$( find src -type f -exec cksum {} + | cksum )
1112+ sleep 0.2
1113+ current_hash=$( get_src_hash )
10611114 if [ " $current_hash " != " $last_hash " ]; then
1062- log_info " Change detected, rebuilding..."
1115+ log_verbose " Change detected, rebuilding..."
10631116 build_site
1064- last_hash=" $current_hash "
1117+ last_hash=$( get_src_hash)
1118+ log_verbose " Watching for file changes in src/..."
10651119 fi
10661120 done
10671121else
10681122 build_site
10691123 if [ " $SERVE " -eq 1 ]; then
10701124 start_server
10711125 [ " $OPEN_BROWSER " -eq 1 ] && open_browser
1072- log_info " Server is running at http://localhost:8000 (Press Ctrl+C to stop)"
10731126 wait " $SERVER_PID "
10741127 fi
10751128fi
0 commit comments