Files for the official Dragora website
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

412 lines
7.8 KiB

#!/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 -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")"
item="${item%/}"
printf " %${index_width}s %s%s%s\n" "$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
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"
else
if [[ ! "${input:1}" -lt "${#navtree[@]}" ]]
then
_perr "invalid selection -- '$input'"
printf '%s\n' "$HELP_TIP_INTERACTIVE"
else
break
fi
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
# Find the line number of the path at "$nav_slot" in $NAVTREE_FILE
local line=
while read -r line
do
[[ "$line" = "${navtree[$nav_slot]}" ]] && 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
[[ "$in_nav" -eq 1 ]] && _prompt_navplace
_add_page || _abort
[[ "$in_nav" -eq 1 ]] && _add_page_nav