diff options
| -rw-r--r-- | README.md | 15 | ||||
| -rwxr-xr-x | gemtexter | 11 | ||||
| -rw-r--r-- | gemtexter-paul.cyou.conf | 1 | ||||
| -rw-r--r-- | gemtexter.conf | 4 | ||||
| -rw-r--r-- | lib/assert.source.sh | 14 | ||||
| -rw-r--r-- | lib/html.source.sh | 69 |
6 files changed, 96 insertions, 18 deletions
@@ -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. @@ -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|\&|\&|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 />" } |
