From 3b6c8421d8652990f858fd8e796d5124d7ec2fa7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Mon, 11 Sep 2023 15:42:37 +0200 Subject: [PATCH] remodeling macro engine: do not depend on cgilite/markdown.awk to call macro functions --- macros/toc | 12 +---- parsers/50_markdown.sh | 6 +-- parsers/60_macros.awk | 116 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 15 deletions(-) create mode 100755 parsers/60_macros.awk diff --git a/macros/toc b/macros/toc index 801347a..5f89936 100755 --- a/macros/toc +++ b/macros/toc @@ -16,22 +16,12 @@ . "$_EXEC/cgilite/cgilite.sh" -unset MD_MACROS - -if [ "$(which awk)" ]; then - md() { awk -f "$_EXEC/cgilite/markdown.awk"; } -elif [ "$(which busybox)" ]; then - md() { busybox awk -f "$_EXEC/cgilite/markdown.awk"; } -else - md() { cat; } -fi - min="$1" max="$2" [ "$min" -ge 1 -a "$min" -le 6 ] || min=1 [ "$max" -ge "$min" ] || max="$min" [ "$max" -le 6 ] || max=6 -md |sed -nE ' +sed -nE ' 1i diff --git a/parsers/50_markdown.sh b/parsers/50_markdown.sh index 63d8f0e..8a21616 100755 --- a/parsers/50_markdown.sh +++ b/parsers/50_markdown.sh @@ -15,11 +15,9 @@ # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. if which awk >/dev/null; then - awk -f "$_EXEC/md_macros.awk" -f "$_EXEC/cgilite/markdown.awk" - # | sed -E 's;(<[^>]+ )href="((/[^"/]+|[^"/]+[^:/]|)/([^"/]+/)*)"([^>]*>);\1href="\2:'"${LANGUAGE}"'"\5;g' + awk -f "$_EXEC/cgilite/markdown.awk" elif which busybox >/dev/null; then - busybox awk -f "$_EXEC/md_macros.awk" -f "$_EXEC/cgilite/markdown.awk" - # | sed -E 's;(<[^>]+ )href="((/[^"/]+|[^"/]+[^:/]|)/([^"/]+/)*)"([^>]*>);\1href="\2:'"${LANGUAGE}"'"\5;g' + busybox awk -f "$_EXEC/cgilite/markdown.awk" else cat fi diff --git a/parsers/60_macros.awk b/parsers/60_macros.awk new file mode 100755 index 0000000..b72110b --- /dev/null +++ b/parsers/60_macros.awk @@ -0,0 +1,116 @@ +#!/bin/awk -f +#!/opt/busybox/awk -f + +# Copyright 2022 - 2023 Paul Hänsch +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +function sh_escape(arg){ + return "'" gensub(/'/, "'\"'\"'", "g", arg) "'"; +} + +function argsplit(line, args, LOCAL, c, n, ctx) { + ctx="space"; n=0; + + while ( length(line) > 0 ) { + c = substr(line, 1, 1); + line = substr(line, 2); + if (ctx == "space" ) + if (c ~ /[ \t]/) ctx = "space"; + else if (c ~ /\\/) { n++; ctx = "escbare"; } + else if (c ~ /"/) { n++; ctx = "dquot"; } + else if (c ~ /'/) { n++; ctx = "squot"; } + else { n++; args[n] = c; ctx = "bare"; } + else if (ctx == "bare") + if (c ~ /[ \t]/) ctx = "space"; + else if (c ~ /\\/) ctx = "escbare"; + else if (c ~ /"/) ctx = "dquot"; + else if (c ~ /'/) ctx = "squot"; + else args[n] = args[n] c; + else if (ctx == "dquot") + if (c ~ /"/) ctx = "bare"; + else if (c ~ /\\/) ctx = "escdquot"; + else args[n] = args[n] c; + else if (ctx == "squot") + if (c ~ /'/) ctx = "bare"; + else args[n] = args[n] c; + else if (ctx == "escbare") { + args[n] = args[n] c; + ctx = "bare"; + } + else if (ctx == "escdquot") { + args[n] = args[n] c; + ctx = "dquot"; + } + } +} + +function HTML ( text ) { + gsub( /&/, "\\&", text ); + gsub( //, "\\>", text ); + gsub( /"/, "\\"", text ); + gsub( /'/, "\\'", text ); + gsub( /\\/, "\\\", text ); + return text; +} + +function macro(call, LOCAL, line, args) { + argsplit(call, args); + call=""; + + for (n = 1; n in args; n++) call = call sh_escape(args[n]) " "; + + if (args[1] in MACROS) { + printf "%s", file | sh_escape(ENVIRON["MD_MACROS"]) "/" call; + close(sh_escape(ENVIRON["MD_MACROS"]) "/" call); + } else { + printf "%s", HTML("<<" call ">>"); + } +} + +function unhtml ( text ) { + gsub( /</, "<", text); + gsub( />/, ">", text); + gsub( /"/, "\"", text); + gsub( /'/, "'", text); + gsub( /\/, "\\", text); + gsub( /&/, "\\&", text); + return text; +} + +function findmacro(line, LOCAL, st, len, pre, post) { + if ( match(line, /[^\n]*<\/code>/) ) { + match(line, //); pre = substr( line, 1, RSTART - 1 ); + line = substr( line, RSTART + RLENGTH); + match( line, /<\/code>/); post = substr(line, RSTART + RLENGTH); + line = substr(line, 1, RSTART - 1); + + printf "%s", pre; macro( unhtml(line) ); findmacro( post ); + } else { + printf "%s", line; + } +} + +BEGIN { + if (ENVIRON["MD_MACROS"]) { + AllowMacros = "true"; + "cd " sh_escape(ENVIRON["MD_MACROS"]) "; printf '%s/' *" |getline macro_list; + split(macro_list, MACROS, "/"); + for (n in MACROS) { MACROS[MACROS[n]] = ""; delete MACROS[n]; } + delete MACROS[""]; + + file = ""; while ( getline ) { file = file $0 "\n"; } + findmacro( file ); + } +} -- 2.39.2