971 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			971 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/zsh
 | 
						|
 | 
						|
# 
 | 
						|
# Quick Site Generator 2 is a static website generator inspired by Nikola.
 | 
						|
# It is written for the Z shell (zsh) because that's what I use and also because I like it better than Bash.
 | 
						|
#
 | 
						|
# This script is an almost complete rewrite of my old script because it became overly complicated and
 | 
						|
# had way too many bugs, even though it worked on simple sites.
 | 
						|
# 
 | 
						|
# https://github.com/kekePower/qsgen2/
 | 
						|
# 
 | 
						|
 | 
						|
VERSION="0.2.4" # Sat-2024-02-03
 | 
						|
QSGEN="Quick Site Generator 2"
 | 
						|
 | 
						|
# Set to true or false
 | 
						|
# This will show debug information from almost every function in this script
 | 
						|
debug=false
 | 
						|
 | 
						|
function include () {
 | 
						|
    
 | 
						|
    # This function is used to include other functions that will normally be in
 | 
						|
    # ${HOME}/bin/include/
 | 
						|
 | 
						|
        # Edit this path to reflect your installation
 | 
						|
        local inc_file=${HOME}/bin/include/${1}.inc
 | 
						|
        if [[ ! -f ${inc_file} ]]; then
 | 
						|
                local inc_opt=$( echo ${1} | cut -d\/ -f2 )
 | 
						|
                echo "Supplied option \"${inc_opt}\" is not a valid include."
 | 
						|
        else
 | 
						|
                builtin source ${inc_file} ${2}
 | 
						|
        fi
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
# Including some colors to the script
 | 
						|
include common/colors
 | 
						|
 | 
						|
echo "${magenta}${blue_bg} ${QSGEN} ${end}${white}${blue_bg}${VERSION} ${end}"
 | 
						|
 | 
						|
function _version() {
 | 
						|
    echo "${yellow}- Created by kekePower - 2018-$(date +%Y)${end}"
 | 
						|
    echo "${yellow}- https://github.com/kekePower/qsgen2/${end}"
 | 
						|
    echo "${yellow}- See '${1} help' for more information.${end}"
 | 
						|
    exit
 | 
						|
}
 | 
						|
 | 
						|
function _help() {
 | 
						|
    echo "This is where I'll write the Help documentation."
 | 
						|
	exit
 | 
						|
}
 | 
						|
 | 
						|
if [[ "$1" == "version" || "$1" == "-v" || "$1" == "--version" ]]; then
 | 
						|
  _version ${0:t}
 | 
						|
elif [[ "$1" == "help" || "$1" == "-h" || "$1" == "--help" ]]; then
 | 
						|
  _help ${0:t}
 | 
						|
fi
 | 
						|
 | 
						|
# Loading Zsh modules
 | 
						|
zmodload zsh/files
 | 
						|
 | 
						|
# Check for, an source, the config file for this specific website
 | 
						|
if [[ -f $(pwd)/config ]]; then
 | 
						|
    if (${debug}); then echo "${red}Config file found and sourced${end}\n- ${yellow} - $(pwd)/config${end}"; fi
 | 
						|
	# CONFIG=$(pwd)/config
 | 
						|
	builtin source $(pwd)/config
 | 
						|
else
 | 
						|
	echo "${red}Cannot find configuration file.${end}"
 | 
						|
	echo "${yellow} - Please create the file 'config' in your project directory.${end}"
 | 
						|
	exit
 | 
						|
fi
 | 
						|
 | 
						|
if (${debug}); then
 | 
						|
    qsconfig=$( cat $(pwd)/config | grep -v \# | awk '{print substr($0, index($0, " ") + 1)}' )
 | 
						|
	echo "${red}Contents of Config file:${end}"
 | 
						|
    for qslines in ${qsconfig}
 | 
						|
    do
 | 
						|
        echo "${yellow}${qslines}${end}"
 | 
						|
    done
 | 
						|
fi
 | 
						|
 | 
						|
function _msg() {
 | 
						|
    # Use this function to write out messages based on their type
 | 
						|
    # Types are: std=green - info=yellow - debug=red other=bold_yellow
 | 
						|
    # Usage: _msg <type> "<message>"
 | 
						|
    
 | 
						|
    case ${1} in
 | 
						|
        std)
 | 
						|
            echo "${green}${2}${end}"
 | 
						|
        ;;
 | 
						|
        info)
 | 
						|
            echo "${yellow}${2}${end}"
 | 
						|
        ;;
 | 
						|
        debug)
 | 
						|
            echo "${red}${2}${end}"
 | 
						|
        ;;
 | 
						|
        other)
 | 
						|
            echo "${bold_yellow}${2}${end}"
 | 
						|
        ;;
 | 
						|
        *)
 | 
						|
            echo "${2}"
 | 
						|
        ;;
 | 
						|
    esac
 | 
						|
}
 | 
						|
 | 
						|
# Let's check if qsgen2 can generate this site by checking if 'generator' is available
 | 
						|
if [[ ! ${generator} ]] || [[ -d $(pwd)/.git ]]; then
 | 
						|
    _msg other "${0:t} cannot parse this site. Exiting."
 | 
						|
    exit
 | 
						|
fi
 | 
						|
 | 
						|
# We define the variable 'engine' based on what's in the 'config' file.
 | 
						|
if [[ ${generator} == "native" ]]; then
 | 
						|
        # Usage: ${engine} ${1} - Where 1 is the file you want to convert
 | 
						|
        engine=_html
 | 
						|
        export file_ext=tpl
 | 
						|
elif [[ ${generator} == "markdown" ]]; then
 | 
						|
    if [[ ! -f /usr/local/bin/pandoc ]]; then
 | 
						|
        _msg other "Please install Pandoc."
 | 
						|
        _msg other "https://github.com/jgm/pandoc/releases"
 | 
						|
        exit
 | 
						|
    else
 | 
						|
        # Usage: ${engine} ${1} - Where 1 is the file you want parsed
 | 
						|
        engine=/usr/local/bin/pandoc
 | 
						|
        export file_ext=md
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
if (${debug}) _msg debug "Using the ${generator} engine for files: ${file_ext}"
 | 
						|
 | 
						|
# Define cache files for blogs and pages
 | 
						|
blog_cache_file="${project_dir}/.blog_cache"
 | 
						|
pages_cache_file="${project_dir}/.pages_cache"
 | 
						|
 | 
						|
builtin cd ${project_dir}
 | 
						|
 | 
						|
# Let's put these here for now.
 | 
						|
export today=$( date "+%Y-%m-%d - %T" )
 | 
						|
export blogdate=$( date +%a-%Y-%b-%d )
 | 
						|
 | 
						|
