123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- #!/bin/bash
- #
- # addpage
- #
- # Page addition helper for the Dragora GNU/Linux-Libre website
- # (https://www.dragora.org)
- #
- #
- # Copyright (C) 2021 Michael Siegel
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #### INCLUDES ####
- . include/constants || exit 1
- . include/subroutines || exit 1
- #### CONSTANTS ####
- #### GLOBAL PARAMETERS ####
- pg_basedir=
- pg_dir=
- pg_prefixdir=
- pg_title=
- in_nav=
- nav_slot=
- nav_direction=
-
- #### FUNCTIONS ####
- ## Retrievers
- _show_navtree() {
- local -r index_start=0
- local indent=
- local item=
- local line_mark=
-
- local prefix="${1}/"
- local -r index_end="$(("${#navtree[@]}" - 1))"
- local -r index_width="${#index_end}"
- _get_tree_flow "${navtree[@]}" # _mk_tree_item_indent needs this
- local i=
- for ((i="$index_start"; i<="$index_end"; ++i))
- do
- if [[ "$i" -eq 0 ]] # Beware that this requires the start page to always
- # be the first in the site navigation.
- then
- item='[home page]'
- else
- item="${navtree[i]}"
- fi
- indent="$(_mk_tree_item_indent "$item" "$i")"
- if [[ "$item" = "$prefix" ]]
- then
- line_mark='* '
- else
- line_mark=' '
- fi
- item="${item%/}"
- printf "%s%${index_width}s %s%s%s\n" "$line_mark" "$i" "$indent" \
- "${item##*/}"
- done
- unset i
- }
- ## User queries and input parsers
- _prompt_basedir() {
- local input=
- while true
- do
- if [[ -z "$input" ]]
- then
- printf '%s\n' 'Please provide a directory name for the new page to add.'
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- fi
- read -rp "$PROMPT" input
- if [[ -z "$input" ]]
- then
- continue
- elif [[ "$input" = "$HELP_COMMAND" ]]
- then
- _show_help "$FUNCNAME"
- elif [[ ! "$input" =~ ^[abcdefghijklmnopqrstuvwxyz0123456789_]+$ ]]
- then
- _perr "invalid directory name -- '$input'"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- else
- break
- fi
- done
- pg_basedir="$input"
- }
- _prompt_title() {
- local input=
- while true
- do
- if [[ -z "$input" ]]
- then
- printf '%s\n' 'Please provide a title for the new page.'
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- fi
- read -rp "$PROMPT" input
- if [[ -z "$input" ]]
- then
- continue
- elif [[ "$input" = "$HELP_COMMAND" ]]
- then
- _show_help "$FUNCNAME"
- else
- break
- fi
- done
- # Currently, $pg_title may contain anything but a newline.
- # Apply further restrictions: The only whitespace character allowed shall be
- # space.
- pg_title="$input"
- }
- _prompt_prefixdir() {
- local input=
- while true
- do
- if [[ -z "$input" ]]
- then
- printf '%s\n' 'Please select where you want the new page to be placed:'
- _show_pagetree -add
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- fi
- read -rp "$PROMPT" input
- if [[ -z "$input" ]]
- then
- continue
- elif [[ "$input" = "$HELP_COMMAND" ]]
- then
- _show_help "$FUNCNAME"
- elif [[ ! "$input" =~ ^[0123456789]+$ ]]
- then
- _perr "invalid selection -- '$input'"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- else
- if [[ ! "$input" -lt "${#pagetree[@]}" ]]
- then
- _perr "invalid selection -- '$input'"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- else
- break
- fi
- fi
- done
- [[ "$input" -ne 0 ]] && pg_prefixdir="${pagetree["$input"]%/}"
- }
- _prompt_putnav() {
- local input=
- while true
- do
- if [[ -z "$input" ]]
- then
- printf '%s\n' \
- 'Do you want the new page to appear in the site navigation? [y/n]'
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- fi
-
- read -rp "$PROMPT" input
- if [[ -z "$input" ]]
- then
- continue
- elif [[ "$input" = "$HELP_COMMAND" ]]
- then
- _show_help "$FUNCNAME"
- elif [[ ! "$input" =~ ^y|n$ ]]
- then
- _perr "invalid input -- '$input'"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- else
- break
- fi
- done
- case "$input" in
- y)
- in_nav=1
- ;;
- n)
- in_nav=0
- ;;
- esac
- }
- _prompt_navplace() {
- local input=
- while true
- do
- if [[ -z "$input" ]]
- then
- printf '%s\n' \
- 'Where in the site navigation do you want the new page to appear?'
- _show_navtree "$pg_prefixdir"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- fi
- read -rp "$PROMPT" input
- if [[ -z "$input" ]]
- then
- continue
- elif [[ "$input" = "$HELP_COMMAND" ]]
- then
- _show_help "$FUNCNAME"
- elif [[ "${#input}" -lt 2 || ! "$input" =~ ^b|a[0-9]+$ ]]
- then
- _perr "invalid selection -- '$input'"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- elif [[ ! "${input:1}" -lt "${#navtree[@]}" ]]
- then
- _perr "invalid selection -- '$input'"
- printf '%s\n' "$HELP_TIP_INTERACTIVE"
- else
- break
- fi
- done
- nav_slot="${input:1}" # just the number
- nav_direction="${input:0:1}" # just the letter
- }
- _set_pagedir() {
- if [[ -z "$pg_prefixdir" ]]
- then
- pg_dir="$pg_basedir"
- else
- pg_dir="$pg_prefixdir/$pg_basedir"
- fi
- }
- ## Checks
- _probe_pagedir() {
- if [[ -e "$PAGES_DIR_MASTER/$pg_dir" ]]
- then
- _perr "Page directory '$pg_dir' already exists."
- return 1
- fi
- }
- ## Actions
- _add_page() {
- local pg_dir_full=
- local pg_file="$SOURCE_PAGE_FILENAME"
- local lang_dir=
- for lang_dir in $(_get_lang_dirs)
- do
- pg_dir_full="$PAGES_DIR/$lang_dir/$pg_dir"
- mkdir -p -- "$pg_dir_full" || return 1
- printf '%s\n\n%s' \
- "<!--PAGETITLE:${pg_title}-->" "<h2>$pg_title</h2>" \
- > "$pg_dir_full/$pg_file" || return 1
- printf '%s\n' "Added page '$pg_dir_full/$pg_file'."
- unset pg_dir_full
- done
- unset lang_dir
- }
- _add_page_nav() {
- local nav_slot_lnum=0
- local prefix=
- [[ -z "$nav_direction" ]] && nav_direction=a
- if [[ -z "$nav_slot" ]]
- then
- prefix="${pg_prefixdir}/"
- else
- prefix="${navtree[$nav_slot]}"
- fi
- local line=
- # Find the line number of "$prefix" in $NAVTREE_FILE
- while read -r line
- do
- [[ "$line" = "$prefix" ]] && break
- ((++nav_slot_lnum))
- done < "$NAVTREE_FILE"
- unset line
- cp -a -- "$NAVTREE_FILE" "${NAVTREE_FILE}.old"
- case "$nav_direction" in
- b)
- sed -- "$nav_slot_lnum a\\$pg_dir/" "$NAVTREE_FILE" \
- > "$TMP_DIR/navtree"
- ;;
- a)
- ((++nav_slot_lnum))
- sed -- "$nav_slot_lnum a\\$pg_dir/" "$NAVTREE_FILE" \
- > "$TMP_DIR/navtree"
- ;;
- esac
- mv -- "$TMP_DIR/navtree" "$NAVTREE_FILE"
- printf '%s\n' "Added '$pg_dir' to site navigation."
- }
- _show_help() {
- case "$1" in
- _prompt_basedir)
- cat <<'EOF'
- Page directory names may only contain lowercase ASCII letters (a-z), ASCII
- digits (0-9), and the underscore (_).
- EOF
- ;;
- _prompt_prefixdir)
- cat <<'EOF'
- Simply enter the number corresponding to the path into which you want the new
- page to be placed, or `0` to create a new top-level page.
- EOF
- ;;
- # _prompt_putnav)
- # :
- # ;;
- _prompt_navplace)
- cat <<'EOF'
- Please select the desired slot number and indicate whether the new page shall
- be inserted before or after the chosen slot, by putting either `b` (before) or
- `a` (after) infront of the slot number -- e.g., `a2`, to insert after the
- second slot.
- EOF
- ;;
- global)
- cat <<'EOF'
- Add a page interactively
- Usage:
- addpage
- Options:
- --help
- Show this help text and exit
- EOF
- ;;
- *)
- printf '%s\n' "Sorry, no help text available."
- ;;
- esac
- }
- #### MAIN ####
- if [[ "$1" = '--help' ]]
- then
- _show_help global
- exit
- fi
- ## Environment checks
- _env_checks || _abort
- ## Action
- _get_pagetree
- _get_navtree
- _prompt_prefixdir
- while true
- do
- _prompt_basedir
- _set_pagedir
- _probe_pagedir && break
- done
- _prompt_title
- _prompt_putnav
- if [[ "$in_nav" -eq 1 ]] && \
- [[ "$(find "${PAGES_DIR_MASTER}/$pg_prefixdir" -type d | wc -l)" -gt 1 ]]
- then
- _prompt_navplace
- fi
- _add_page || _abort
- [[ "$in_nav" -eq 1 ]] && _add_page_nav
|