1 #!/usr/bin/zsh
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 VERSION="0.4.3"
20 QSGEN="Quick Site Generator 2"
21
22
23
24
25 globaldebug=false
26
27
28 fpath=(${HOME}/bin/include/common ${HOME}/bin/include/qsgen2/lang $fpath)
29
30 autoload include
31 autoload zini
32
33
34 include common/colors
35
36 echo "${magenta}${blue_bg} ${QSGEN} ${end}${bold_white}${blue_bg}${VERSION} ${end}"
37
38
39 if [[ -f $(pwd)/config ]]; then
40 if (${globaldebug}); then echo "${red}Config file found and sourced${end}\n${yellow} - $(pwd)/config${end}"; fi
41 zini $(pwd)/config
42 else
43 echo "${red}Cannot find configuration file.${end}"
44 echo "${yellow} - Please create the file 'config' in your project directory.${end}"
45 echo "${yellow} - See 'config.example' in the git source tree.${end}"
46 exit
47 fi
48
49
50 typeset -A qsgenlang
51 lang_found=false
52 for dir in $fpath; do
53 if [[ -f "${dir}/${config[project_lang]}" ]]; then
54
55 source "${dir}/${config[project_lang]}"
56 lang_found=true
57 break
58 fi
59 done
60 if [[ ${lang_found} == "false" ]]; then
61
62 echo "Defined language, ${config[project_lang]}, not found. Using en_US."
63 source "${HOME}/bin/include/qsgen2/lang/en_US"
64 fi
65
66 if (${globaldebug}); then
67 qsconfig=$( cat $(pwd)/config | grep -v \# | awk '{print substr($0, index($0, " ") + 1)}' )
68 echo "Content of Config file"
69 for qslines in ${qsconfig}
70 do
71 echo "${yellow}${qslines}${end}"
72 done
73 fi
74
75 function _msg() {
76 local type=$1
77 shift
78
79 local full_msg=""
80 for arg in "$@"; do
81 if [[ -n "${qsgenlang[$arg]}" ]]; then
82 full_msg+="${qsgenlang[$arg]}"
83 else
84 full_msg+="$arg"
85 fi
86 done
87
88
89 local color="${end}"
90 case $type in
91 std) color="${green}" ;;
92 info) color="${yellow}" ;;
93 debug) color="${red}" ;;
94 other) color="${bold_yellow}" ;;
95 sub) color="${magenta}" ;;
96 main) color="${white}${green_bg}" ;;
97 esac
98
99
100 printf "${color}%b${end}\n" "${full_msg}"
101 }
102
103 function _version() {
104 _msg info "_qsgen2_msg_7" "-$(strftime "%Y")"
105 echo "${yellow}- https://github.com/kekePower/qsgen2/${end}"
106 _msg info "_qsgen2_msg_8" " '${1} help' " "_qsgen2_msg_8.1"
107 exit
108 }
109
110 function _help() {
111
112 echo "This is where I'll write the Help documentation."
113 exit
114 }
115
116 if [[ "$1" == "version" || "$1" == "-v" || "$1" == "--version" ]]; then
117 _version ${0:t}
118 elif [[ "$1" == "help" || "$1" == "-h" || "$1" == "--help" ]]; then
119 _help ${0:t}
120 fi
121
122
123 blog_cache_file="${config[project_root]}/.blog_cache"
124 pages_cache_file="${config[project_root]}/.pages_cache"
125
126
127 if [[ ! ${config[project_generator]} ]] || [[ -d $(pwd)/.git ]]; then
128 _msg debug "_qsgen2_msg_3"
129 exit
130 fi
131
132
133 if [[ ${config[project_generator]} == "native" ]]; then
134
135 engine=_qstags
136 export file_ext="qst"
137 elif [[ ${config[project_generator]} == "markdown" ]]; then
138 if [[ ! -f /usr/local/bin/pandoc ]]; then
139 _msg other "_qsgen2_msg_4"
140 _msg other "https://github.com/jgm/pandoc/releases"
141 exit
142 else
143
144 engine="/usr/local/bin/pandoc"
145 engine_opts=
146 export file_ext="md"
147 fi
148 else
149 _msg debug "_qsgen2_msg_5"
150 exit
151 fi
152
153 function _run_engine() {
154
155 local debug=false
156
157 if [[ ${config[project_generator]} == "native" ]]; then
158 ${engine} ${1}
159 elif [[ ${config[project_generator]} == "markdown" ]]; then
160 echo "${1} | ${engine} ${engine_opts}"
161 else
162 _msg debug "ERROR running engine: ${engine}!"
163 _msg info "Usage: _run_engine <input>"
164 exit
165 fi
166 }
167
168 if (${globaldebug}); then _msg debug "_qsgen2_msg_6"; fi
169
170 builtin cd ${config[project_root]}
171
172
173 zmodload zsh/files
174 zmodload zsh/datetime
175 zmodload zsh/regex
176
177
178 export today=$(strftime "%Y-%m-%d - %T")
179 export blogdate=$(strftime "%a-%Y-%b-%d")
180
181
182
183 function _list_pages() {
184
185 if [[ ${globaldebug} == "true" ]]; then
186 local debug=true
187 else
188 local debug=false
189 fi
190
191
192 pages_file_array=()
193
194 export no_pages_found=false
195
196
197 setopt local_options null_glob
198
199
200 local -a pages_files=(*.${file_ext})
201
202 if (( ${#pages_files} == 0 )); then
203 if ${debug}; then _msg debug "${0:t}_msg_1" " ${file_ext}."; fi
204 export no_pages_found=true
205 return
206 else
207 for file in "${pages_files[@]}"; do
208 if ${debug}; then _msg debug "${0:t}_msg_2" " ${file}"; fi
209 pages_file_array+=("$file")
210 done
211 fi
212
213 }
214
215 function _list_blogs() {
216
217 if [[ ${globaldebug} == "true" ]]; then
218 local debug=true
219 else
220 local debug=false
221 fi
222
223
224 blogs_file_array=()
225
226 export no_blogs_found=false
227
228
229 setopt local_options null_glob
230
231
232 local -a blog_files=(blog/*.blog(On))
233
234 if (( ${#blog_files[@]} == 0 )); then
235 if ${debug}; then _msg debug "${0:t}_msg_1"; fi
236 export no_blogs_found=true
237 return
238 else
239 for file in "${blog_files[@]}"
240 do
241 if ${debug}; then _msg debug "${0:t}_msg_2" " $file"; fi
242 blogs_file_array+=("$file")
243 done
244 fi
245
246 }
247
248
249
250 function _blog_cache() {
251
252 if [[ ${globaldebug} == "true" ]]; then
253 local debug=true
254 else
255 local debug=false
256 fi
257
258 _list_blogs
259
260
261 typeset -A blog_cache
262
263
264 if [[ -f $blog_cache_file ]]; then
265 while IFS=':' read -r name hash; do
266 blog_cache[$name]=$hash
267 if (${debug}) _msg debug "${0:t}_msg_1" " ${blog_cache[${name}]}"
268 done < "$blog_cache_file"
269 fi
270
271
272 make_blog_array=()
273
274
275 for blog_file in ${blogs_file_array[@]}; do
276
277 current_hash=$(md5sum "$blog_file" | awk '{print $1}')
278
279 if (${debug}) _msg debug "${0:t}_msg_2" " ${blog_file}"
280 if (${debug}) _msg debug "${0:t}_msg_3" " ${current_hash}"
281
282
283 if [[ ${blog_cache[$blog_file]} != "$current_hash" ]]; then
284 if (${debug}) _msg debug "${0:t}_msg_4" " ${blog_file}"
285 if (${debug}) _msg debug "${0:t}_msg_5" " ${current_hash}"
286
287 make_blog_array+=("$blog_file")
288
289
290 blog_cache[$blog_file]=$current_hash
291 fi
292 done
293
294
295 : >| "$blog_cache_file"
296 for name in "${(@k)blog_cache}"; do
297 echo "$name:${blog_cache[$name]}" >> "$blog_cache_file"
298 done
299
300 }
301
302
303
304
305 function _pages_cache() {
306
307 if [[ ${globaldebug} == "true" ]]; then
308 local debug=true
309 else
310 local debug=false
311 fi
312
313
314 typeset -A pages_cache
315
316 _list_pages
317
318
319 if [[ -f $pages_cache_file ]]; then
320 while IFS=':' read -r name hash; do
321 pages_cache[$name]=$hash
322 if (${debug}) _msg debug "${0:t}_msg_1" " ${pages_cache[${name}]}"
323 done < "$pages_cache_file"
324 fi
325
326
327 pages_array=()
328
329
330 for file in ${pages_file_array[@]}; do
331
332 current_hash=$(md5sum "$file" | awk '{print $1}')
333
334 if (${debug}) _msg debug "${0:t}_msg_2" " ${pages_cache[$file]}"
335 if (${debug}) _msg debug "${0:t}_msg_3" " current_cache: ${current_hash}"
336
337
338 if [[ ${pages_cache[$file]} != "$current_hash" ]]; then
339 if (${debug}) _msg debug "${0:t}_msg_4" " ${pages_cache[$file]}"
340 if (${debug}) _msg debug "${0:t}_msg_5" " current_cache: ${current_hash}"
341
342
343 pages_array+=("$file")
344
345
346 pages_cache[$file]=$current_hash
347 fi
348 done
349
350
351 : >| "$pages_cache_file"
352 for name in "${(@k)pages_cache}"; do
353 echo "$name:${pages_cache[$name]}" >> "$pages_cache_file"
354 done
355
356 }
357
358 function _last_updated() {
359
360
361 if [[ ${globaldebug} == "true" ]]; then
362 local debug=true
363 else
364 local debug=false
365 fi
366
367 local upd_msg="Last updated ${today} by <a href=\"https://blog.kekepower.com/qsgen2.html\">${QSGEN} ${VERSION}</a>"
368
369 if (${debug}); then _msg debug "${0:t}_msg_1"; fi
370 if (${debug}); then _msg debug "${0:t}_msg_2" " ${upd_msg}"; fi
371
372 local content="${1}"
373
374
375 local updated_content=$(echo "${content}" | sed \
376 -e "s|#updated|${upd_msg}|")
377
378
379 echo "${updated_content}"
380
381 }
382
383 function _f_last_updated() {
384
385
386 if [[ ${globaldebug} == "true" ]]; then
387 local debug=true
388 else
389 local debug=false
390 fi
391
392
393 local upd_msg="Last updated ${today} by <a href=\"https://blog.kekepower.com/qsgen2.html\">${QSGEN} ${VERSION}</a>"
394
395 if ${debug}; then
396 _msg debug "${0:t}_msg_1" " ${1}"
397 _msg debug "${0:t}_msg_2" " ${upd_msg}"
398 fi
399
400
401 local content="$(<${1})"
402
403
404 content="${content//#updated/${upd_msg}}"
405
406 if [[ -f "${1}" ]]; then
407 sed -i -e "s|#updated|${upd_msg}|" "${1}"
408 else
409 _msg debug "${0:t}_msg_3" " '${1}' " "${0:t}_msg_3.1"
410 fi
411
412 }
413
414 function _file_to_lower() {
415
416 local filename="${1}"
417
418
419 filename="${filename// /-}"
420
421
422 filename=$(echo "${filename}" | sed -e 's/^[^a-zA-Z0-9_.]+//g' -e 's/[^a-zA-Z0-9_-]+/-/g')
423
424 echo ${filename}
425
426 }
427
428
429 function _pages() {
430
431
432 if [[ ${globaldebug} == "true" ]]; then
433 local debug=true
434 else
435 local debug=false
436 fi
437
438 _msg main "${0:t}_msg_3"
439
440
441 if (${debug}) _msg debug "${0:t}_msg_1"
442 _pages_cache
443
444 if [[ ${no_pages_found} == "true" ]]; then
445 _msg sub "${0:t}_msg_1"
446 return
447 fi
448
449 if (( ${#pages_array[@]} > 0 )); then
450
451
452 if (${debug}) _msg debug "${0:t}_msg_4"
453
454 for pages_in_array in ${pages_array[@]}
455 do
456 if (${debug}) _msg debug "${0:t}_msg_5"
457 local pages=${config[project_root]}/themes/${config[site_theme]}/pages.tpl
458
459
460
461 if [[ ! -f ${pages} ]]; then
462 _msg info "${0:t}_msg_6" " ${pages}"
463 exit
464 else
465
466 if (${debug}) _msg debug "${0:t}_msg_7"
467 local pages_tpl="$(<${pages})"
468 fi
469
470
471
472 if (${debug}) _msg debug "${0:t}_msg_9" " ${pages_in_array}"
473 local page_content="$(<${pages_in_array})"
474
475
476 if (${debug}) _msg debug "${0:t}_msg_10"
477 if [[ ${config[project_generator]} == "native" ]]; then
478 while read -r line
479 do
480 if [[ "$line" =~ ^#title=(.*) ]]; then
481 local page_title=${match[1]}
482 break
483
484 fi
485 done <<< "$page_content"
486 elif [[ ${config[project_generator]} == "markdown" ]]; then
487 while IFS= read -r line
488 do
489
490 if [[ "$line" == \#* ]]; then
491
492 local page_title="${line#\#}"
493 page_title="${page_title#\#}"
494 page_title="${page_title#"${page_title%%[![:space:]]*}"}"
495 break
496 fi
497 done <<< ${page_content}
498 fi
499 _msg std " - ${page_title}"
500 if (${debug}) _msg debug "${0:t}_msg_11" " ${page_title}"
501
502
503 if (${debug}) _msg debug "${0:t}_msg_12"
504 page_content=$( echo ${page_content} | grep -v \#title )
505
506
507 if (${debug}) _msg debug "${0:t}_msg_13" " ${pages_in_array}"
508 page_content=$( _run_engine "$page_content" )
509
510 if (${debug}) _msg debug "${0:t}_msg_14"
511 if [[ $( echo ${page_content} | grep \#link ) ]]; then
512 if (${debug}) _msg debug "${0:t}_msg_15"
513 page_content=$( _link "${page_content}" )
514 fi
515 if [[ $( echo ${page_content} | grep \#showimg ) ]]; then
516 if (${debug}) _msg debug "${0:t}_msg_16"
517 page_content=$( _image "${page_content}" )
518 fi
519 if [[ $( echo ${page_content} | grep \#ytvideo ) ]]; then
520 if (${debug}) _msg debug "${0:t}_msg_17"
521 page_content=$( _youtube "${page_content}" )
522 fi
523
524
525 if (${debug}) _msg debug "${0:t}_msg_18"
526 pages_tpl=$(echo "${pages_tpl}" | perl -pe "s|#pagetitle|${page_title}|gs; s|#tagline|${config[site_tagline]}|gs; s|#sitename|${config[site_name]}|gs")
527
528 if (${debug}) _msg debug "${0:t}_msg_19"
529
530 pages_tpl=$( awk -v new_body="$page_content" '{sub(/BODY/, new_body)} 1' <(echo "${pages_tpl}") )
531
532
533 if (${debug}) _msg debug "${0:t}_msg_20"
534 pages_tpl=$( _last_updated ${pages_tpl} )
535
536
537 if (${debug}) _msg debug "${0:t}_msg_21"
538 pages_title_lower=$( _file_to_lower "${pages_in_array}" )
539
540
541 if (${debug}) _msg debug "${0:t}_msg_22"
542 pages_tpl=$( _cleanup "${pages_tpl}" )
543
544
545
546 echo "${pages_tpl}" > ${config[site_root]}/${pages_title_lower%.*}.html
547
548
549
550 if [[ ${pages_in_array} == "index.${file_ext}" && ${config[site_blog]} == "true" && -s "${config[project_root]}/blog/index.tmp.html" ]]; then
551 if (${debug}) _msg sub "${0:t}_msg_23" " ${pages_in_array}"
552 if (${debug}) _msg sub "${0:t}_msg_24" " ${config[site_blog]}"
553 if (${debug}) _msg sub "${0:t}_msg_25"
554 if (${debug}) ls -l ${config[project_root]}/blog/index.tmp.html
555 _add_blog_list_to_index
556 fi
557
558 done
559
560 export new_updated_pages=true
561
562 else
563
564
565 if [[ ${config[site_blog]} == "true" && -s "${config[project_root]}/blog/index.tmp.html" ]]; then
566 _msg std "${0:t}_msg_26"
567 if (${debug}) _msg sub "${0:t}_msg_27" " ${pages_in_array}"
568 if (${debug}) _msg sub "${0:t}_msg_28" " ${config[site_blog]}"
569 if (${debug}) _msg sub "${0:t}_msg_25"
570 if (${debug}) ls -l ${config[project_root]}/blog/index.tmp.html
571 _add_blog_list_to_index
572 fi
573
574 _msg sub "${0:t}_msg_29"
575 export new_updated_pages=false
576
577 fi
578
579 }
580
581 function _blogs() {
582
583
584 if [[ ${globaldebug} == "true" ]]; then
585 local debug=true
586 else
587 local debug=false
588 fi
589
590 _msg main "${0:t}_msg_3"
591
592
593 if (${debug}) _msg debug "${0:t}_msg_1"
594 _list_blogs
595
596 if [[ ${no_blogs_found} == "true" ]]; then
597 _msg sub "${0:t}_msg_2"
598 return
599 fi
600
601
602 if (${debug}) _msg debug "${0:t}_msg_4"
603 _blog_cache
604
605 if (( ${#make_blog_array[@]} > 0 )); then
606
607
608 BLOG_META_STR_ARRAY=()
609
610
611
612 if [[ -f ${config[project_root]}/themes/${config[site_theme]}/blogs.tpl ]]; then
613 local blog_tpl=$(<"${config[project_root]}/themes/${config[site_theme]}/blogs.tpl")
614 else
615 _msg info "${0:t}_msg_5"
616 exit
617 fi
618
619 for blog in "${make_blog_array[@]}"; do
620 if (${debug}) _msg info "*************************************************************************"
621 if (${debug}) _msg info "**************************FOR LOOP START*********************************"
622 if (${debug}) _msg info "*************************************************************************"
623 if (${debug}) _msg debug "${0:t}_msg_6" " ${blog}"
624
625 local content="$(<"${blog}")"
626 local sdate btitle ingress body blog_index blog_dir blog_url
627
628
629 local date_found=false
630 local title_found=false
631
632
633 while IFS= read -r line
634 do
635
636 if [[ "${line}" == "DATE "* ]]; then
637 if (${debug}) _msg debug "${0:t}_msg_7"
638 date_found=true
639 fi
640
641 if [[ "${line}" == "BLOG_TITLE "* ]]; then
642 if (${debug}) _msg debug "${0:t}_msg_8"
643 title_found=true
644 fi
645
646 if [[ "${date_found}" == true && "${title_found}" == true ]]; then
647 break
648 fi
649 done <<< "${content}"
650
651
652 if [[ "${date_found}" == false ]]; then
653 if (${debug}) _msg debug "${0:t}_msg_9" " ${blog}."
654 continue
655 fi
656 if [[ "${title_found}" == false ]]; then
657 if (${debug}) _msg debug "${0:t}_msg_10" " ${blog}."
658 continue
659 fi
660
661
662 sdate=( $( echo ${content} | grep DATE | sed "s|DATE\ ||" | sed "s|\-|\ |g" ) )
663 if [[ ${config[project_generator]} == "native" ]]; then
664 if (${debug}) _msg debug "* qstags: Fetching BLOG_TITLE"
665 while IFS= read -r line; do
666 if [[ "$line" == "BLOG_TITLE "* ]]; then
667 btitle="${line#BLOG_TITLE }"
668 break
669 fi
670 done <<< "$content"
671 elif [[ ${config[project_generator]} == "markdown" ]]; then
672 if (${debug}) _msg debug "* markdown: Fetching BLOG_TITLE"
673 while IFS= read -r line; do
674 if [[ "$line" == \#* ]]; then
675 btitle="${line#\#}"
676 btitle="${btitle#\#}"
677 btitle="${btitle#"${btitle%%[![:space:]]*}"}"
678 break
679 fi
680 done <<< "$content"
681 fi
682 if (${debug}) _msg debug "* Fetching INGRESS"
683 ingress=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#INGRESS_START\K(.*?)#INGRESS_STOP" | sed "s|\ \#INGRESS_STOP||" | sed "s|^\ ||" )
684 if (${debug}) _msg debug "* Fetching BODY"
685 body=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#BODY_START\K(.*?)#BODY_STOP" | sed "s|\ \#BODY_STOP||" | sed "s|^\ ||" )
686
687 blog_index=$(echo "${btitle:l}" | sed 's/ /_/g; s/,//g; s/\.//g; s/://g; s/[()]//g')
688
689 blog_dir="/blog/${sdate[2]}/${sdate[3]:l}/${sdate[4]}"
690 blog_url="${blog_dir}/${blog_index}.html"
691
692 if (${debug}) _msg debug "${0:t}_msg_11" " ${blog} " "${0:t}_msg_11.1"
693
694
695 local metadata_str="SDATE: ${sdate[@]}||BTITLE: ${btitle}||INGRESS: ${ingress}||URL: ${blog_url}"
696
697 BLOG_META_STR_ARRAY+=("${metadata_str}")
698
699 if (${debug}) _msg debug "${0:t}_msg_12" " ${blog}"
700
701 _msg std " - ${btitle}"
702
703
704 if (${debug}) _msg debug "${0:t}_msg_14" " ${blog}"
705 local blog_content=$(
706 echo "${blog_tpl}" | \
707 perl -pe "\
708 s|BLOGTITLE|${btitle}|g; \
709 s|BLOGURL|${blog_url}|g; \
710 s|\QINGRESS\E|${ingress}|g; \
711 s|\QBODY\E|${body}|g \
712 ")
713 blog_content="${blog_content//CALNDAY/${sdate[4]}}"
714 blog_content="${blog_content//CALYEAR/${sdate[2]}}"
715 blog_content="${blog_content//CALMONTH/${sdate[3]}}"
716 blog_content="${blog_content//CALADAY/${sdate[1]}}"
717
718 if (${debug}) _msg debug "${0:t}_msg_15" " ${engine} " "${0:t}_msg_15_1" " ${blog}"
719 blog_content=$( _run_engine "${blog_content}" )
720
721 if (${debug}) _msg debug "${0:t}_msg_16"
722 if [[ $( echo ${blog_content} | grep \#link ) ]]; then
723 if (${debug}) _msg debug "${0:t}_msg_17"
724 blog_content=$(_link "${blog_content}")
725 fi
726 if [[ $( echo ${blog_content} | grep \#showimg ) ]]; then
727 if (${debug}) _msg debug "${0:t}_msg_18"
728 blog_content=$(_image "${blog_content}")
729 fi
730 if [[ $( echo ${blog_content} | grep \#ytvideo ) ]]; then
731 if (${debug}) _msg debug "${0:t}_msg_19"
732 blog_content=$(_youtube "${blog_content}")
733 fi
734
735
736 if (${debug}) _msg debug "${0:t}_msg_20"
737 blog_content=$( echo ${blog_content} | perl -pe "s|#tagline|${config[site_tagline]}|gs; s|#sitename|${config[site_name]}|gs; s|#pagetitle|${page_title}|gs" )
738
739 if (${debug}) _msg debug "* Running _last_updated"
740 blog_content=$(_last_updated "${blog_content}")
741 if (${debug}) _msg debug "* Running _cleanup"
742 blog_content=$(_cleanup "${blog_content}")
743
744
745 if (${debug}) _msg debug "${0:t}_msg_21" " ${config[site_root]}${blog_dir}"
746 [[ ! -d "${config[site_root]}/${blog_dir}" ]] && mkdir -p "${config[site_root]}/${blog_dir}"
747
748
749 if (${debug}) _msg debug "${0:t}_msg_22" " ${config[site_root]}${blog_url}"
750 echo "${blog_content}" > "${config[site_root]}${blog_url}"
751
752 unset sdate btitle ingress body blog_index blog_dir blog_url
753
754 done
755
756 export BLOG_META_STR_ARRAY
757 if (${debug}) _msg debug "${0:t}_msg_23"
758 export new_updated_blogs=true
759
760 else
761 _msg sub "${0:t}_msg_24"
762 export new_updated_blogs=false
763 fi
764
765 if [[ ${new_updated_blogs} == "true" ]]; then
766 if (${debug}) _msg sub "${0:t}_msg_25"
767 _blog_idx_for_index
768 if (${debug}) _msg sub "${0:t}_msg_26"
769 _blog_index
770 fi
771
772 }
773
774 function _blog_idx_for_index() {
775
776
777 if [[ ${globaldebug} == "true" ]]; then
778 local debug=true
779 else
780 local debug=false
781 fi
782
783 _msg sub "${0:t}_msg_1" " ${config[project_root]}/blog/index.tmp.html"
784
785 if (${debug}) _msg debug "${0:t}_msg_2"
786
787 local blog_list_tpl=$(<${config[project_root]}/themes/${config[site_theme]}/blog_list.tpl)
788 local blog_list_content=""
789
790
791 : >| "${config[project_root]}/blog/index.tmp.html"
792
793
794
795 for meta_str in ${BLOG_META_STR_ARRAY[@]}
796 do
797 if (${debug}) _msg debug "${0:t}_msg_4"
798 if (${debug}) _msg debug "${0:t}_msg_5" " ${meta_str}"
799
800
801 local -a meta_array=("${(@s/||/)meta_str}")
802
803
804 local sdate btitle ingress url
805
806
807 if (${debug}) _msg debug "${0:t}_msg_6"
808 for component in "${meta_array[@]}"
809 do
810 case "${component}" in
811 SDATE:*) sdate=${component#SDATE: } ;;
812 BTITLE:*) btitle=${component#BTITLE: } ;;
813 INGRESS:*) ingress=${component#INGRESS: } ;;
814 URL:*) url=${component#URL: } ;;
815 esac
816
817 done
818
819 local adate=( $( echo ${sdate} ) )
820 local caladay="${adate[1]}"
821 local calyear="${adate[2]}"
822 local calmonth="${adate[3]}"
823 local calnday="${adate[4]}"
824
825 local bdate="${adate[1]} - ${adate[4]}/${adate[3]}/${adate[2]}"
826 blog_list_content+=$(
827 echo "${blog_list_tpl}" | \
828 perl -pe "\
829 s|BLOGURL|${config[site_url]}${url}|g; \
830 s|BLOGTITLE|${btitle}|g; \
831 s|INGRESS|${ingress}|g; \
832 s|BLOGDATE|${bdate}|g; \
833 s|CALADAY|${caladay}|g; \
834 s|CALNDAY|${calnday}|g; \
835 s|CALMONTH|${calmonth}|g; \
836 s|CALYEAR|${calyear}|g \
837 ")
838
839 unset sdate btitle ingress url adate caladay calyear calmonth calnday
840
841 done
842 if (${debug}) _msg debug "${0:t}_msg_7" " ${engine} " "${0:t}_msg_7.1"
843
844 blog_list_content=$( _run_engine ${blog_list_content} )
845 if (${debug}) _msg debug "${0:t}_msg_8" " ${config[project_root]}/blog/index.tmp.html"
846
847 echo ${blog_list_content} > ${config[project_root]}/blog/index.tmp.html
848
849 }
850
851 function _blog_index() {
852
853 if [[ ${globaldebug} == "true" ]]; then
854 local debug=true
855 else
856 local debug=false
857 fi
858
859
860
861 if [[ ${config[site_blog]} == "false" ]] && [[ ${new_updated_blogs} = "true" ]]; then
862
863 if (${debug}) _msg debug "${0:t}_msg_1" "${config[site_blog]}"
864 if (${debug}) _msg debug "${0:t}_msg_2" "${new_updated_blogs}"
865 if (${debug}) _msg debug "${0:t}_msg_3"
866 if (${debug}) _msg debug "${0:t}_msg_4" " ${config[site_blog]}"
867
868 _msg std "${0:t}_msg_5" " ${config[site_root]}/blog/index.html"
869
870 local blog_index_tpl=$(<${config[project_root]}/themes/${config[site_theme]}/blog_index.tpl)
871 local blog_index_list=$(<${config[project_root]}/blog/index.tmp.html)
872
873 if (${debug}) _msg debug "${0:t}_msg_6"
874 local blog_index_content=$(echo "${blog_index_tpl}" | perl -pe "s|#sitename|${config[site_name]}|gs; s|#tagline|${config[site_tagline]}|gs")
875 if (${debug}) _msg debug "${0:t}_msg_7" " ${config[project_root]}/blog/index.tmp.html"
876 blog_index_content=$( awk -v new_body="$blog_index_list" '{sub(/BODY/, new_body)} 1' <(echo "${blog_index_content}") )
877
878 if (${debug}); then
879 _msg debug "${0:t}_msg_8" " ${config[site_root]}/blog/index.html"
880 _msg debug "${0:t}_msg_9" " ${#blog_index_content}"
881 fi
882 echo "$blog_index_content" > ${config[site_root]}/blog/index.html
883 _f_last_updated ${config[site_root]}/blog/index.html
884
885 fi
886
887 }
888
889 function _add_blog_list_to_index() {
890
891 if [[ ${globaldebug} == "true" ]]; then
892 local debug=true
893 else
894 local debug=false
895 fi
896
897
898 if (${debug}) _msg debug "${0:t}_msg_1"
899 local blog_index_list=$(<${config[project_root]}/blog/index.tmp.html)
900 local site_index_file=$(<${config[site_root]}/index.html)
901 echo "${site_index_file}" | awk -v new_body="${blog_index_list}" '{sub(/BLOGINDEX/, new_body)} 1' > "${config[site_root]}/index.html"
902
903 }
904
905 function _sitemap() {
906
907 if [[ ${globaldebug} == "true" ]]; then
908 local debug=true
909 else
910 local debug=false
911 fi
912
913
914 if ([[ ${config[site_sitemap]} == "true" ]] && ( [[ ${new_updated_blogs} == "true" ]] || [[ ${new_updated_pages} == "true" ]] )) || [[ ${sitemap_force} == "true" ]]; then
915
916 setopt extendedglob
917
918 _msg main "${0:t}_msg_1"
919
920 local sm_file="sitemap.xml"
921 local b_file="sitemap-blogs.xml"
922 local p_file="sitemap-pages.xml"
923 local sitemap_file="${config[site_root]}/${sm_file}"
924 local sitemap_blog="${config[site_root]}/${b_file}"
925 local sitemap_page="${config[site_root]}/${p_file}"
926
927
928 builtin cd ${config[site_root]}
929 local -a html_files=(**/[a-z]*.html(.))
930 local -a blog_files=()
931 local -a page_files=()
932 for file in "${html_files[@]}"; do
933 if [[ $file == *blog* ]]; then
934 blog_files+=("$file")
935 else
936 page_files+=("$file")
937 fi
938 done
939
940
941 echo '<?xml version="1.0" encoding="UTF-8"?>' > ${sitemap_blog}
942 echo "<!-- Sitemap generated by ${QSGEN} ${VERSION} - https://github.com/kekePower/qsgen2 -->" >> ${sitemap_blog}
943 echo "<?xml-stylesheet type=\"text/xsl\" href=\"${config[site_url]}/css/default-sitemap.xsl?sitemap=page\"?>" >> ${sitemap_blog}
944 echo '<urlset' >> ${sitemap_blog}
945 echo ' xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' >> ${sitemap_blog}
946 echo ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' >> ${sitemap_blog}
947 echo ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"' >> ${sitemap_blog}
948 echo '>' >> ${sitemap_blog}
949
950
951 for file in "${blog_files[@]}"
952 do
953
954 local url="${config[site_url]}/${file}"
955 local lastmod=$(stat -c %y "${file}" 2>/dev/null | cut -d' ' -f1,2 | sed 's/ /T/' | sed 's/\..*$//')
956
957 echo " <url>" >> ${sitemap_blog}
958 echo " <loc>${url}</loc>" >> ${sitemap_blog}
959 echo " <lastmod><![CDATA[${lastmod}+01:00]]></lastmod>" >> ${sitemap_blog}
960 echo " <changefreq><![CDATA[always]]></changefreq>" >> ${sitemap_blog}
961 echo " <priority><![CDATA[1]]></priority>" >> ${sitemap_blog}
962 echo " </url>" >> ${sitemap_blog}
963 done
964
965
966 echo '</urlset>' >> "${sitemap_blog}"
967 _msg std " - ${b_file}"
968
969
970 echo '<?xml version="1.0" encoding="UTF-8"?>' > ${sitemap_page}
971 echo "<!-- Sitemap generated by ${QSGEN} ${VERSION} - https://github.com/kekePower/qsgen2 -->" >> ${sitemap_page}
972 echo "<?xml-stylesheet type=\"text/xsl\" href=\"${config[site_url]}/css/default-sitemap.xsl?sitemap=page\"?>" >> ${sitemap_page}
973 echo '<urlset' >> ${sitemap_page}
974 echo ' xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' >> ${sitemap_page}
975 echo ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' >> ${sitemap_page}
976 echo ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"' >> ${sitemap_page}
977 echo '>' >> ${sitemap_page}
978
979
980 for file in "${page_files[@]}"
981 do
982
983 local url="${config[site_url]}/${file}"
984 local lastmod=$(stat -c %y "${file}" 2>/dev/null | cut -d' ' -f1,2 | sed 's/ /T/' | sed 's/\..*$//')
985
986 echo " <url>" >> ${sitemap_page}
987 echo " <loc>${url}</loc>" >> ${sitemap_page}
988 echo " <lastmod><![CDATA[${lastmod}+01:00]]></lastmod>" >> ${sitemap_page}
989 echo " <changefreq><![CDATA[always]]></changefreq>" >> ${sitemap_page}
990 echo " <priority><![CDATA[1]]></priority>" >> ${sitemap_page}
991 echo " </url>" >> ${sitemap_page}
992 done
993
994
995 echo '</urlset>' >> "${sitemap_page}"
996 _msg std " - ${p_file}"
997
998 if (${debug}); then _msg debug "${0:t}_msg_2" " ${sitemap_file}"; fi
999
1000
1001 echo '<?xml version="1.0" encoding="UTF-8"?>' > "${sitemap_file}"
1002 echo "<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">" >> "${sitemap_file}"
1003
1004
1005 echo " <sitemap>" >> "${sitemap_file}"
1006 echo " <loc>${config[site_url]}/${b_file}</loc>" >> "${sitemap_file}"
1007 local lastmod_b=$(stat -c %y "${b_file}" 2>/dev/null | cut -d' ' -f1,2 | sed 's/ /T/' | sed 's/\..*$//')
1008 echo " <lastmod>${lastmod_b}</lastmod>" >> "${sitemap_file}"
1009 echo " </sitemap>" >> "${sitemap_file}"
1010
1011
1012 echo " <sitemap>" >> "${sitemap_file}"
1013 echo " <loc>${config[site_url]}/${p_file}</loc>" >> "${sitemap_file}"
1014 local lastmod_p=$(stat -c %y "${p_file}" 2>/dev/null | cut -d' ' -f1,2 | sed 's/ /T/' | sed 's/\..*$//')
1015 echo " <lastmod>${lastmod_p}</lastmod>" >> "${sitemap_file}"
1016 echo " </sitemap>" >> "${sitemap_file}"
1017
1018
1019 echo "</sitemapindex>" >> "${sitemap_file}"
1020 _msg std " - ${sm_file}"
1021
1022 builtin cd ${config[project_root]}
1023
1024 fi
1025
1026 }
1027
1028 function _link() {
1029
1030
1031 if [[ ${globaldebug} == "true" ]]; then
1032 local debug=true
1033 else
1034 local debug=false
1035 fi
1036
1037 local content="${1}"
1038 local modified_content=""
1039
1040
1041 echo "${content}" | while IFS= read -r line; do
1042 if [[ ${line} == *"#link"* ]]; then
1043 if (${debug}) _msg debug "${0:t}_msg_1" " ${line}"
1044
1045
1046 local url_full=$(echo "${line}" | awk -F'#link ' '{print $2}' | awk -F'¤' '{print $1 "¤" $2}')
1047 local url_dest=$(echo "${url_full}" | awk -F'¤' '{print $1}')
1048 local url_txt=$(echo "${url_full}" | awk -F'¤' '{print $2}')
1049
1050 if (${debug}) _msg debug "${0:t}_msg_2" " ${url_dest}"
1051 if (${debug}) _msg debug "${0:t}_msg_3" " ${url_txt}"
1052
1053
1054 local modified_link="<a href=\"${url_dest}\">${url_txt}"
1055 if [[ ${url_dest} =~ ^https?:// ]]; then
1056
1057 modified_link+="<img class=\"exticon\" alt=\"External site icon\" src=\"/images/ext-black-top.svg\" width=\"12\" />"
1058 fi
1059 modified_link+="</a>"
1060 line=${line//"#link ${url_full}"/${modified_link}}
1061 fi
1062 modified_content+="${line}\n"
1063 done
1064
1065
1066 echo -e "${modified_content}"
1067
1068 }
1069
1070 function _image() {
1071
1072
1073 if [[ ${globaldebug} == "true" ]]; then
1074 local debug=true
1075 else
1076 local debug=false
1077 fi
1078
1079 local content="${1}"
1080 local modified_content=""
1081
1082
1083 echo "${content}" | while IFS= read -r line; do
1084 if [[ ${line} == *"#showimg"* ]]; then
1085 if (${debug}) _msg debug "${0:t}_msg_1" " ${line}"
1086
1087
1088 local img_link=$(echo "${line}" | awk -F'#showimg ' '{print $2}')
1089 local image=$(echo "${img_link}" | awk -F'¤' '{print $1}')
1090 local img_alt=$(echo "${img_link}" | awk -F'¤' '{print $2}')
1091
1092
1093 local real_image=""
1094 if [[ ${image} =~ ^https?:// ]]; then
1095 real_image=${image}
1096 elif [[ ${image} =~ ^\/ ]]; then
1097 real_image=${image}
1098 else
1099 real_image="/images/${image}"
1100 fi
1101
1102
1103 local img_tag="<img src=\"${real_image}\" alt=\"${img_alt}\" width=\"500\" />"
1104 line=${line//"#showimg ${img_link}"/${img_tag}}
1105 fi
1106 modified_content+="${line}\n"
1107 done
1108
1109
1110 echo -e "${modified_content}"
1111
1112 }
1113
1114 function _youtube() {
1115
1116
1117 if [[ ${globaldebug} == "true" ]]; then
1118 local debug=true
1119 else
1120 local debug=false
1121 fi
1122
1123 local content="${1}"
1124 local modified_content=""
1125
1126
1127 echo "${content}" | while IFS= read -r line; do
1128 if [[ ${line} == *"#ytvideo"* ]]; then
1129 if (${debug}) _msg debug "${0:t}_msg_1" " ${line}"
1130
1131
1132 local yt_id=$(echo "${line}" | awk -F'#ytvideo ' '{print $2}')
1133
1134
1135 local yt_iframe="<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/${yt_id}\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>"
1136 line=${line//"#ytvideo ${yt_id}"/${yt_iframe}}
1137 fi
1138 modified_content+="${line}\n"
1139 done
1140
1141
1142 echo -e "${modified_content}"
1143
1144 }
1145
1146 function _cleanup() {
1147
1148
1149 if [[ ${globaldebug} == "true" ]]; then
1150 local debug=true
1151 else
1152 local debug=false
1153 fi
1154
1155 local content="${1}"
1156
1157 if (${debug}) _msg debug "${0:t}_msg_1"
1158
1159
1160
1161 local cleaned_content=$(echo "${content}" | sed \
1162 -e "s|¤||g" \
1163 -e "s|#showimg\ ||g" \
1164 -e "s|#ytvideo\ ||g" \
1165 -e "s|#link\ ||g" \
1166 )
1167
1168
1169 echo "${cleaned_content}"
1170
1171 }
1172
1173 function _p_qstags() {
1174
1175 if [[ ${globaldebug} == "true" ]]; then
1176 local debug=true
1177 else
1178 local debug=false
1179 fi
1180
1181 local content="${1}"
1182
1183 if ${debug}; then
1184 _msg debug "${0:t}_msg_1"
1185 fi
1186
1187
1188 perl -0777 -pe '
1189 BEGIN {
1190 @qstags = (
1191 "#BR", "<br/>\n",
1192 "#BD", "<b>", "#EBD", "</b>",
1193 "#I", "<i>", "#EI", "</i>\n",
1194 "#P", "<p>", "#EP", "</p>\n",
1195 "#Q", "<blockquote>", "#EQ", "</blockquote>\n",
1196 "#C", "<code>", "#EC", "</code>\n",
1197 "#H1", "<h1>", "#EH1", "</h1>\n",
1198 "#H2", "<h2>", "#EH2", "</h2>\n",
1199 "#H3", "<h3>", "#EH3", "</h3>\n",
1200 "#H4", "<h4>", "#EH4", "</h4>\n",
1201 "#H5", "<h5>", "#EH5", "</h5>\n",
1202 "#H6", "<h6>", "#EH6", "</h6>\n",
1203 "#STRONG", "<strong>", "#ESTRONG", "</strong>\n",
1204 "#EM", "<em>", "#SEM", "</em>\n",
1205 "#DV", "<div>", "#EDV", "</div>\n",
1206 "#SPN", "<span>", "#ESPN", "</span>\n",
1207 "#UL", "<ul>", "#EUL", "</ul>\n",
1208 "#OL", "<ol>", "#EOL", "</ol>\n",
1209 "#LI", "<li>", "#ELI", "</li>\n",
1210 "#UD", "<u>", "#EUD", "</u>\n",
1211 "#TBL", "<table>", "#ETBL", "</table>\n",
1212 "#TR", "<tr>", "#ETR", "</tr>\n",
1213 "#TD", "<td>", "#ETD", "</td>\n",
1214 "#TH", "<th>", "#ETH", "</th>\n",
1215 "#ART", "<article>", "#EART", "</article>\n",
1216 "#SEC", "<section>", "#ESEC", "</section>\n",
1217 "#ASIDE", "<aside>", "#EASIDE", "</aside>\n",
1218 "#NAV", "<nav>", "#ENAV", "</nav>\n",
1219 "#BTN", "<button>", "#EBTN", "</button>\n",
1220 "#SEL", "<select>", "#ESEL", "</select>\n",
1221 "#OPT", "<option>", "#EOPT", "</option>\n",
1222 "#LT", "<", "#GT", ">", "#NUM", "#"
1223 );
1224 }
1225
1226 for (my $i = 0; $i < $#qstags; $i += 2) {
1227 my $qstag = $qstags[$i];
1228 my $html = $qstags[$i + 1];
1229 s/\Q$qstag\E/$html/g;
1230 }
1231 ' <<< "$content"
1232
1233 }
1234
1235 function _qstags() {
1236
1237
1238
1239 if [[ ${globaldebug} == "true" ]]; then
1240 local debug=true
1241 else
1242 local debug=false
1243 fi
1244
1245 local content="${1}"
1246
1247 if ${debug}; then
1248 _msg debug "${0:t}_msg_1"
1249 fi
1250
1251
1252
1253
1254
1255 typeset -A qstags=(
1256 "#BR" "<br/>\n"
1257 "#BD" "<b>" "#EBD" "</b>"
1258 "#I" "<i>" "#EI" "</i>\n"
1259 "#P" "<p>" "#EP" "</p>\n"
1260 "#Q" "<blockquote>" "#EQ" "</blockquote>\n"
1261 "#C" "<code>" "#EC" "</code>\n"
1262 "#H1" "<h1>" "#EH1" "</h1>\n"
1263 "#H2" "<h2>" "#EH2" "</h2>\n"
1264 "#H3" "<h3>" "#EH3" "</h3>\n"
1265 "#H4" "<h4>" "#EH4" "</h4>\n"
1266 "#H5" "<h5>" "#EH5" "</h5>\n"
1267 "#H6" "<h6>" "#EH6" "</h6>\n"
1268 "#STRONG" "<strong>" "#ESTRONG" "</strong>\n"
1269 "#EM" "<em>" "#SEM" "</em>\n"
1270 "#DV" "<div>" "#EDV" "</div>\n"
1271 "#SPN" "<span>" "#ESPN" "</span>\n"
1272 "#UL" "<ul>" "#EUL" "</ul>\n"
1273 "#OL" "<ol>" "#EOL" "</ol>\n"
1274 "#LI" "<li class=\"libody\">" "#ELI" "</li>\n"
1275 "#UD" "<u>" "#EUD" "</u>\n"
1276 "#TBL" "<table>" "#ETBL" "</table>\n"
1277 "#TR" "<tr>" "#ETR" "</tr>\n"
1278 "#TD" "<td>" "#ETD" "</td>\n"
1279 "#TH" "<th>" "#ETH" "</th>\n"
1280 "#ART" "<article>" "#EART" "</article>\n"
1281 "#SEC" "<section>" "#ESEC" "</section>\n"
1282 "#ASIDE" "<aside>" "#EASIDE" "</aside>\n"
1283 "#NAV" "<nav>" "#ENAV" "</nav>\n"
1284 "#BTN" "<button>" "#EBTN" "</button>\n"
1285 "#SEL" "<select>" "#ESEL" "</select>\n"
1286 "#OPT" "<option>" "#EOPT" "</option>\n"
1287 "#LT" "<" "#GT" ">" "#NUM" "#"
1288 )
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298 for qstag html (${(kv)qstags}); do
1299
1300 content=${content//${qstag}/${html}}
1301 done
1302
1303 echo "${content}"
1304
1305 }
1306
1307
1308 case ${1} in
1309 force)
1310 _msg sub "_qsgen2_msg_2"
1311 : >| "$blog_cache_file"
1312 : >| "$pages_cache_file"
1313 ;;
1314 sitemap)
1315 _msg sub "Updating sitemaps"
1316 export sitemap_force=true
1317 _sitemap
1318 exit
1319 ;;
1320 *)
1321
1322 ;;
1323 esac
1324
1325 _blogs
1326 _pages
1327 _sitemap