# Let's create arrays of all the files we'll be working on
 | 
						|
 | 
						|
function _list_pages() {
 | 
						|
    local debug=false
 | 
						|
    
 | 
						|
    export no_pages_found=false
 | 
						|
 | 
						|
    # Temporarily set null_glob for this function
 | 
						|
    setopt local_options null_glob
 | 
						|
 | 
						|
    # Check if there are any .blog files in the blog directory
 | 
						|
    local pages_files=$(ls *${file_ext})
 | 
						|
    if (( ${#pages_files} == 0 )); then
 | 
						|
        if (${debug}); then _msg debug "_list_pages: No Pages found."; fi
 | 
						|
        export no_pages_found=true
 | 
						|
        return
 | 
						|
    fi
 | 
						|
 | 
						|
    for file in $( echo ${pages_files} ); do
 | 
						|
        if (${debug}) _msg debug "_list_pages: Adding file to array: ${file}"
 | 
						|
        pages_file_array+=("$file")
 | 
						|
    done
 | 
						|
}
 | 
						|
 | 
						|
function _list_blogs() {
 | 
						|
    local debug=false
 | 
						|
    
 | 
						|
    export no_blogs_found=false
 | 
						|
 | 
						|
    # Temporarily set null_glob for this function
 | 
						|
    setopt local_options null_glob
 | 
						|
 | 
						|
    # Check if there are any .blog files in the blog directory
 | 
						|
    local blog_files=(blog/*.blog)
 | 
						|
    if (( ${#blog_files} == 0 )); then
 | 
						|
        if (${debug}); then _msg debug "_list_blogs: No blog files found."; fi
 | 
						|
        export no_blogs_found=true
 | 
						|
        return
 | 
						|
    fi
 | 
						|
 | 
						|
    for file in $( ls -har blog/*.blog ); do
 | 
						|
        blogs_file_array+=("$file")
 | 
						|
    done
 | 
						|
}
 | 
						|
 | 
						|
# BLOG CACHE
 | 
						|
function _blog_cache() {
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    _list_blogs
 | 
						|
 | 
						|
    # Create an associative array for the blog cache
 | 
						|
    typeset -A blog_cache
 | 
						|
 | 
						|
    # Load the existing blog cache
 | 
						|
    if [[ -f $blog_cache_file ]]; then
 | 
						|
        while IFS=':' read -r name hash; do
 | 
						|
            blog_cache[$name]=$hash
 | 
						|
    		if (${debug}) _msg debug "_blog_cache: HASH VALUE: ${blog_cache[${name}]}"
 | 
						|
        done < "$blog_cache_file"
 | 
						|
    fi
 | 
						|
 | 
						|
    # Initialize the array for storing blog files to process
 | 
						|
    make_blog_array=()
 | 
						|
 | 
						|
    # Process blog files
 | 
						|
    for blog_file in ${blogs_file_array[@]}; do
 | 
						|
        # Compute the current blog file hash
 | 
						|
        current_hash=$(md5sum "$blog_file" | awk '{print $1}')
 | 
						|
	
 | 
						|
    	if (${debug}) _msg debug "1. _blog_cache: ${blog_file}"
 | 
						|
    	if (${debug}) _msg debug "2. _blog_cache: current_cache: ${current_hash}"
 | 
						|
 | 
						|
        # Check if the blog file is new or has changed
 | 
						|
        if [[ ${blog_cache[$blog_file]} != "$current_hash" ]]; then
 | 
						|
    		if (${debug}) _msg debug "3. _blog_cache: new_cache_file: ${blog_file}$"
 | 
						|
    		if (${debug}) _msg debug "4. _blog_cache: new_current_cache: ${current_hash}"
 | 
						|
            # Blog file is new or has changed; add it to the processing array
 | 
						|
            make_blog_array+=("$blog_file")
 | 
						|
 | 
						|
            # Update the blog cache with the new hash
 | 
						|
            blog_cache[$blog_file]=$current_hash
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    # Rebuild the blog cache file from scratch
 | 
						|
    : >| "$blog_cache_file"  # Truncate the file before writing
 | 
						|
    for name in "${(@k)blog_cache}"; do
 | 
						|
        echo "$name:${blog_cache[$name]}" >> "$blog_cache_file"
 | 
						|
    done
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
# PAGES CACHE
 | 
						|
# Returns the array pages_array()
 | 
						|
function _pages_cache() {
 | 
						|
    local debug=false
 | 
						|
    # Create an associative array for the pages cache
 | 
						|
    typeset -A pages_cache
 | 
						|
    
 | 
						|
    _list_pages
 | 
						|
    
 | 
						|
    # Load the existing pages cache
 | 
						|
    if [[ -f $pages_cache_file ]]; then
 | 
						|
        while IFS=':' read -r name hash; do
 | 
						|
            pages_cache[$name]=$hash
 | 
						|
    		if (${debug}) _msg debug "PAGES HASH VALUE: ${pages_cache[${name}]}"
 | 
						|
        done < "$pages_cache_file"
 | 
						|
    fi
 | 
						|
    
 | 
						|
    # Initialize the array for storing pages files to process
 | 
						|
    pages_array=()
 | 
						|
    
 | 
						|
    # Process pages files
 | 
						|
    for file in ${pages_file_array[@]}; do
 | 
						|
        # Compute the current blog file hash
 | 
						|
        current_hash=$(md5sum "$file" | awk '{print $1}')
 | 
						|
        
 | 
						|
    	if (${debug}) _msg debug "1. pages_cache: ${pages_cache[$file]}"
 | 
						|
    	if (${debug}) _msg debug "1. _pages_cache: current_cache: ${current_hash}"
 | 
						|
        
 | 
						|
        # Check if the pages file is new or has changed
 | 
						|
        if [[ ${pages_cache[$file]} != "$current_hash" ]]; then
 | 
						|
    		if (${debug}) _msg debug "2. _pages_cache: pages_file: ${pages_cache[$file]}"
 | 
						|
    		if (${debug}) _msg debug "2. _pages_cache: current_cache: ${current_hash}"
 | 
						|
            # Pages file is new or has changed; add it to the processing array
 | 
						|
            pages_array+=("$file")
 | 
						|
            
 | 
						|
            # Update the pages cache with the new hash
 | 
						|
            pages_cache[$file]=$current_hash
 | 
						|
        fi
 | 
						|
    done
 | 
						|
    
 | 
						|
    # Rebuild the pages cache file from scratch
 | 
						|
    : >| "$pages_cache_file"  # Truncate the file before writing
 | 
						|
    for name in "${(@k)pages_cache}"; do
 | 
						|
        echo "$name:${pages_cache[$name]}" >> "$pages_cache_file"
 | 
						|
    done
 | 
						|
}
 | 
						|
 | 
						|
function _last_updated() {
 | 
						|
    # This function updates #updated and #version tags in the provided string for buffers
 | 
						|
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    if (${debug}); then _msg debug "_last_updated: Setting date and version in footer"; fi
 | 
						|
    if (${debug}); then _msg debug "_last_updated: ${upd_msg}"; fi
 | 
						|
      
 | 
						|
    local upd_msg="Last updated ${today} by <a href=\"https://blog.kekepower.com/qsgen2.html\">${QSGEN} ${VERSION}</a>"
 | 
						|
    
 | 
						|
    local content="${1}"
 | 
						|
 | 
						|
    # Perform the replacements
 | 
						|
    local updated_content=$(echo "${content}" | sed \
 | 
						|
        -e "s|#updated|${upd_msg}|")
 | 
						|
 | 
						|
    # Return the updated content
 | 
						|
    echo "${updated_content}"
 | 
						|
}
 | 
						|
 | 
						|
function _f_last_updated() {
 | 
						|
    # This function updates #updated and #version tags in the provided string in files
 | 
						|
    
 | 
						|
    local debug=false
 | 
						|
    
 | 
						|
    if (${debug}); then _msg debug "_f_last_updated: Setting date and version in footer of file ${1}"; fi
 | 
						|
    if (${debug}); then _msg debug "_f_last_updated: ${upd_msg}"; fi
 | 
						|
    
 | 
						|
    local upd_msg="Last updated ${today} by <a href=\"https://blog.kekepower.com/qsgen2.html\">${QSGEN} ${VERSION}</a>"
 | 
						|
    
 | 
						|
    local content="${1}"
 | 
						|
    
 | 
						|
    # Perform the replacements
 | 
						|
    tee < ${content} | sed \
 | 
						|
        -e "s|#updated|${upd_msg}|" \
 | 
						|
        > ${content}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function _file_to_lower() {
 | 
						|
    
 | 
						|
    local filename="${1}"
 | 
						|
 | 
						|
    # Replace spaces with dashes
 | 
						|
    filename="${filename// /-}"
 | 
						|
 | 
						|
    # Convert to lowercase and remove invalid characters
 | 
						|
    filename=$(echo "${filename}" | sed -e 's/^[^a-zA-Z0-9_.]+//g' -e 's/[^a-zA-Z0-9_-]+/-/g')
 | 
						|
 | 
						|
    echo ${filename}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function _pages() {
 | 
						|
    # This function generates all the new and updated Pages
 | 
						|
    
 | 
						|
    _msg other "Generating Pages"
 | 
						|
    
 | 
						|
    local debug=false
 | 
						|
    
 | 
						|
    # Load the cache for Pages
 | 
						|
    if (${debug}) _msg debug "_pages: Running function _pages_cache"
 | 
						|
    _pages_cache
 | 
						|
    
 | 
						|
    if (( ${#pages_array[@]} > 0 )); then
 | 
						|
    
 | 
						|
      # If pages_array is not empty, we do work
 | 
						|
      if (${debug}) _msg debug "_pages: pages_array is not empty"
 | 
						|
      for pages_in_array in ${pages_array[@]}
 | 
						|
      do
 | 
						|
          
 | 
						|
        if (${debug}) _msg debug "_pages: Setting Pages template"
 | 
						|
        local pages=${project_dir}/themes/${theme}/pages.tpl
 | 
						|
        
 | 
						|
        # Let's check if we can access the pages.tpl file.
 | 
						|
        # It not, exit script.
 | 
						|
        if [[ ! -f ${pages} ]]; then
 | 
						|
            _msg info "Unable to find the Pages template: ${pages}"
 | 
						|
            exit
 | 
						|
        else
 | 
						|
            # Read template once
 | 
						|
            if (${debug}) _msg debug "_pages: Reading Pages template into pages_tpl"
 | 
						|
            pages_tpl="$(<${pages})"
 | 
						|
        fi
 | 
						|
        
 | 
						|
        _msg std "Generating Page: ${pages_in_array}"
 | 
						|
        # Read the file once
 | 
						|
        if (${debug}) _msg debug "_pages: Loading page_content once - ${pages_in_array}"
 | 
						|
        local page_content="$(<${pages_in_array})"
 | 
						|
              
 | 
						|
        # Grab the title from the Page
 | 
						|
        if (${debug}) _msg debug "_pages: Grepping for page_title"
 | 
						|
        local page_title=$( echo ${page_content} | head -2 | grep \#title | cut -d= -f2 )
 | 
						|
        if (${debug}) _msg debug "_pages: ${page_title}"
 | 
						|
        
 | 
						|
        # Remove the #title line from the buffer. No longer needed.
 | 
						|
        if (${debug}) _msg debug "_pages: Removing #title line from page_content"
 | 
						|
        local page_content=$( echo ${page_content} | grep -v \#title )
 | 
						|
        
 | 
						|
        # HTML'ify the page content
 | 
						|
        if (${debug}) _msg debug "_pages: Running engine on ${pages_in_array}"
 | 
						|
        if [[ ${file_ext} == "tpl" ]]; then
 | 
						|
            local page_content=$( ${engine} "$page_content" )
 | 
						|
            # Look for links, images and videos and convert them if present.
 | 
						|
          if (${debug}) _msg debug "_pages: Checking for #link, #showimg and #ytvideo in page_content"
 | 
						|
          if [[ $( echo ${page_content} | grep \#link ) ]]; then
 | 
						|
            if (${debug}) _msg debug "_pages: #link is present, run _link: page_content"
 | 
						|
            local page_content=$( _link "${page_content}" )
 | 
						|
            fi
 | 
						|
          if [[ $( echo ${page_content} | grep \#showimg ) ]]; then
 | 
						|
            if (${debug}) _msg debug "_pages: #showimg is present, run _image: page_content"
 | 
						|
            local page_content=$( _image "${page_content}" )
 | 
						|
          fi
 | 
						|
          if [[ $( echo ${page_content} | grep \#ytvideo ) ]]; then
 | 
						|
            if (${debug}) _msg debug "_pages: #ytvideo is present, run _youtube: page_content"
 | 
						|
            local page_content=$( _youtube "${page_content}" )
 | 
						|
          fi
 | 
						|
        elif [[ ${file_ext} == "md" ]]; then
 | 
						|
            local page_content=$(echo "$page_content" | ${engine})
 | 
						|
        fi
 | 
						|
        
 | 
						|
        if (${debug}) _msg debug "_pages: Replacing BODY with page_content in pages_tpl"
 | 
						|
        # Use Perl for multi-line and special character handling
 | 
						|
        local pages_tpl=$( awk -v new_body="$page_content" '{sub(/BODY/, new_body)} 1' <(echo "${pages_tpl}") )
 | 
						|
        
 | 
						|
        # Replace every #pagetitle in pages_tpl
 | 
						|
        if (${debug}) _msg debug "_pages: Replacing #pagetitle in pages_tpl"
 | 
						|
        local pages_tpl=$( echo ${pages_tpl} | perl -pe "s|#pagetitle|${page_title}|gs" )
 | 
						|
        
 | 
						|
        # Replace every #tagline in pages_tpl
 | 
						|
        if (${debug}) _msg debug "_pages: Replacing tagline"
 | 
						|
        local pages_tpl=$( echo ${pages_tpl} | perl -pe "s|#tagline|${site_tagline}|gs" )
 | 
						|
        
 | 
						|
        # Replace every #sitename in pages_tpl
 | 
						|
        if (${debug}) _msg debug "_pages: Replacing sitename"
 | 
						|
        local pages_tpl=$( echo ${pages_tpl} | perl -pe "s|#sitename|${site_name}|gs" )
 | 
						|
        
 | 
						|
        # Replace #updated with today's date and #version with Name and Version to footer
 | 
						|
        if (${debug}) _msg debug "_pages: _last_updated in pages_tpl"
 | 
						|
        local pages_tpl=$( _last_updated ${pages_tpl} )
 | 
						|
        
 | 
						|
        # Always use lowercase for file names
 | 
						|
        if (${debug}) _msg debug "_pages: Lowercase filnames, always"
 | 
						|
        local pages_title_lower=$( _file_to_lower "${pages_in_array}" )
 | 
						|
        
 | 
						|
        # Clean up unused tags, if any
 | 
						|
        if (${debug}) _msg debug "_pages: Running _cleanup"
 | 
						|
        local pages_tpl=$( _cleanup "${pages_tpl}" )
 | 
						|
        
 | 
						|
        # Write pages_tpl to disk
 | 
						|
        _msg std "Writing ${www_root}/${pages_title_lower%.*}.html to disk."
 | 
						|
        echo "${pages_tpl}" > ${www_root}/${pages_title_lower%.*}.html
 | 
						|
        
 | 
						|
      done
 | 
						|
      
 | 
						|
      export new_updated_pages=true
 | 
						|
      
 | 
						|
    else
 | 
						|
        
 | 
						|
        _msg info "No new or updated Pages"
 | 
						|
        export new_updated_pages=false
 | 
						|
      
 | 
						|
    fi
 | 
						|
    
 | 
						|
}
 | 
						|
 | 
						|
function _blogs() {
 | 
						|
    # This function either generates blog files or exports metadata based on the argument
 | 
						|
    
 | 
						|
    _msg other "Generating Blogs"
 | 
						|
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    # Running function _list_blogs
 | 
						|
    if (${debug}) _msg debug "_blogs: Running function _list_blogs"
 | 
						|
    _list_blogs
 | 
						|
    # Running function _blog_cache
 | 
						|
    if (${debug}) _msg debug "_blogs: Running function _blog_cache"
 | 
						|
    _blog_cache
 | 
						|
 | 
						|
    if (( ${#make_blog_array[@]} > 0 )); then
 | 
						|
        
 | 
						|
        # Declare the array to hold metadata strings for each blog
 | 
						|
        BLOG_META_STR_ARRAY=()
 | 
						|
 | 
						|
            # Regular blog creation process
 | 
						|
            #if [[ ! ${mode} ]]; then
 | 
						|
                
 | 
						|
                if [[ -f ${project_dir}/themes/${theme}/blogs.tpl ]]; then
 | 
						|
                    local blog_tpl=$(<"${project_dir}/themes/${theme}/blogs.tpl")
 | 
						|
                else
 | 
						|
                    _msg info "Unable to find theme template for Blogs."
 | 
						|
                    exit
 | 
						|
                fi
 | 
						|
                
 | 
						|
                for blog in "${make_blog_array[@]}"; do
 | 
						|
                    
 | 
						|
                    if (${debug}) _msg debug "_blogs: Processing pre-data for ${blog}"
 | 
						|
                
 | 
						|
                    local content="$(<"${blog}")"
 | 
						|
                    local sdate btitle ingress body blog_index blog_dir blog_url
 | 
						|
 | 
						|
                    # Extract blog information
 | 
						|
                    sed -i "s/GETDATE/${blogdate}/" ${blog}
 | 
						|
                    # Array sdate = Name day=1, Year=2, Month=3, Number day=4
 | 
						|
                    sdate=( $( echo ${content} | grep DATE | sed "s|DATE\ ||" | sed "s|\-|\ |g" ) )
 | 
						|
                    btitle=$( echo ${content} | grep BLOG_TITLE | cut -d' ' -f2- )
 | 
						|
                    ingress=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#INGRESS_START\K(.*?)#INGRESS_STOP" | sed "s|\ \#INGRESS_STOP||" | sed "s|^\ ||" )
 | 
						|
                    body=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#BODY_START\K(.*?)#BODY_STOP" | sed "s|\ \#BODY_STOP||" | sed "s|^\ ||" )
 | 
						|
 | 
						|
                    blog_index=$(echo "${btitle:l}" | sed 's/ /_/g; s/,//g; s/\.//g; s/://g; s/[()]//g')
 | 
						|
 | 
						|
                    blog_dir="/blog/${sdate[2]}/${sdate[3]:l}/${sdate[4]}"
 | 
						|
                    blog_url="${blog_dir}/${blog_index}.html"
 | 
						|
                    
 | 
						|
                    if (${debug}) _msg debug "_blogs: Adding data for ${blog} to array to export"
 | 
						|
 | 
						|
                    # Concatenate all metadata into a single string for the current blog
 | 
						|
                    local metadata_str="SDATE: ${sdate[@]}||BTITLE: ${btitle}||INGRESS: ${ingress}||URL: ${blog_url}"
 | 
						|
                    # Append this metadata string to the array
 | 
						|
                    BLOG_META_STR_ARRAY+=("${metadata_str}")
 | 
						|
                    
 | 
						|
                   if (${debug}) _msg debug "_blogs: Processing ${blog}"
 | 
						|
                       
 | 
						|
                   _msg std "Generating blog ${blog_index}.html"
 | 
						|
 | 
						|
                   # Prepare the blog template
 | 
						|
                   if (${debug}) _msg debug "_blogs: Processing substitutes in ${blog}"
 | 
						|
                   local blog_content=$(echo "${blog_tpl}" | perl -pe "s|BLOGTITLE|${btitle}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|CALADAY|${sdate[1]}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|CALNDAY|${sdate[4]}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|CALMONTH|${sdate[3]}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|CALYEAR|${sdate[2]}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|BLOGURL|${blog_url}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|\QINGRESS\E|${ingress}|g")
 | 
						|
                   blog_content=$(echo "${blog_content}" | perl -pe "s|\QBODY\E|${body}|g")
 | 
						|
 | 
						|
                   if (${debug}) _msg debug "_blogs: Running function $engine for ${blog}"
 | 
						|
                  if [[ ${file_ext} == "tpl" ]]; then
 | 
						|
                   blog_content=$( ${engine} "${blog_content}" )
 | 
						|
                   # Look for links, images and videos and convert them if present.
 | 
						|
                   if (${debug}) _msg debug "_blogs: Checking for #link, #showimg and #ytvideo in blog_content"
 | 
						|
                   if [[ $( echo ${blog_content} | grep \#link ) ]]; then
 | 
						|
                       if (${debug}) _msg debug "_blogs: #link is present, run _link: blog_content"
 | 
						|
                       blog_content=$(_link "${blog_content}")
 | 
						|
                   fi
 | 
						|
                   if [[ $( echo ${blog_content} | grep \#showimg ) ]]; then
 | 
						|
                       if (${debug}) _msg debug "_blogs: #showimg is present, run _link: blog_content"
 | 
						|
                       blog_content=$(_image "${blog_content}")
 | 
						|
                   fi
 | 
						|
                   if [[ $( echo ${blog_content} | grep \#ytvideo ) ]]; then
 | 
						|
                       if (${debug}) _msg debug "_blogs: #ytvideo is present, run _link: blog_content"
 | 
						|
                       blog_content=$(_youtube "${blog_content}")
 | 
						|
                   fi
 | 
						|
                  elif [[ ${file_ext} == "md" ]]; then
 | 
						|
                    local blog_content=$(echo "$blog_content" | ${engine})
 | 
						|
                  fi
 | 
						|
                  
 | 
						|
                  # Replace every #tagline in blog_content
 | 
						|
                  if (${debug}) _msg debug "_blogs: Replacing tagline"
 | 
						|
                  local blog_content=$( echo ${blog_content} | perl -pe "s|#tagline|${site_tagline}|gs" )
 | 
						|
                  
 | 
						|
                  # Replace every #sitename in blog_content
 | 
						|
                  if (${debug}) _msg debug "_blogs: Replacing sitename"
 | 
						|
                  local blog_content=$( echo ${blog_content} | perl -pe "s|#sitename|${site_name}|gs" )
 | 
						|
                  
 | 
						|
                   blog_content=$(_last_updated "${blog_content}")
 | 
						|
                   blog_content=$(_cleanup "${blog_content}")
 | 
						|
                   
 | 
						|
                   # Create directory if it doesn't exist
 | 
						|
                   if (${debug}) _msg debug "_blogs: Creating directoty ${www_root}/${blog_dir}"
 | 
						|
                   [[ ! -d "${www_root}/${blog_dir}" ]] && mkdir -p "${www_root}/${blog_dir}"
 | 
						|
 | 
						|
                   # Write to file
 | 
						|
                   if (${debug}) _msg debug "_blogs: Writing blog to disk: ${www_root}${blog_url}"
 | 
						|
                   echo "${blog_content}" > "${www_root}${blog_url}"
 | 
						|
                   
 | 
						|
                   unset sdate btitle ingress body blog_index blog_dir blog_url
 | 
						|
                
 | 
						|
                done
 | 
						|
            # Now BLOG_META_STR_ARRAY contains the metadata string for each blog post
 | 
						|
            export BLOG_META_STR_ARRAY
 | 
						|
            export new_updated_blogs=true
 | 
						|
 | 
						|
    else
 | 
						|
        _msg info "No new or updated Blogs detected."
 | 
						|
        export new_updated_blogs=false
 | 
						|
    fi
 | 
						|
_blog_idx_for_index
 | 
						|
_blog_index
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function _blog_idx_for_index() {
 | 
						|
    # This function generates the file blog/index.tmp.html
 | 
						|
    
 | 
						|
    local debug=false
 | 
						|
    
 | 
						|
    if (${debug}) _msg debug "_blog_idx_for_index: Initiating function"
 | 
						|
    
 | 
						|
    local blog_list_tpl=$(<${project_dir}/themes/${theme}/blog_list.tpl)
 | 
						|
    
 | 
						|
    # Truncate file before writing new one
 | 
						|
    : >| "${project_dir}/blog/index.tmp.html"
 | 
						|
    
 | 
						|
    if (${debug}) _msg debug "_blog_idx_for_index: BLOG_META_STR_ARRAY: ${BLOG_META_STR_ARRAY[@]}"
 | 
						|
    
 | 
						|
    for meta_str in ${BLOG_META_STR_ARRAY[@]}
 | 
						|
    do
 | 
						|
        if (${debug}) _msg debug "_blog_idx_for_index: meta_str from BLOG_META_STR_ARRAY from _blogs"
 | 
						|
        if (${debug}) _msg debug "_blog_idx_for_index: ${meta_str}"
 | 
						|
        local debug=false
 | 
						|
        # Split meta_str into individual metadata components
 | 
						|
        local -a meta_array=("${(@s/||/)meta_str}")
 | 
						|
 | 
						|
        # Initialize variables to store each component
 | 
						|
        local sdate btitle ingress url
 | 
						|
 | 
						|
        # Iterate over each component and extract information
 | 
						|
        if (${debug}) _msg debug "_blog_idx_for_index: Iterate over each component and extract information"
 | 
						|
        for component in "${meta_array[@]}"; do
 | 
						|
            local debug=false
 | 
						|
            case "${component}" in
 | 
						|
                SDATE:*) sdate=${component#SDATE: } ;;
 | 
						|
                BTITLE:*) btitle=${component#BTITLE: } ;;
 | 
						|
                INGRESS:*) ingress=${component#INGRESS: } ;;
 | 
						|
                URL:*) url=${component#URL: } ;;
 | 
						|
            esac
 | 
						|
 | 
						|
            local adate=( $( echo ${sdate} ) )
 | 
						|
            local caladay="${adate[1]}"
 | 
						|
            local calnday="${adate[4]}"
 | 
						|
            local calmonth="${adate[3]}"
 | 
						|
            local calyear="${adate[2]}"
 | 
						|
            
 | 
						|
            local bdate="${adate[1]} - ${adate[4]}/${adate[3]}/${adate[2]}"
 | 
						|
            blog_list_content=$(echo "${blog_list_tpl}" | perl -pe "s|BLOGURL|${url}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|BLOGTITLE|${btitle}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|INGRESS|${ingress}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|BLOGDATE|${bdate}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|CALADAY|${caladay}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|CALNDAY|${calnday}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|CALMONTH|${calmonth}|g")
 | 
						|
            blog_list_content=$(echo "${blog_list_content}" | perl -pe "s|CALYEAR|${calyear}|g")
 | 
						|
        
 | 
						|
        done
 | 
						|
          unset sdate btitle ingress url
 | 
						|
    
 | 
						|
            if (${debug}) _msg debug "_blog_idx_for_index: Writing _blog_idx_for_index to file: ${project_dir}/blog/index.tmp.html"
 | 
						|
            if (${debug}) _msg debug "_blog_idx_for_index: blog_list_content = ${blog_list_content}"
 | 
						|
            echo ${blog_list_content} >> ${project_dir}/blog/index.tmp.html
 | 
						|
 | 
						|
    done
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function _blog_index() {
 | 
						|
  
 | 
						|
  local debug=false
 | 
						|
 | 
						|
    # This function generates the /blog/index.html file that gets its data from _blog_list_for_index()
 | 
						|
    # ${new_updated_blogs} comes from the function _blogs if anything new or updated is detected
 | 
						|
    if [[ ${blog_in_index} == "false" ]] && [[ ${new_updated_blogs} = "true" ]]; then
 | 
						|
 | 
						|
        if (${debug}) _msg debug "Running function _blog_index"
 | 
						|
        if (${debug}) _msg debug "_blog_index: blog_in_index = ${blog_in_index}"
 | 
						|
 | 
						|
        _msg std "Generating the Blog index file"
 | 
						|
 | 
						|
        local debug=false
 | 
						|
        local blog_index=$(<${project_dir}/themes/${theme}/blog_index.tpl)
 | 
						|
        local blog_index_list=$(<${project_dir}/blog/index.tmp.html)
 | 
						|
 | 
						|
        local blog_index_content=$(echo "${blog_index}" | perl -pe "s|BODY|${blog_index_list}|g")
 | 
						|
        
 | 
						|
        # Replace every #pagetitle in pages_tpl
 | 
						|
        if (${debug}) _msg debug "_blog_index: Replacing #pagetitle in blog_index_content"
 | 
						|
        blog_index_content=$( echo ${blog_index_content} | perl -pe "s|#pagetitle|${page_title}|gs" )
 | 
						|
        
 | 
						|
        # Replace every #tagline in pages_tpl
 | 
						|
        if (${debug}) _msg debug "_blog_index: Replacing tagline in blog_index_content"
 | 
						|
        blog_index_content=$( echo ${pages_tpl} | perl -pe "s|#tagline|${site_tagline}|gs" )
 | 
						|
        
 | 
						|
        echo "${blog_index_content}" > ${www_root}/blog/index.html
 | 
						|
        _f_last_updated ${www_root}/blog/index.html
 | 
						|
    fi
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function _add_blog_list_to_index() {
 | 
						|
  
 | 
						|
  local debug=true
 | 
						|
  
 | 
						|
  # Let's find the file 'index.tpl' and add the blog if blog_in_index is true
 | 
						|
  if [[ ${new_updated_blogs} == "true" ]] && [[ ${blog_in_index} == "true" ]]; then
 | 
						|
    if (${debug}) _msg debug "_add_blog_list_to_index: Inserting blog list to index.html"
 | 
						|
    local blog_index_list=$(<${project_dir}/blog/index.tmp.html)
 | 
						|
    local site_index_file=$(<${www_root}/index.html)
 | 
						|
    echo "${site_index_file}" | awk -v new_body="${blog_index_list}" '{sub(/BLOGINDEX/, new_body)} 1' > "${www_root}/index.html"
 | 
						|
  fi
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function _sitemap() {
 | 
						|
    
 | 
						|
# Check if sitemap is set to true and if there are updated Blogs or Pages before updating the sitemap.xml file.
 | 
						|
if [[ ${sitemap} == "true" ]] && ( [[ ${new_updated_blogs} == "true" ]] || [[ ${new_updated_pages} == "true" ]] ); then
 | 
						|
    
 | 
						|
    _msg info "Updating sitemap.xml"
 | 
						|
 | 
						|
    local sitemap_file="${www_root}/sitemap.xml"
 | 
						|
 | 
						|
    # Find all HTML files and store them in an array
 | 
						|
    local -a html_files=("${(@f)$(find "${www_root}" -type f -name "*.html")}")
 | 
						|
 | 
						|
    # Start of the XML file
 | 
						|
    echo '<?xml version="1.0" encoding="UTF-8"?>' > ${sitemap_file}
 | 
						|
    echo "<!-- Sitemap generated by ${QSGEN} ${VERSION} - https://github.com/kekePower/qsgen2 -->" >> ${sitemap_file}
 | 
						|
    echo "<?xml-stylesheet type=\"text/xsl\" href=\"${site_url}/css/default-sitemap.xsl?sitemap=page\"?>" >> ${sitemap_file}
 | 
						|
    echo '<urlset' >> ${sitemap_file}
 | 
						|
    echo '  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' >> ${sitemap_file}
 | 
						|
    echo '  xmlns:xhtml="http://www.w3.org/1999/xhtml"' >> ${sitemap_file}
 | 
						|
    echo '  xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"' >> ${sitemap_file}
 | 
						|
    echo '>' >> ${sitemap_file}
 | 
						|
 | 
						|
    # Add each URL to the sitemap
 | 
						|
    for file in "${html_files[@]}"; do
 | 
						|
        # Remove www_root from the path and prepend site_url
 | 
						|
        local url="${site_url}${file#$www_root}"
 | 
						|
        local lastmod=$(stat -c %y "${file}" 2>/dev/null | cut -d' ' -f1,2 | sed 's/ /T/' | sed 's/\..*$//')
 | 
						|
 | 
						|
        echo "  <url>" >> ${sitemap_file}
 | 
						|
        echo "    <loc>${url}</loc>" >> ${sitemap_file}
 | 
						|
        echo "    <lastmod><![CDATA[${lastmod}+01:00]]></lastmod>" >> "${sitemap_file}"
 | 
						|
        echo "    <changefreq><![CDATA[always]]></changefreq>" >> ${sitemap_file}
 | 
						|
        echo "    <priority><![CDATA[1]]></priority>" >> ${sitemap_file}
 | 
						|
        echo "  </url>" >> ${sitemap_file}
 | 
						|
    done
 | 
						|
 | 
						|
    # End of the XML file
 | 
						|
    echo '</urlset>' >> "${sitemap_file}"
 | 
						|
 | 
						|
    if (${debug}); then _msg debug "Sitemap generated at ${sitemap_file}"; fi
 | 
						|
 | 
						|
fi
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function _link() {
 | 
						|
    # This converts #link tags to actual clickable links in a provided string
 | 
						|
 | 
						|
    local content="${1}"
 | 
						|
    local modified_content=""
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    # Process the content line by line
 | 
						|
    echo "${content}" | while IFS= read -r line; do
 | 
						|
        if [[ ${line} == *"#link"* ]]; then
 | 
						|
            if (${debug}) _msg debug "_link: URL_MAIN(line): ${line}"
 | 
						|
 | 
						|
            # Extract the URL and the link text
 | 
						|
            local url_full=$(echo "${line}" | awk -F'#link ' '{print $2}' | awk -F'¤' '{print $1 "¤" $2}')
 | 
						|
            local url_dest=$(echo "${url_full}" | awk -F'¤' '{print $1}')
 | 
						|
            local url_txt=$(echo "${url_full}" | awk -F'¤' '{print $2}')
 | 
						|
            
 | 
						|
            if (${debug}) _msg debug "_link_ URL: ${url_dest}"
 | 
						|
            if (${debug}) _msg debug "_link: Text: ${url_txt}"
 | 
						|
 | 
						|
            # Form the replacement HTML link
 | 
						|
            local modified_link="<a href=\"${url_dest}\">${url_txt}"
 | 
						|
            if [[ ${url_dest} =~ ^https?:// ]]; then
 | 
						|
                # Add external link icon for external URLs
 | 
						|
                modified_link+="<img class=\"exticon\" alt=\"External site icon\" src=\"/images/ext-url.png\" width=\"16\" />"
 | 
						|
            fi
 | 
						|
            modified_link+="</a>"
 | 
						|
            line=${line//"#link ${url_full}"/${modified_link}}
 | 
						|
        fi
 | 
						|
        modified_content+="${line}\n"
 | 
						|
    done
 | 
						|
 | 
						|
    # Return the modified content
 | 
						|
    echo -e "${modified_content}"
 | 
						|
}
 | 
						|
 | 
						|
function _image() {
 | 
						|
    # This replaces #showimg tags with actual HTML img tags in a provided string
 | 
						|
 | 
						|
    local content="${1}"
 | 
						|
    local modified_content=""
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    # Process the content line by line
 | 
						|
    echo "${content}" | while IFS= read -r line; do
 | 
						|
        if [[ ${line} == *"#showimg"* ]]; then
 | 
						|
            if (${debug}) _msg debug "_image: Processing line: ${line}"
 | 
						|
 | 
						|
            # Extract image link and alt text
 | 
						|
            local img_link=$(echo "${line}" | awk -F'#showimg ' '{print $2}')
 | 
						|
            local image=$(echo "${img_link}" | awk -F'¤' '{print $1}')
 | 
						|
            local img_alt=$(echo "${img_link}" | awk -F'¤' '{print $2}')
 | 
						|
 | 
						|
            # Determine the source of the image
 | 
						|
            local real_image=""
 | 
						|
            if [[ ${image} =~ ^https?:// ]]; then
 | 
						|
                real_image=${image}
 | 
						|
            elif [[ ${image} =~ ^\/ ]]; then
 | 
						|
                real_image=${image}
 | 
						|
            else
 | 
						|
                real_image="/images/${image}"
 | 
						|
            fi
 | 
						|
 | 
						|
            # Form the replacement HTML image tag
 | 
						|
            local img_tag="<img src=\"${real_image}\" alt=\"${img_alt}\" width=\"500\" />"
 | 
						|
            line=${line//"#showimg ${img_link}"/${img_tag}}
 | 
						|
        fi
 | 
						|
        modified_content+="${line}\n"
 | 
						|
    done
 | 
						|
 | 
						|
    # Return the modified content
 | 
						|
    echo -e "${modified_content}"
 | 
						|
}
 | 
						|
 | 
						|
function _youtube() {
 | 
						|
    # This embeds a YouTube video in a provided string
 | 
						|
 | 
						|
    local content="${1}"
 | 
						|
    local modified_content=""
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    # Process the content line by line
 | 
						|
    echo "${content}" | while IFS= read -r line; do
 | 
						|
        if [[ ${line} == *"#ytvideo"* ]]; then
 | 
						|
            if (${debug}) _msg debug "_youtube: Processing line: ${line}"
 | 
						|
 | 
						|
            # Extract YouTube video ID
 | 
						|
            local yt_id=$(echo "${line}" | awk -F'#ytvideo ' '{print $2}')
 | 
						|
 | 
						|
            # Form the replacement YouTube iframe embed
 | 
						|
            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>"
 | 
						|
            line=${line//"#ytvideo ${yt_id}"/${yt_iframe}}
 | 
						|
        fi
 | 
						|
        modified_content+="${line}\n"
 | 
						|
    done
 | 
						|
 | 
						|
    # Return the modified content
 | 
						|
    echo -e "${modified_content}"
 | 
						|
}
 | 
						|
 | 
						|
function _cleanup() {
 | 
						|
    # This removes tags used in the templates that may be left over for some reason
 | 
						|
 | 
						|
    local content="${1}"
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    if (${debug}) _msg debug "_cleanup: Cleaning up tags in content"
 | 
						|
 | 
						|
    # Perform the cleanup
 | 
						|
    # -e "s|BLOGINDEX\ ||g"
 | 
						|
    local cleaned_content=$(echo "${content}" | sed \
 | 
						|
        -e "s|¤||g" \
 | 
						|
        -e "s|#showimg\ ||g" \
 | 
						|
        -e "s|#ytvideo\ ||g" \
 | 
						|
        -e "s|#link\ ||g" \
 | 
						|
        )
 | 
						|
 | 
						|
    # Return the cleaned content
 | 
						|
    echo "${cleaned_content}"
 | 
						|
}
 | 
						|
 | 
						|
function _html() {
 | 
						|
    local content="$1"
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    if ${debug}; then
 | 
						|
        echo "_html: Converting QStags in content"
 | 
						|
    fi
 | 
						|
 | 
						|
    # Use perl to convert QStags to HTML
 | 
						|
    perl -0777 -pe '
 | 
						|
    BEGIN {
 | 
						|
        @tags = (
 | 
						|
            "#BR", "<br/>\n",
 | 
						|
            "#BD", "<b>", "#EBD", "</b>",
 | 
						|
            "#I", "<i>", "#EI", "</i>\n",
 | 
						|
            "#P", "<p>", "#EP", "</p>\n",
 | 
						|
            "#Q", "<blockquote>", "#EQ", "</blockquote>\n",
 | 
						|
            "#C", "<code>", "#EC", "</code>\n",
 | 
						|
            "#H1", "<h1>", "#EH1", "</h1>\n",
 | 
						|
            "#H2", "<h2>", "#EH2", "</h2>\n",
 | 
						|
            "#H3", "<h3>", "#EH3", "</h3>\n",
 | 
						|
            "#H4", "<h4>", "#EH4", "</h4>\n",
 | 
						|
            "#H5", "<h5>", "#EH5", "</h5>\n",
 | 
						|
            "#H6", "<h6>", "#EH6", "</h6>\n",
 | 
						|
            "#STRONG", "<strong>", "#ESTRONG", "</strong>\n",
 | 
						|
            "#EM", "<em>", "#EEM", "</em>\n",
 | 
						|
            "#DV", "<div>", "#EDV", "</div>\n",
 | 
						|
            "#SPN", "<span>", "#ESPN", "</span>\n",
 | 
						|
            "#UL", "<ul>", "#EUL", "</ul>\n",
 | 
						|
            "#OL", "<ol>", "#EOL", "</ol>\n",
 | 
						|
            "#LI", "<li>", "#ELI", "</li>\n",
 | 
						|
            "#U", "<u>", "#EU", "</u>\n",
 | 
						|
            "#TBL", "<table>", "#ETBL", "</table>\n",
 | 
						|
            "#TR", "<tr>", "#ETR", "</tr>\n",
 | 
						|
            "#TD", "<td>", "#ETD", "</td>\n",
 | 
						|
            "#TH", "<th>", "#ETH", "</th>\n",
 | 
						|
            "#ART", "<article>", "#EART", "</article>\n",
 | 
						|
            "#SEC", "<section>", "#ESEC", "</section>\n",
 | 
						|
            "#ASIDE", "<aside>", "#EASIDE", "</aside>\n",
 | 
						|
            "#NAV", "<nav>", "#ENAV", "</nav>\n",
 | 
						|
            "#BTN", "<button>", "#EBTN", "</button>\n",
 | 
						|
            "#SEL", "<select>", "#ESEL", "</select>\n",
 | 
						|
            "#OPT", "<option>", "#EOPT", "</option>\n",
 | 
						|
            "#LT", "<", "#GT", ">", "#NUM", "#"
 | 
						|
        );
 | 
						|
    }
 | 
						|
    for (my $i = 0; $i < $#tags; $i += 2) {
 | 
						|
        my $tag = $tags[$i];
 | 
						|
        my $html = $tags[$i + 1];
 | 
						|
        s/\Q$tag\E/$html/g;
 | 
						|
    }
 | 
						|
    ' <<< "$content"
 | 
						|
}
 | 
						|
 | 
						|
function _zhtml() {
 | 
						|
  # This function uses the regex module from Zsh to parse the QStags
 | 
						|
  
 | 
						|
    local content="$1"
 | 
						|
    local debug=false
 | 
						|
 | 
						|
    if ${debug}; then
 | 
						|
        echo "_html: Converting QStags in content"
 | 
						|
    fi
 | 
						|
 | 
						|
    # Load regex module
 | 
						|
    zmodload zsh/regex
 | 
						|
 | 
						|
    # Define tag replacements as an associative array
 | 
						|
    typeset -A tags=(
 | 
						|
        "#BR" "<br/>\n"
 | 
						|
        "#BD" "<b>" "#EBD" "</b>"
 | 
						|
        "#I" "<i>" "#EI" "</i>\n"
 | 
						|
        "#P" "<p>" "#EP" "</p>\n"
 | 
						|
        "#Q" "<blockquote>" "#EQ" "</blockquote>\n"
 | 
						|
        "#C" "<code>" "#EC" "</code>\n"
 | 
						|
        "#H1" "<h1>" "#EH1" "</h1>\n"
 | 
						|
        "#H2" "<h2>" "#EH2" "</h2>\n"
 | 
						|
        "#H3" "<h3>" "#EH3" "</h3>\n"
 | 
						|
        "#H4" "<h4>" "#EH4" "</h4>\n"
 | 
						|
        "#H5" "<h5>" "#EH5" "</h5>\n"
 | 
						|
        "#H6" "<h6>" "#EH6" "</h6>\n"
 | 
						|
        "#STRONG" "<strong>" "#ESTRONG" "</strong>\n"
 | 
						|
        "#EM" "<em>" "#EEM" "</em>\n"
 | 
						|
        "#DV" "<div>" "#EDV" "</div>\n"
 | 
						|
        "#SPN" "<span>" "#ESPN" "</span>\n"
 | 
						|
        "#UL" "<ul>" "#EUL" "</ul>\n"
 | 
						|
        "#OL" "<ol>" "#EOL" "</ol>\n"
 | 
						|
        "#LI" "<li>" "#ELI" "</li>\n"
 | 
						|
        "#U" "<u>" "#EU" "</u>\n"
 | 
						|
        "#TBL" "<table>" "#ETBL" "</table>\n"
 | 
						|
        "#TR" "<tr>" "#ETR" "</tr>\n"
 | 
						|
        "#TD" "<td>" "#ETD" "</td>\n"
 | 
						|
        "#TH" "<th>" "#ETH" "</th>\n"
 | 
						|
        "#ART" "<article>" "#EART" "</article>\n"
 | 
						|
        "#SEC" "<section>" "#ESEC" "</section>\n"
 | 
						|
        "#ASIDE" "<aside>" "#EASIDE" "</aside>\n"
 | 
						|
        "#NAV" "<nav>" "#ENAV" "</nav>\n"
 | 
						|
        "#BTN" "<button>" "#EBTN" "</button>\n"
 | 
						|
        "#SEL" "<select>" "#ESEL" "</select>\n"
 | 
						|
        "#OPT" "<option>" "#EOPT" "</option>\n"
 | 
						|
        "#LT" "<" "#GT" ">" "#NUM" "#"
 | 
						|
    )
 | 
						|
 | 
						|
    for tag html (${(kv)tags}); do
 | 
						|
        # Escape tag for regex use
 | 
						|
        local escapedTag=$(printf '%s' "$tag" | sed 's/[].\[^$*]/\\&/g')
 | 
						|
        if [[ "$content" =~ "$escapedTag" ]]; then
 | 
						|
            content=${content//($tag)/$html}
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    echo "$content"
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# Time to run the first function
 | 
						|
_blogs
 | 
						|
_pages
 | 
						|
_add_blog_list_to_index
 | 
						|
_sitemap |