Internally, LibreOffice Writer has been used for technical documentation for many years:
- Writer is very strong in combination with style sheets and
- SVG format is perfectly supported. Vector-based images can therefore be inserted very well.
When you work with large documents, there is an annoying peculiarity you should be aware of: It is not possible to link templates to documents from the user interface. This sounds a bit crazy and yes, it may be considered to be a bug, a reason not to use LibreOffice.
An extension “Template Changer” was available for linking template files. However, it does not work with new versions. That is why we created a BASH script as a tool to solve this. It has been tested on Linux but should also work with Cygwin on Windows. OS-X should work with minor changes, like the date function in Unix does not require an @ sign.

The underlying idea is that you have documentation projects where both the documents and the templates are in the same directory. If that is the case with you, then this script can help you.
You can paste the following to a text file called “cht.sh”, give it executable rights, put it in your documentation directory, and start attaching templates to your documents.
Hope you like it!
Update 2018-11-19: Now both ODT and ODM files are supported.
Update 2023: Repaginating bug is solved and information is removed from this page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | #!/bin/bash # Template CHanger alternative # This script uses xmlstarlet, zip and unzip. echo echo ./cht.sh, CHange Template... echo This script inserts or replaces, a template XML node in a echo LibreOffice Writer file, by modifying meta.xml and adding an echo absolute url for template location. It accepts both echo document and master document files and template files. echo xmlstarlet is expected to be installed. echo This is for documentation projects where Writer files and Templates echo reside in the same directory! echo USE AT YOUR OWN RISK, HAVE A BACK-UP READY, wiebe-nedcad-nl echo Run script always in directory with documents, cd your_project echo "Usage: cht <OTT-file> <ODT-or-ODM-file>" echo Example: ./cht.sh template.ott writer.odt echo ## Variables I, more below Checks # General TEMPL=$1 DOC=$2 WORKDIR="temp_extracted" ## Checks # Do files exist with right extension? if [ -f $TEMPL ] && [ "${TEMPL: -4}" == ".ott" ]; then echo "File $TEMPL found." else echo "ERROR: Writer template $TEMPL does not exist or is not valid. Aborting." exit 1 fi if [ -f $DOC ] && ([ "${DOC: -4}" == ".odt" ] || [ "${DOC: -4}" == ".odm" ]); then echo "File $DOC found." else echo "ERROR: Writer document $DOC does not exist or is not valid. Aborting." exit 1 fi # Do we have xmlstarlet? hash xmlstarlet 2>/dev/null || { echo >&2 "ERROR: xmlstarlet is required. Please install this first. Aborting."; exit 1; } ## Variables II # XML node "meta:template" values echo Node meta:template will contain the following bare attributes: # xlink:type xlink:actuate xlink:title xlink:href meta:date # Static N_XLINK_TYPE="xlink:type" && V_XLINK_TYPE="simple" echo $N_XLINK_TYPE -- $V_XLINK_TYPE # Static N_XLINK_ACTUATE="xlink:actuate" && V_XLINK_ACTUATE="onRequest" echo $N_XLINK_ACTUATE -- $V_XLINK_ACTUATE # Template name N_XLINK_TITLE="xlink:title" NO_EXT="${TEMPL%.*}" V_XLINK_TITLE=${NO_EXT##*/} echo $N_XLINK_TITLE -- $V_XLINK_TITLE # Absolute template location N_XLINK_HREF="xlink:href" V_XLINK_HREF="$PWD/$TEMPL" echo $N_XLINK_HREF -- $V_XLINK_HREF # Template time N_META_DATE="meta:date" # Lower epoch time sec to force updating document styles BELLE_EPOCH_COR=-1 BELLE_EPOCH_X=$(stat -c %Y $TEMPL) BELLE_EPOCH=$((BELLE_EPOCH_X+BELLE_EPOCH_COR)) V_META_DATE=$(date -d @$BELLE_EPOCH +%Y-%m-%dT%T.%9N) echo $N_META_DATE -- $V_META_DATE echo ## The proces # Unzip the document file mkdir -p $WORKDIR if [ -z "$(ls -A ./$WORKDIR)" ]; then echo "Ready for processing meta.xml" else echo "ERROR: ./$WORKDIR is not empty and may contain an unzipped document file. Aborting." exit 1 fi unzip -q $DOC -d $WORKDIR cd $WORKDIR # If exists, delete node meta:template, add node and subnodes via pipes xmlstarlet ed -d "/office:document-meta/office:meta/meta:template" meta.xml | \ xmlstarlet ed -s "/office:document-meta/office:meta" -t elem -n meta:template | \ xmlstarlet ed -i "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_TYPE -v $V_XLINK_TYPE | \ xmlstarlet ed -i "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_ACTUATE -v $V_XLINK_ACTUATE | \ xmlstarlet ed -i "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_TITLE -v $V_XLINK_TITLE | \ xmlstarlet ed -i "/office:document-meta/office:meta/meta:template" -t attr -n $N_XLINK_HREF -v $V_XLINK_HREF | \ xmlstarlet ed -i "/office:document-meta/office:meta/meta:template" -t attr -n $N_META_DATE -v $V_META_DATE \ > temp.xml && mv temp.xml meta.xml # What is the result? echo meta.xml is now: && echo cat meta.xml && echo # Back-up original file mv ../$DOC "../${DOC%.*}.bak" echo A .bak file is created && echo # Create modified Writer file, mimetype first zip -rq ../$DOC mimetype . # Cleaning up cd .. rm -rf $WORKDIR echo Finished && echo |