From 752ae10dcadd508ee35e50170c0574ca6492c54f Mon Sep 17 00:00:00 2001 From: Steven Baltakatei Sandoval Date: Tue, 30 Jan 2024 00:14:18 +0000 Subject: [PATCH] feat(user/mw_create_subpage_navlinks.sh):Add script - Note: For use with generating navigation links for Mediawiki subpages. Requires manually inserting each line into each subpage. --- user/mw_create_subpage_navlinks.sh | 147 +++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 user/mw_create_subpage_navlinks.sh diff --git a/user/mw_create_subpage_navlinks.sh b/user/mw_create_subpage_navlinks.sh new file mode 100644 index 0000000..de37365 --- /dev/null +++ b/user/mw_create_subpage_navlinks.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# Desc: Generates Mediawiki subpage navigation links +# Input: file text file with list of chapters +# stdin text with list of chapters +# Output: [[../Chapter 4|Next]], [[../Chapter 2|Previous]], [[../|Up]] +# Version: 0.0.1 +# Attrib: Steven Baltakatei Sandoval. (2024-01-29). reboil.com +# License: GPLv3+ + +yell() { echo "$0: $*" >&2; } # print script path and all args to stderr +die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status +must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails +read_input() { + # Note: May accept specified file or stdin, but not both + # Input: arg input text (newline delimited) + # stdin input text (newline delimited) + # Output: stdout output text (newline delimited) + # Depends: BK-2020-03 read_stdin (v0.1.1), yell(), die() + + # Parse args + ## Only 1 argument. + if [[ "$#" -gt 1 ]]; then die "FATAL:Too many arguments ($#):$*"; fi; + ## File specified. + if [[ "$#" -eq 1 ]] && [[ -f "$1" ]] && [[ ! -p /dev/stdin ]]; then + while read -r line; do + printf "%s\n" "$line"; + done < "$1" && return 0; fi; + if [[ "$#" -eq 0 ]] && [[ -p /dev/stdin ]]; then + read_stdin && return 0; fi; + die "FATAL:Unknown error."; +}; +read_stdin() { + # Desc: Consumes stdin; outputs as stdout lines + # Input: stdin (consumes) + # Output: stdout (newline delimited) + # return 0 stdin read + # return 1 stdin not present + # Example: printf "foo\nbar\n" | read_stdin + # Depends: GNU bash (version 5.1.16), GNU Coreutils 8.32 (cat) + # Version: 0.1.1 + # Attrib: Steven Baltakatei Sandoval (2024-01-29). reboil.com + local input_stdin output; + + # Store stdin + if [[ -p /dev/stdin ]]; then + input_stdin="$(cat -)" || { + echo "FATAL:Error reading stdin." 1>&2; return 1; }; + else + return 1; + fi; + + # Store as output array elements + ## Read in stdin + if [[ -n $input_stdin ]]; then + while read -r line; do + output+=("$line"); + done < <(printf "%s\n" "$input_stdin") || { + echo "FATAL:Error parsing stdin."; return 1; }; + fi; + + # Print to stdout + printf "%s\n" "${output[@]}"; + + return 0; +}; # read stdin to stdout lines +validate_subpage_list() { + # Desc: Check for illegal characters in subpage titles + # Input: stdin unvalidated subpage list + # Output: stdout validated subpage list + # Depends: BK-2020-03 read_stdin(), yell(), die() + # GNU sed v4.8 + while read -r line; do + + # Reject chars illegal in Mediawiki page titles. + re_illegal='[][><|}{#_]'; # match illegal page names chars #, <, >, [, ], _, {, |, } + if [[ "$line" =~ $re_illegal ]]; then + die "FATAL:Illegal char. Not allowed: #, <, >, [, ], _, {, |, }:$line"; + fi; + + # Reject trailing spaces. + re_ts=' $'; # match trailing space + if [[ "$line" =~ $re_ts ]]; then + die "FATAL:Trailing spaces not allowed:$line"; + fi; + + # Replace some chars with HTML-style codes + ## replace ampersand & with & # must be first + ## replace double quote " with " + ## replace single quote ' with ' + line="$(sed \ + -e 's/&/\&/g' \ + -e 's/"/\"/g' \ + -e "s/'/\'/g" \ + <<< "$line" )" || { echo "FATAL:Error running sed."; }; + printf "%s\n" "$line"; + done || { + echo "FATAL:Error reading stdin." 1>&2; return 1; }; +}; +generate_wikicode() { + # Input: stdin validated subpage list + # Output: stdout wikicode + local lprev lnext; + + n=0; + while read -r line; do + #yell "$n:Processing line:$line"; # debug + lprev="$lcurr"; + lcurr="$lnext"; + lnext="$line"; + #declare -p lprev lcurr lnext; # debug + + # Skip first iteration + if [[ "$n" -eq 0 ]]; then + # yell "$n:DEBUG:Skipping first iteration."; # debug + ((n++)); + #printf -- "----\n" 1>&2; # debug + continue; fi; + + # Handle first valid input set + # yell "$n:DEBUG:Handling first valid input set."; # debug + if [[ "$n" -eq 1 ]]; then + printf "[[../%s|Next]], [[../|Up]]\n" \ + "$lnext"; + #printf -- "----\n" 1>&2; # debug + ((n++)); continue; fi; + + # Handle middle lines + # yell "$n:DEBUG:Handling middle lines."; # debug + printf "[[../%s|Next]], [[../%s|Previous]], [[../|Up]]\n" \ + "$lnext" "$lprev"; + ((n++)); + #printf -- "----\n" 1>&2; # debug + done; + + # Handle last line + lprev="$lcurr"; + lcurr="$lnext"; + lnext="$line"; + printf "[[../%s|Previous]], [[../|Up]]\n" \ + "$lprev"; + ((n++)); +}; +main() { + read_input "$@" | validate_subpage_list | generate_wikicode; +}; # main program + +main "$@"; -- 2.30.2