summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2023-04-09 13:21:29 +0300
committerPaul Buetow <paul@buetow.org>2023-04-09 13:21:29 +0300
commitb253915c629c6d38641a81c7f1bb47d662c48a03 (patch)
treebdd494eff528c68cf26ce2bd18bf87c6c2a66d41 /lib
parentfed1dbf0d164a18b01843323b676d1bff3f628da (diff)
add support for GNU Source Highlight - for Source code highlighting in bare blocks
Diffstat (limited to 'lib')
-rw-r--r--lib/assert.source.sh14
-rw-r--r--lib/html.source.sh69
2 files changed, 69 insertions, 14 deletions
diff --git a/lib/assert.source.sh b/lib/assert.source.sh
index a1713c3..990194c 100644
--- a/lib/assert.source.sh
+++ b/lib/assert.source.sh
@@ -31,6 +31,20 @@ assert::not_empty () {
log VERBOSE "Result in $callee as expected not empty"
}
+# Unit test for whether a given string contains a substring
+assert::contains () {
+ local -r content="$1"; shift
+ local -r substring="$1"; shift
+ local -r callee=${FUNCNAME[1]}
+
+ if ! $GREP -q -F "$substring" <<< "$content"; then
+ log ERROR "In $callee expected '$content' to contain substring '$substring'"
+ exit 2
+ fi
+
+ log VERBOSE "Substring check in $callee as expected, contains '$substring'"
+}
+
# Unit test for whether a given string matches a regex.
assert::matches () {
local -r name="$1"; shift
diff --git a/lib/html.source.sh b/lib/html.source.sh
index e148ef1..7056f24 100644
--- a/lib/html.source.sh
+++ b/lib/html.source.sh
@@ -1,4 +1,4 @@
-# Convert special characters to their HTML codes
+# Convert specia characters to their HTML codes
html::encode () {
$SED '
s|\&|\&amp;|g;
@@ -105,10 +105,26 @@ html::add_extras () {
fi
}
+html::source_highlight () {
+ local -r bare_text="$1"; shift
+ local -r language="$1"; shift
+
+ if [[ -z "$language" || -z "$SOURCE_HIGHLIGHT" ]]; then
+ echo '<pre>'
+ html::encode "$bare_text"
+ echo '</pre>'
+ else
+ $SOURCE_HIGHLIGHT --src-lang="$language" <<< "$bare_text" |
+ $SED 's|<tt>||; s|</tt>||;'
+ fi
+}
+
# Convert Gemtext to HTML
html::fromgmi () {
local is_list=no
- local is_plain=no
+ local is_bare=no
+ local bare_text=''
+ local language=''
while IFS='' read -r line; do
if [[ "$is_list" == yes ]]; then
@@ -125,12 +141,17 @@ html::fromgmi () {
fi
continue
- elif [[ "$is_plain" == yes ]]; then
+ elif [[ "$is_bare" == yes ]]; then
if [[ "$line" == '```'* ]]; then
- echo "</pre>"
- is_plain=no
+ html::source_highlight "$bare_text" "$language"
+ is_bare=no
+ bare_text=''
+ language=''
+ elif [ -z "$bare_text" ]; then
+ bare_text="$line"
else
- html::encode "$line"
+ bare_text="$bare_text
+$line"
fi
continue
fi
@@ -143,8 +164,8 @@ html::fromgmi () {
html::process_inline
;;
'```'*)
- is_plain=yes
- echo '<pre>'
+ language=$(cut -d'`' -f4 <<< "$line")
+ is_bare=yes
;;
'# '*)
html::make_heading "$line" 1 | html::process_inline
@@ -162,11 +183,7 @@ html::fromgmi () {
generate::make_link html "$line" | html::process_inline
;;
*)
- if [[ "$is_plain" == no ]]; then
- html::make_paragraph "$line" | html::process_inline
- else
- html::make_paragraph "$line"
- fi
+ html::make_paragraph "$line" | html::process_inline
;;
esac
done
@@ -212,6 +229,31 @@ html::test::default () {
line='=> http://example.org/image.png Image description'
assert::equals "$(generate::make_link html "$line")" \
"<a href='http://example.org/image.png'><img alt='Image description' title='Image description' src='http://example.org/image.png' /></a><br />"
+
+ local input_block='```
+this
+ is
+ a
+ bare block
+```'
+
+ local output_block='<pre>
+this
+ is
+ a
+ bare block
+</pre>'
+
+ assert::equals "$(html::fromgmi <<< "$input_block")" "$output_block"
+
+ if [ -n "$SOURCE_HIGHLIGHT" ]; then
+ input_block='```bash
+if [ -z $foo ]; then
+ echo $foo
+fi
+```'
+ assert::contains "$(html::fromgmi <<< "$input_block")" 'GNU source-highlight'
+ fi
}
# Test exact HTML variant.
@@ -237,7 +279,6 @@ html::test::exact () {
line='### Header 3'
assert::equals "$(html::make_heading "$line" 3)" "<h3 style='display: inline'>Header 3</h3><br />"
-
line='> This is a quote'
assert::equals "$(html::make_quote "$line")" "<span class='quote'>This is a quote</span><br />"
}