pyratelog

personal blog
git clone git://git.pyratebeard.net/pyratelog.git
Log | Files | Refs | README

20221117-as_a_matter_of_course.md (9030B)


      1 This web log as been through a few iterations.  First I used [Jekyll](https://jekyllrb.com/){target="_blank" rel="noreferrer"} on [Github Pages](https://pages.github.com/){target="_blank" rel="noreferrer"}, then I switched to [Hugo](https://gohugo.io/){target="_blank" rel="noreferrer"} using a docker container and [Gitlab's CI/CD](https://docs.gitlab.com/ee/ci/){target="_blank" rel="noreferrer"} pipeline, then finally the current setup.
      2 
      3 I moved away from the docker container as the build started failing then I was hitting too many issues trying to get it working.  In an effort to simplify everything I thought, why couldn't I write my entries in markdown then use [pandoc](https://pandoc.org/){target="_blank" rel="noreferrer"} to convert them to HTML?
      4 ```
      5 pandoc -f markdown -t html -o new_entry.html new_entry.md
      6 ```
      7 
      8 Sounds so easy.
      9 
     10 The main script, [pyratelog.sh](https://git.pyratebeard.net/pyratelog/file/pyratelog.sh.html){target="_blank" rel="noreferrer"} does all the heavy lifting.  When a new entry is published the script does some prep then runs `pandoc` to convert the markdown file to html.  I use a template file so my markdown only has to be the main body of content.  This is how the command looks in my script
     11 
     12 ```
     13 pandoc -s \
     14 	--template=./entry_template.html \
     15 	--metadata title="${input_title}" \
     16 	-f markdown \
     17 	-t html \
     18 	-o entry/${input}.html \
     19 	entry/${input}.md
     20 ```
     21 
     22 The `pyratelog.sh` script also sets the link on the main page as well as adding the entry to my _rss.xml_ file.
     23 
     24 In order for the script to know when a new entry has been published I use `inotifywait` to watch for files in the _entry/_ directory
     25 ```
     26 inotifywait -m -e create -e moved_to /var/www/html/entry/ | xargs -L 1 /var/www/html/pyratelog.sh
     27 ```
     28 
     29 Over time I have included three more scripts to improve my writing workflow, [draft](https://git.pyratebeard.net/pyratelog/file/scripts/draft.html){target="_blank" rel="noreferrer"}, [preview](https://git.pyratebeard.net/pyratelog/file/scripts/preview.html){target="_blank" rel="noreferrer"}, and [publish](https://git.pyratebeard.net/pyratelog/file/scripts/publish.html).
     30 
     31 ### clapperboard
     32 The `draft` script will checkout a new or existing branch based on the name I pass it, the name will be the title of the entry.
     33 ```
     34 # use arg as title and set entry file path
     35 TITLE=$1
     36 ENTRY="entry/${TITLE}.md"
     37 
     38 # checkout the correct branch
     39 git branch | grep ${TITLE} && \
     40 	git checkout -q ${TITLE} || \
     41 	$(git checkout -q main && git checkout -q -b ${TITLE})
     42 ```
     43 
     44 It will then open up a new or the existing file with that same name in `vim`. 
     45 ```
     46 # if entry file does not exist yet touch it
     47 [ -f "${ENTRY}" ] || touch "${ENTRY}"
     48 
     49 # open entry file in favourite editor
     50 vim "${ENTRY}"
     51 ```
     52 
     53 Now I let my creative juices flow to produce more enjoyable content for you.
     54 
     55 Once I have finished and close `vim`, the `draft` script continues by adding then committing the changes to `git`
     56 ```
     57 # when vim closes add and commit the changes
     58 # if there are any
     59 git status | grep "${ENTRY}" || exit 0
     60 git add "${ENTRY}"
     61 git commit -S -m "${TITLE}"
     62 ```
     63 
     64 ### advanced screening
     65 The `preview` script was written as sometimes I like to see what the entry looks like in the browser, especially when I put pictures in.  It is useful to read through in the browser as well, I have caught a number of spelling mistakes along with poorly worded sentences that way.
     66 
     67 To do this the script creates a temporary directory, copies the entry in question, the template file for `pandoc`, and my custom CSS
     68 ```
     69 # use arg as title and set entry file path
     70 TITLE=$1
     71 ENTRY="entry/${TITLE}.md"
     72 
     73 # create a tmp dir
     74 mkdir demo
     75 
     76 # copy entry file, entry_template and css
     77 # to temp dir
     78 cp ${ENTRY} demo/index.md
     79 cp entry_template.html style.css demo/
     80 
     81 # small change to entry_template for stylesheet
     82 sed -i 's%\.\./%%' demo/entry_template.html
     83 ```
     84 
     85 The same `pandoc` command is used to generate the HTML
     86 ```
     87 # generate html file
     88 pandoc -s \
     89 	--template=demo/entry_template.html \
     90 	--metadata title="demolog" \
     91 	-f markdown \
     92 	-t html \
     93 	-o demo/index.html \
     94 	demo/index.md
     95 ```
     96 
     97 Using `busybox` the script starts a simple web server then waits for me to finish reviewing before killing the process and tidying up the temporary directory
     98 ```
     99 # start web server and capture pid for later
    100 busybox httpd -f -h ./demo -p 8080 &
    101 busypid=$!
    102 
    103 # open demo ENTRY file in browser
    104 xdg-open http://localhost:8080
    105 
    106 # wait until ready to stop web server
    107 echo press any key to cancel
    108 read -n 1
    109 
    110 # kill the web server and remove temp dir
    111 kill ${busypid}
    112 rm -rf demo/
    113 ```
    114 
    115 Unfortunately this script didn't work on my phone while using [Termux](https://f-droid.org/en/packages/com.termux/){target="_blank" rel="noreferrer"} because `pandoc` is not available to install.  As a workaround I started using [AnLinux](https://github.com/EXALAB/AnLinux-App){target="_blank" rel="noreferrer"} to give me a full Linux distro to work in.
    116 
    117 ### it's a wrap
    118 Finally I can run the `publish` script to send my entry out into the world.  This is the simplest of the three scripts.  It will rename the entry to prefix the date then merge the branch into the main branch before pushing to my git server
    119 ```
    120 # use arg as title and set entry file path
    121 # set published file path with date
    122 TITLE=$1
    123 ENTRY="entry/${TITLE}.md"
    124 PUBLISH="entry/$(date +%Y%m%d)-${TITLE}.md"
    125 
    126 # checkout the correct branch
    127 git branch | grep ${TITLE} && \
    128 	git checkout ${TITLE} || \
    129 	git checkout -b ${TITLE}
    130 
    131 # rename entry to set date
    132 git mv "${ENTRY}" "${PUBLISH}"
    133 
    134 # commit the rename as published
    135 git commit -S -m "publish ${TITLE}"
    136 
    137 # checkout main branch and merge published entry
    138 git checkout main
    139 git merge "${TITLE}"
    140 
    141 # push new entry
    142 git push
    143 ```
    144 
    145 In my [last entry](20221111-what_the_hook.html){target="_blank" rel="noreferrer"} I spoke about using [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks){target="_blank" rel="noreferrer"} on my git server to keep my wiki up to date.  I use the same `post-receive` hook for my web log.
    146 ```
    147 #!/bin/sh
    148 ssh logserver "cd /var/www/html ; git pull"
    149 ```
    150 
    151 The only thing I have to do after hitting publish is [toot about it](https://harbour.cafe/@pyratebeard){target="_blank" rel="noreferrer"}.  I will be adding in an auto toot in the `publish` script soon, similar to my [weeklymusictoot](20221005-weeklymusictoot.html){target="_blank" rel="noreferrer"}, to save me having to even do that little job.
    152 
    153 ### behind the scenes
    154 Now because I [seem to like](20220124-make_believe.html){target="_blank" rel="noreferrer"} using Makefiles for running things I had a go at one for the `draft`, `preview`, and `publish` scripts.
    155 
    156 It got a bit complicated with the arguments, but I was able to make it work, even setting it so that if I am already on the correct branch I don't have to pass any arguments
    157 ```
    158 #TITLE := $(shell git branch --show-current)
    159 RND := ""
    160 # https://stackoverflow.com/a/14061796
    161 # If the first argument is "draft"
    162 ifeq (draft,$(firstword $(MAKECMDGOALS)))
    163   # use the rest as arguments for "draft"
    164   ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
    165   # ...and turn them into do-nothing targets
    166   $(eval $(ARGS):;@:)
    167 else
    168 ifeq (preview,$(firstword $(MAKECMDGOALS)))
    169   ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
    170   $(eval $(ARGS):;@:)
    171 else
    172 ifeq (publish,$(firstword $(MAKECMDGOALS)))
    173   ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
    174   $(eval $(ARGS):;@:)
    175 endif
    176 endif
    177 endif
    178 
    179 ifeq ($(ARGS), )
    180 	ARGS := $(shell git branch --show-current)
    181 endif
    182 
    183 prog: # ...
    184     # ...
    185 
    186 .PHONY: draft preview publish
    187 
    188 draft : prog
    189 	scripts/draft $(ARGS) $(RND)
    190 
    191 preview : prog
    192 	scripts/preview $(ARGS)
    193 
    194 publish : prog
    195 	scripts/publish $(ARGS) $(RND)
    196 ```
    197 
    198 As an example, to start a new entry I incant
    199 ```
    200 make draft as_a_matter_of_course
    201 ```
    202 
    203 An empty buffer is opened in `vim` so I can start writing.  After some time I decide I need a break so I save and exit `vim`.  When I come back I know I am already on the *as_a_matter_of_course* branch so I can incant
    204 ```
    205 make draft
    206 ```
    207 
    208 Once the entry is finished I save and exit `vim` then incant
    209 ```
    210 make preview
    211 ```
    212 
    213 After reviewing the finished piece I can incant
    214 ```
    215 make publish
    216 ```
    217 
    218 These three scripts have sped up my writing process as well as making it even easier to switch between drafts if I have more than one entry in the works at a time.
    219 
    220 One issue that I have had to overcome, it's a big one, is that I need to think of the title before I start the draft.  A few of my previous entries have had working titles right up until the moment they are published.  I have thought about adding in a step to the publish script to change the title before it goes out, but for now I will force myself to think harder about the titles.
    221 
    222 There are still some tweaks and improvements I want to look into but I have been happy with this process since I created it, adding in the additional scripts has helped a lot.  It has certainly sped up my workflow and I haven't had any issues with the automated publishing, long may it last.