-
Notifications
You must be signed in to change notification settings - Fork 0
/
publish_6.sh
625 lines (488 loc) · 17.9 KB
/
publish_6.sh
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
#!/usr/bin/env bash
# ==============================================================================
# Change Log:
# ----------------- Carried Over --------------------
# 1. Generate directory level htmls - a collection of posts with their excerpts : DONE
# 2. Fix the link to the sections: DONE
# 5. Support markdown format parsing within shell or using standard perl script: DONE
# ---------------Planned in this version --------------
# 6. Fix the post excerpts formating on section pages: DONE
# Also implemented a workaround for top-level index.html by creating "About" section
# ----------------- Some day --------------------
# 3. Fix the top level index.html
# 4. Refactor the code to remove redundant logic and restructure for clarity
# 7. Fix post tag search / links , especially in case of multiple tags for a post
# 8. Generate section level tag cloud from individual post tags: dir_tag_cloud
# ==============================================================================
topdir=$(pwd)
scriptdir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# configuration: site level config and files / vars =============================================
# Source configuration file if it exists in the project directory
if [ -f "$topdir/_config.sh" ]; then
. "$topdir/_config.sh"
fi
metadata_file="metadata.txt" # search for this file in each section directory for section-wide metadata
site_title=${site_title:-"My default sitename"}
# echo "\nsite_title is $site_title"
site_sub_title=${site_sub_title:-"My default subtitle"}
# echo "\nsite_title is $site_sub_title"
theme_dir=${theme_dir:-"theme3"}
# display a toggle button to show/hide the text
text_toggle=${text_toggle:-true}
social_button=${social_button:-true}
# declare any sub-routines (functions) here ================================================
# $1: template, $2: {{ variable name }}, $3: replacement string
template () {
# remove spaces from the 2nd arguement to template function call
key=$(echo "$2" | tr -d '[:space:]')
# replace all "/" in $3 (3rd arguement) with "\/"
value=$(echo $3 | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/&/\\\&/g') # escape sed input
# replace all instaces of {{some_key}} in template, i.e $1, with {{corresponding_value}}
echo "$1" | sed "s/{{$key}}/$value/g; s/{{$key:[^}]*}}/$value/g"
}
# if on cygwin, transforms given param to windows style path
winpath () {
if command -v cygpath >/dev/null 2>&1
then
cygpath -m "$1"
else
echo "$1"
fi
}
cleanup() {
# remove any ffmpeg log/temp files
rm -f ffmpeg*.log
rm -f ffmpeg*.mbtree
rm -f ffmpeg*.temp
if [ -d "$scratchdir" ]
then
rm -r "$scratchdir"
fi
if [ -e "$output_url" ]
then
rm -f "$output_url"
fi
exit
}
scratchdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'exposetempdir')
scratchdir=$(winpath "$scratchdir")
if [ -z "$scratchdir" ]
then
echo "Could not create scratch directory" >&2; exit 1;
fi
chmod -R 740 "$scratchdir"
trap cleanup EXIT INT TERM
# script starts here
# Scan directory structure and store required variables ========================================
paths=() # relevant non-empty dirs in $topdir; () indicates an empty list
nav_name=() # a front-end friendly label for each item in paths[], with numeric prefixes stripped
nav_depth=() # depth of each navigation item
nav_type=() # 0 = structure, 1 = leaf. Where a leaf directory is a section of images
nav_url=() # a browser-friendly url for each path, relative to _site
nav_count=() # the number of images in each section, or -1 if not a leaf
section_files=() # a flat list of all section images and videos
section_nav=() # index of nav item the section image belongs to
section_url=() # url-friendly name of each image
section_type=() # 0 = image, 1 = video, 2 = image sequence
# scan working directory to populate $nav variables
root_depth=$(echo "$topdir" | awk -F"/" "{ print NF }")
output_url=""
printf "Scanning directories"
while read node
do
printf "."
if [ "$node" = "$topdir/_site" ]
then
continue
fi
node_depth=$(echo "$node" | awk -F"/" "{ print NF-$root_depth }")
# echo "\n node_depth for $node is $node_depth \n"
# ignore empty directories
if find "$node" -maxdepth 0 -empty | read v
then
continue
fi
# extract the filename from filepath (node) and remove all leading numerals, spaces, etc
node_name=$(basename "$node" | sed -e 's/^[0-9]*//' | sed -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [ -z "$node_name" ]
then
node_name=$(basename "$node")
fi
dircount=$(find "$node" -maxdepth 1 -type d ! -path "$node" ! -path "$node*/_*" | wc -l)
dircount_sequence=$(find "$node" -maxdepth 1 -type d ! -path "$node" ! -path "$node*/_*" ! -path "$node/*$sequence_keyword*" | wc -l)
if [ "$dircount" -gt 0 ]
then
if [ -z "$sequence_keyword" ] || [ "$dircount_sequence" -gt 0 ]
then
node_type=0 # dir contains other dirs, it is not a leaf
else
node_type=1 # dir contains other dirs, but they are imagesequence dirs which are not galleries
fi
# echo " node_type for $node is $node_type # 0: Has sub-directories 1: has sub-directories with image sequences \n "
else
if [ ! -z "$sequence_keyword" ] && [ $(echo "$node_name" | grep "$sequence_keyword" | wc -l) -gt 0 ]
then
# echo " $node is is an imagesequence dir, it is in effect a video. Do not add to the path list \n "
continue # dir is an imagesequence dir, it is in effect a video. Do not add to the path list
else
node_type=1 # does not contain other dirs, and is not image sequence. It is a leaf
fi
# echo " node_type for $node is $node_type # \n "
fi
paths+=("$node")
nav_name+=("$node_name")
nav_depth+=("$node_depth")
nav_type+=("$node_type")
done < <(find "$topdir" -type d ! -path "$topdir*/_*" | sort)
echo ". \n ............... paths / files identified ................ \n "
echo ". \n paths: $paths \n "
echo ". \n nav_name: $node_name \n "
echo ". \n nav_depth: $node_depth \n "
echo ". \n nav_type: $node_type \n "
echo ". \n ............................................................... \n\n "
# re-create directory structure under a new subfolder - _site - for the website ===================================
mkdir -p "$topdir/_site"
dir_stack=()
url_rel=""
nav_url+=(".") # first item in paths will always be $topdir
printf "\nPopulating nav"
for i in "${!paths[@]}"
do
printf "."
if [ "$i" = 0 ]
then
continue
fi
path="${paths[i]}"
if [ "$i" -gt 1 ]
then
if [ "${nav_depth[i]}" -gt "${nav_depth[i-1]}" ]
then
# push onto stack when we go down a level
dir_stack+=("$url_rel")
elif [ "${nav_depth[i]}" -lt "${nav_depth[i-1]}" ]
then
# pop stack with respect to current level
diff="${nav_depth[i-1]}"
while [ "$diff" -gt "${nav_depth[i]}" ]
do
unset dir_stack[${#dir_stack[@]}-1]
((diff--))
done
fi
fi
url_rel=$(echo "${nav_name[$i]}" | sed 's/[^ a-zA-Z0-9]//g;s/ /-/g' | tr '[:upper:]' '[:lower:]')
url=""
for u in "${dir_stack[@]}"
do
url+="$u/"
done
url+="$url_rel"
mkdir -p "$topdir/_site/$url"
nav_url+=("$url")
section_nav+=("$i") # copied here from the "store file and type for later use" section for navigation html generation
done
# create the html code for the sidebar ================================================
# build main navigation
navigation=""
# write html menu via depth first search
depth=1
prevdepth=0
remaining="${#paths[@]}"
parent=-1
while [ "$remaining" -gt 1 ]
do
for j in "${!paths[@]}"
do
if [ "$depth" -gt 1 ] && [ "${nav_depth[j]}" = "$prevdepth" ]
then
parent="$j"
fi
if [ "$parent" -lt 0 ] && [ "${nav_depth[j]}" = 1 ]
then
if [ "${nav_type[j]}" = 0 ]
then
navigation+=""
else
gindex=0
for k in "${!section_nav[@]}"
do
if [ "${section_nav[k]}" = "$j" ]
then
gindex="$k"
break
fi
done
navigation+="<a class="sidebar-nav-item" href=\"{{basepath}}${nav_url[j]}\">${nav_name[j]}</a>"
fi
((remaining--))
elif [ "${nav_depth[j]}" = "$depth" ]
then
if [ "${nav_type[j]}" = 0 ]
then
substring="<li><span class=\"label\">${nav_name[j]}</span><ul>{{marker$j}}</ul></li>{{marker$parent}}"
else
gindex=0
for k in "${!section_nav[@]}"
do
if [ "${section_nav[k]}" = "$j" ]
then
gindex="$k"
break
fi
done
substring="<a class="sidebar-nav-item" href=\"{{basepath}}${nav_url[j]}\">${nav_name[j]}</a>"
fi
navigation=$(template "$navigation" "marker$parent" "$substring")
((remaining--))
fi
done
((prevdepth++))
((depth++))
done
nav_template=$(cat "$scriptdir/$theme_dir/nav-template.html")
nav_html="$nav_template"
nav_html=$(template "$nav_html" navigation "$navigation")
# =============================================================================
# read each relevant file in the directory structure and store the processed content for future use =====
# TODO: might be better to create corresponding html files while looping through the files, in the same loop
printf "\nReading files"
# read in each file to populate $section variables
for i in "${!paths[@]}"
do
nav_count[i]=-1
if [ "${nav_type[i]}" -lt 1 ]
then
continue
fi
dir="${paths[i]}"
name="${nav_name[i]}"
url="${nav_url[i]}"
mkdir -p "$topdir"/_site/"$url"
index=0
# loop over found files
while read file
do
printf "."
filename=$(basename "$file")
filedir=$(dirname "$file")
filepath=$(winpath "$file")
# echo ".. \n Currently processing $filename ...... \n"
trimmed=$(echo "${filename%.*}" | sed -e 's/^[[:space:]0-9]*//;s/[[:space:]]*$//')
if [ -z "$trimmed" ]
then
trimmed=$(echo "${filename%.*}")
fi
image_url=$(echo "$trimmed" | sed 's/[^ a-zA-Z0-9]//g;s/ /-/g' | tr '[:upper:]' '[:lower:]')
if [ -d "$file" ] && [ $(echo "$filename" | grep "$sequence_keyword" | wc -l) -gt 0 ]
then
format="sequence"
image=$(find "$file" -maxdepth 1 ! -path "$file" -iname "*.md" -o -iname "*.post" | sort | head -n 1)
else
extension=$(echo "${filename##*.}" | tr '[:upper:]' '[:lower:]')
# we'll trust that extensions aren't lying
if [ "$extension" = "md" ] || [ "$extension" = "post" ] || [ "$extension" = "txt" ]
then
format="$extension"
else
# could be a video file
if [ "$video_enabled" = false ]
then
continue
fi
found=false
for e in "${video_extensions[@]}"
do
if [ "$e" = "$extension" ]
then
found=true
break
fi
done
if [ "$found" = false ]
then
LC_ALL=C file -ib "$filename" | grep video >/dev/null || continue # not image or video or sequence, ignore
fi
format="video"
fi
fi
((index++))
# store file and type for later use
section_files+=("$file")
section_nav+=("$i")
section_url+=("$image_url")
if [ "$format" = "sequence" ]
then
section_type+=(2)
elif [ "$format" = "video" ]
then
section_type+=(1)
else
section_type+=(0)
fi
done < <(find "$dir" -maxdepth 1 ! -path "$dir" ! -path "$dir*/_*" | sort)
nav_count[i]="$index"
done
# build html file for each post ====================================================
# echo "scriptdir/theme_dir/template.html is $scriptdir/$theme_dir/template.html"
# template=$(cat "$scriptdir/$theme_dir/template.html")
post_template=$(cat "$scriptdir/$theme_dir/post-template.html")
dir_template=$(cat "$scriptdir/$theme_dir/dir-template.html")
section_index=0
firsthtml=""
firstpath=""
printf "\nBuilding HTML"
for i in "${!paths[@]}"
do
if [ "${nav_type[i]}" -lt 1 ]
then
continue
fi
echo ".. \n Currently in ${paths[i]} directory ... \n"
dir_html="$nav_html""$dir_template"
all_posts_excerpts=""
dir_tag_cloud=""
section_metadata=""
if [ -e "${paths[i]}/$metadata_file" ] # -e returns true if the arguement exists; checking if the metadata file exists for this dir
then
section_metadata=$(cat "${paths[i]}/$metadata_file")
fi
j=0
while [ "$j" -lt "${nav_count[i]}" ] # looping through all the posts in current directory ${paths[i]}
do
html="$nav_html""$post_template"
printf "." # show progress
k=$((j+1))
file_path="${section_files[section_index]}"
file_type="${section_type[section_index]}"
# try to find a text file with the same name
filename=$(basename "$file_path")
filename="${filename%.*}"
filedir=$(dirname "$file_path")
echo " .. \n Line 453: file_path is $file_path \n file_type is $file_type \n filename is $filename \n filedir is $filedir \n "
type="image"
if [ "${section_type[section_index]}" -gt 0 ]
then
type="video"
fi
#textfile=$(find "$filedir/$filename".post "$filedir/$filename".md ! -path "$file_path" -print -quit 2>/dev/null) #original code
textfile=$(find "$filedir/$filename".post "$filedir/$filename".md ! -path "$filedir" -print -quit 2>/dev/null) #modified; same as $file_path
metadata=""
content=""
if LC_ALL=C file "$textfile" | grep -q text
then
# if there are two lines "---", the lines preceding the second "---" are assumed to be metadata
text=$(cat "$textfile" | tr -d $'\r')
text=${text%$'\n'}
metaline=$(echo "$text" | grep -n -m 2 -- "^---$" | tail -1 | cut -d ':' -f1) # line number after which actual post content starts
if [ "$metaline" ]
then
sumlines=$(echo "$text" | wc -l)
taillines=$((sumlines-metaline)) # Working fine
metadata=$(head -n "$metaline" "$textfile")
content=$(tail -n "$taillines" "$textfile")
else
metadata=""
content=$(echo "$text")
fi
fi
# if perl available, pass content through markdown parser
if command -v perl >/dev/null 2>&1
then
content=$(perl "$scriptdir/Markdown_1.0.1/Markdown.pl" --html4tags <(echo "$content"))
fi
# echo " . \n ............................... \n post content is : \n $content \n ........................ \n "
metadata+=$'\n'
metadata+="$section_metadata"
metadata+=$'\n'
# post=$(template "$post" postcontent "$content")
# reading key value pairs from the post metadata and updating the same in $post
while read line
do
key=$(echo "$line" | cut -d ':' -f1 | tr -d $'\r\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
value=$(echo "$line" | cut -d ':' -f2- | tr -d $'\r\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
colon=$(echo "$line" | grep ':')
echo " .. \n key is $key \t value is $value \n colon is $colon \n "
if [ "$key" ] && [ "$value" ] && [ "$colon" ]
then
html=$(template "$html" "$key" "$value")
fi
if [ "$key" = "posttitle" ]
then
all_posts_excerpts+="<div class=\"post\"><h1 class=\"post-title\">""$value""</h1>"
fi
#if [ "$key" = "postnote" ]
# then
# all_posts_excerpts+="<span class=\"post-date\">""$value"" </span>"
#fi
if [ "$key" = "postexcerpt" ]
then
all_posts_excerpts+="<span class=\"post-date\">---------------------------<br/>""$value""<br/></span>"
fi
done < <(echo "$metadata")
# html=$(template "$html" content "$post {{content}}" true)
html=$(template "$html" postcontent "$content")
# this section can be collated from both dir and file level loops to the time of initialisation of html/dir_html
html=$(template "$html" sitetitle "$site_title")
html=$(template "$html" sitesubtitle "$site_sub_title")
html=$(template "$html" sectiontitle "${nav_name[i]}")
# old code for writing html file; now taken inside the inner loop to create a file per post instead of per dir - part 2
# TODO: below code to identify the html for top level index.html does not work properly.
if [ -z "$firsthtml" ] # -z checks if the arguement is null; it's checking if $firsthtml has been initialised
then
firsthtml="$html"
firstpath="${nav_url[i]}"
fi
if [ "${nav_depth[i]}" = 0 ]
then
basepath="./"
else
basepath=$(yes "../" | head -n ${nav_depth[i]} | tr -d '\n')
fi
html=$(template "$html" basepath "$basepath")
html=$(template "$html" disqus_identifier "${nav_url[i]}")
# set default values for {{XXX:default}} strings
html=$(echo "$html" | sed "s/{{[^{}]*:\([^}]*\)}}/\1/g")
# remove references to any unused {{xxx}} template variables and empty <ul>s from navigation
html=$(echo "$html" | sed "s/{{[^}]*}}//g; s/<ul><\/ul>//g")
# echo "$html" > "$topdir/_site/${nav_url[i]}"/index.html
echo "$html" > "$topdir/_site/${nav_url[i]}/$filename".html
# add MORE link for each post excerpt for directory level html
all_posts_excerpts+="<a href=./$filename"".html> More </a> <hr/>"
((section_index++))
((j++))
done
# generate directory level html with list of all posts ==============================
dir_html=$(template "$dir_html" all_posts_excerpts "$all_posts_excerpts")
# this section can be collated from both dir and file level loops to the time of initialisation of html/dir_html
dir_html=$(template "$dir_html" sitetitle "$site_title")
dir_html=$(template "$dir_html" sitesubtitle "$site_sub_title")
dir_html=$(template "$dir_html" sectiontitle "${nav_name[i]}")
if [ "${nav_depth[i]}" = 0 ]
then
basepath="./"
else
basepath=$(yes "../" | head -n ${nav_depth[i]} | tr -d '\n')
fi
dir_html=$(template "$dir_html" basepath "$basepath")
# set default values for {{XXX:default}} strings
dir_html=$(echo "$dir_html" | sed "s/{{[^{}]*:\([^}]*\)}}/\1/g")
# remove references to any unused {{xxx}} template variables and empty <ul>s from navigation
dir_html=$(echo "$dir_html" | sed "s/{{[^}]*}}//g; s/<ul><\/ul>//g")
echo "$dir_html" > "$topdir/_site/${nav_url[i]}/"index.html
# echo "$dir_html" > "${paths[i]}"index.html
done
# write top level index.html =========================================================
basepath="./"
firsthtml=$(template "$firsthtml" basepath "$basepath")
firsthtml=$(template "$firsthtml" disqus_identifier "$firstpath")
firsthtml=$(template "$firsthtml" resourcepath "$firstpath/")
firsthtml=$(echo "$firsthtml" | sed "s/{{[^{}]*:\([^}]*\)}}/\1/g")
firsthtml=$(echo "$firsthtml" | sed "s/{{[^}]*}}//g; s/<ul><\/ul>//g")
echo "$firsthtml" > "$topdir/_site"/index.html
printf "\nStarting encode\n"
# copy resources to _site
echo "topdir is: $topdir \n"
echo "scriptdir/theme_dir is: $scriptdir/$theme_dir/"
rsync -av --exclude="dir-template.html" --exclude="nav-template.html" --exclude="post-template.html" "$scriptdir/$theme_dir/" "$topdir/_site/" >/dev/null
cleanup