Skip to content

Commit 3434fd1

Browse files
author
Vijith Assar
committed
add annotated source
from here forward the script will be recursively compiled by the previous version of itself, which seems like a funny idea right now but will almost certainly blow up in my face shortly
1 parent b1e955b commit 3434fd1

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

lit.sh.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Start #
2+
3+
The shebang indicates that this script should be executed by the bash program.
4+
5+
```bash
6+
#!/bin/bash
7+
```
8+
9+
# Filenames #
10+
11+
We want to support any type of code wrapped in Markdown, so we'll make no assumptions about the filename and extension preceding it and pass it through unmodified for use as the output filename.
12+
13+
```bash
14+
# given a filename ending in .md, return the base filename
15+
function remove_extension {
16+
local file=$1
17+
# file extension .md will always have three characters
18+
local extension_length=3
19+
# old file path length
20+
local old_length=${#file}
21+
# calculate new filename length
22+
local new_length=$old_length-$extension_length
23+
# cut substring for new filename
24+
local new_filename=${file:0:$new_length}
25+
# return the new string
26+
echo "$new_filename"
27+
}
28+
```
29+
30+
# Processing
31+
32+
This function uses a needlessly expanded version of [Rich Traube](https://github.com/trauber)'s clever [one-line awk routine](https://gist.github.com/trauber/4955706) to walk through the lines in the Markdown document and pass them into the output file as appropriate.
33+
34+
```bash
35+
# strip Markdown
36+
function process_lines {
37+
# first argument is filename
38+
local file=$1
39+
# iterate through lines with awk
40+
local awk_command='
41+
# if it is a code block
42+
if (/^```/) {
43+
# increase backtick counter
44+
i++;
45+
# jump to next command
46+
next;
47+
}
48+
# print
49+
if ( i % 2 == 1) {
50+
print;
51+
}
52+
'
53+
# run awk command
54+
local processed=$(awk {"$awk_command"} $file)
55+
# return code blocks only
56+
echo "$processed"
57+
}
58+
```
59+
60+
# Single File #
61+
62+
Wrap the awk routine and the filename logic into a single function which can be called on any file to compile its output.
63+
64+
```bash
65+
# compile Markdown code blocks in a file using awk
66+
function compile {
67+
# first argument is filename
68+
local file=$1
69+
# conver to the new filename
70+
local new_filename=$(remove_extension $file "md")
71+
# log message
72+
echo "compiling $file > $new_filename"
73+
# parse file content and remove Markdown comments
74+
local compiled=$(process_lines $file)
75+
# save results to file
76+
echo "$compiled" > $new_filename
77+
}
78+
```
79+
80+
# Loop Through Files #
81+
82+
Everything up until this point has been wrapped in a reusable function, but now it's time to define the script logic. Grab the files specified by an optional filename pattern (or alternatively the files in the current working directory) and run the compilation function on each.
83+
84+
```bash
85+
# if the first argument exists, use it as the
86+
# target directory
87+
if [ $1 ]; then
88+
files=$1
89+
# otherwise load all files in current directory
90+
else
91+
# files must end in .md and must contain TWO
92+
# dots so as to exclude regular non-source
93+
# Markdown files
94+
files=*.*.md
95+
fi
96+
97+
# loop through files
98+
for file in $files
99+
do
100+
# compile
101+
compile $file
102+
done
103+
```

0 commit comments

Comments
 (0)