From 0275b47937bc6fc88a423440fa9f4da1dd90bc55 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Tue, 7 May 2024 22:30:00 -0500 Subject: Begin an sh impl --- jimmy | 5 ++- jimmy.sh | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100755 jimmy.sh diff --git a/jimmy b/jimmy index 74cef29..aa79183 100755 --- a/jimmy +++ b/jimmy @@ -41,7 +41,10 @@ BEGIN { # configuration linefmt["header", 3] = "

%s

\n" isblock["link"] = 0 linefmt["link"] = "%s\n" - # escapes + # escapes -- TODO: rethink these. + ## I think the best solution is to have a pair of arrays -- + ## esc_orig and esc_repl. These will have keys in the + ## [n, block] format to keep them straight. esc["verbatim", 0, "&"] = "\\&" esc["verbatim", 8, "<"] = "\\<" esc["verbatim", 9, ">"] = "\\>" diff --git a/jimmy.sh b/jimmy.sh new file mode 100755 index 0000000..f039f4f --- /dev/null +++ b/jimmy.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +BLOCK= +BUFFER= + +process() { + while read -r LINE + do + if test "$BLOCK" = verbatim + then + printf '%s\n' "$LINE" + continue + fi + + set -- $LINE + + case "$LINE" in + ('```') + if test "$BLOCK" = verbatim + then BLOCK= + else BLOCK=verbatim + fi + ;; + ('') + if test "$BLOCK" = verbatim + then bufpush $'\n' + else bufclose + fi + ;; + ('=>'*) link "$@" ;; + ('#'*) header "$@" ;; + ('*'*) shift; blknew list "$*" ;; + ('>'*) shift; blknew quote "$*" ;; + (*) shift; blknew paragraph "$*" ;; + esac + done + bufclose +} + +blknew() { + test "$BLOCK" = "$1" || bufclose + bufpush "$(printf "$(eval echo "\$format_$BLOCK")" "$@")" + BLOCK="$1" +} + +bufclose() { + if test -z "$BLOCK" + then "$COLLAPSE_BLANKS" && return + else newline; return + fi + + # blockp "$BLOCK" || return + # fillp $BLOCK && buffill "$(fillp $BLOCK)" + + # TODO: escape shit + + printf '%s%s%s\n' \ + "$(echo eval "\$opener_$BLOCK")" \ + "$BUFFER" \ + "$(echo eval "\$closer_$BLOCK")" + + BLOCK= +} + +buffill() { # buffill WIDTH + if test $1 -lt 0 + then BUFFER="$(printf '%s\n' "$BUFFER" | tr '\n' ' ')" + else + out= + nline=0 + printf '%s\n' "$BUFFER" | sed 's/[ \t]\+/\n/g' | + while read -r word + do + if test $((nline + ${#word})) -ge "$1" + then + out="${out}"${out:+$'\n'}"${word}" + nline=${#word} + else + out="${out}${out:+ }${word}" + nline=$((nline + ${#word} + 1)) + fi + done + BUFFER="$out" + fi +} + +bufpush() { BUFFER="${BUFFER}$@"; } + +fillp() { + : +} + +header() { + bufclose + lvl=${#1}; shift + bufpush "$(printf "$(eval echo "\$format_h$lvl")" "$*")" + BLOCK=header +} + +link() { + url="$2"; shift 2 + if test "$BLOCK" = paragraph #&& ! blockp link + then bufpush "$(printf "$format_link" "$url" "$*")" + else blknew linklist "$url" "$*" + fi +} + +newline() { printf '\n'; } + +html() { + format_link='%s\n' + format_h1='

%s

\n' + format_h2='

%s

\n' + format_h3='

%s

\n' + opener_verbatim='
'
+	closer_verbatim='
\n' + format_verbatim='%s\n' + opener_paragraph='

' + closer_paragraph='

\n' + format_paragraph='%s\n' + opener_quote='
' + closer_quote='
\n' + format_quote='%s\n' + opener_list='\n' + format_list='
  • %s
  • ' + opener_linklist='' + format_linklist="$(printf "$format_list" "$format_link")" +} + +main() { + html + process "$@" +} + +main "$@" -- cgit 1.4.1-21-gabe81