summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md15
-rwxr-xr-xgemtexter11
-rw-r--r--gemtexter-paul.cyou.conf1
-rw-r--r--gemtexter.conf4
-rw-r--r--lib/assert.source.sh14
-rw-r--r--lib/html.source.sh69
6 files changed, 96 insertions, 18 deletions
diff --git a/README.md b/README.md
index b4eb9de..582cffd 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ These are the requirements for running the `gemtexter` static site generator scr
* GNU Sed
* GNU Date
* GNU Grep
+* GNU Source Highlight (optional for source code highlighting in bare text blocks)
* Git (optional for version control)
* ShellCheck installed (optional for testing)
* XMLLint (optional for validating the atom feed syntax)
@@ -104,6 +105,20 @@ Once your capsule reaches a certain size it can become annoying to re-generate e
This will help you to quickly review the results once in a while. Once you are happy you should always re-generate the whole capsule before publishing it! Note, that there will be no Atom feed generation in filter mode so before publishing it you should always run a full `--generate`.
+### Source code highlighting
+
+The HTML output supports source code highlighting. The requirement is to have the `source-highlight` command, which is GNU Source Highlight, to be installed. Once done, you can annotate a bare block with the language to be highlighted. E.g.:
+
+```
+ ```bash
+ if [ -n "$foo" ]; then
+ echo "$foo"
+ fi
+ ```
+```
+
+Please run `source-highlight --lang-list` for a list of all supported languages.
+
### Templating
Since version `2.0.0`, Gemtexter supports templating. A template file name must have the suffix `gmi.tpl`. A template must be put into the same directory as the Gemtext `.gmi` file to be generated. Gemtexter will generate a Gemtext file `index.gmi` from a given template `index.gmi.tpl`. All lines starting with `<< ` will be evaluated as a single line of Bash code and the output will be written into the resulting Gemtext file. A `<<<` and `>>>` encloses a multiline template.
diff --git a/gemtexter b/gemtexter
index 8a4d43f..e266544 100755
--- a/gemtexter
+++ b/gemtexter
@@ -5,13 +5,14 @@
declare -r ARG="$1"; shift
declare CONTENT_FILTER="$1"; shift
-declare -r VERSION=2.0.1
-declare -r VERSION_DESCR=bugfix
+declare -r VERSION=2.1.0
+declare -r VERSION_DESCR=develop
declare -r DATE_FORMAT='--iso-8601=seconds'
declare DATE=date
declare SED=sed
declare GREP=grep
declare XMLLINT=''
+declare SOURCE_HIGHLIGHT=''
which gdate &>/dev/null && DATE=gdate
which gsed &>/dev/null && SED=gsed
which ggrep &>/dev/null && GREP=ggrep
@@ -94,6 +95,12 @@ check_dependencies () {
else
export XMLLINT=xmllint
fi
+
+ if ! source-highlight --version &>/dev/null; then
+ log WARN "WARN, GNU \"source-highlight\" command is not installed, but it's recommended!"
+ else
+ export SOURCE_HIGHLIGHT=source-highlight
+ fi
}
setup () {
diff --git a/gemtexter-paul.cyou.conf b/gemtexter-paul.cyou.conf
index c7f1fca..741bf53 100644
--- a/gemtexter-paul.cyou.conf
+++ b/gemtexter-paul.cyou.conf
@@ -9,6 +9,7 @@ declare -xr CONTENT_BASE_DIR=../paul.cyou-content
declare -xr HTML_HEADER=./extras/html/header.html.part
declare -xr HTML_FOOTER=./extras/html/footer.html.part
declare -xr HTML_CSS_STYLE=./extras/html/style.css
+declare -xr HTML_VARIANT=exact
declare -xr HTML_WEBFONT_TEXT=./extras/html/roboto-slab/RobotoSlab-Regular.ttf
declare -xr HTML_WEBFONT_CODE=./extras/html/hack/Hack-Regular.ttf
declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/khand/khand.ttf
diff --git a/gemtexter.conf b/gemtexter.conf
index b5f03be..94c1f89 100644
--- a/gemtexter.conf
+++ b/gemtexter.conf
@@ -9,9 +9,9 @@ declare -xr PRE_GENERATE_HOOK=./pre_generate_hook.sh
declare -xr POST_PUBLISH_HOOK=./post_publish_hook.sh
declare -xr HTML_HEADER=./extras/html/header.html.part
declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=./extras/html/style.css
+declare -xr HTML_VARIANT=exact
declare -xr HTML_WEBFONT_TEXT=./extras/html/hack/Hack-Regular.ttf
declare -xr HTML_WEBFONT_CODE=./extras/html/hack/Hack-Regular.ttf
declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/khand/khand.ttf
declare -xr HTML_WEBFONT_TYPEWRITER=./extras/html/zai-aeg-mignon-typewriter-1924/zai_AEGMignonTypewriter1924.ttf
-declare -xr HTML_VARIANT=exact
-declare -xr HTML_CSS_STYLE=./extras/html/style.css
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 />"
}