3 [ "$include_tools" ] && return 0
6 # Copyright 2022 - 2024 Paul Hänsch
8 # Permission to use, copy, modify, and/or distribute this software for any
9 # purpose with or without fee is hereby granted, provided that the above
10 # copyright notice and this permission notice appear in all copies.
12 # THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
15 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
18 # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 . "${_EXEC}/cgilite/storage.sh"
22 CACHE_AGE=${CACHE_AGE:-300}
23 export MD_MACROS="$_EXEC/macros"
24 export MD_HTML="${MD_HTML:-false}"
30 md "${_EXEC}"/parsers/*
31 elif [ "$#" = 1 ]; then
41 # Check if page exists, if possible fall
42 # back to default page from installation
43 local page="$(PATH "$1")"
46 # Regular processing, keep in sync with tools.sh
47 if [ -f "$_DATA/pages/$page/:$LANGUAGE/#page.md" ]; then
48 printf %s\\n "$_DATA/pages/$page/:$LANGUAGE/#page.md"
49 elif [ -f "$_DATA/pages/$page/#page.md" ]; then
50 printf %s\\n "$_DATA/pages/$page/#page.md"
51 elif [ -f "$_EXEC/pages/$page/:$LANGUAGE/#page.md" ]; then
52 printf %s\\n "$_EXEC/pages/$page/:$LANGUAGE/#page.md"
53 elif [ -f "$_EXEC/pages/$page/#page.md" ]; then
54 printf %s\\n "$_EXEC/pages/$page/#page.md"
58 # ^^ suppress error messages produced
59 # by printf when stdout was closed
65 # Print content of a wiki page
66 # Get page from data or underlay dir, handle caching
67 local page="$(PATH "$1")" mdfile cache cachetime
69 cache="$_DATA/pages/$page/#page:${LANGUAGE}.${USER_ID}.cache"
71 mdfile="$(mdfile "$page")" || return 4
72 acl_read "$page" || return 3
74 cachetime="$(stat -c %Y -- "$mdfile" "$cache" 2>/dev/null)"
76 if [ "${cachetime#*${BR}}" -gt "${cachetime%${BR}*}" \
77 -a "${cachetime#*${BR}}" -gt "$((_DATE - CACHE_AGE))" ]; then
80 mkdir -p -- "$_DATA/pages/$page/"
81 # Macros expect to find page directory as working dir
82 ( cd -- "$_DATA/pages/$page/";
84 | tee -- "${cache}.$$"
86 grep -q '^%nocache' "$mdfile" \
87 && rm -- "${cache}.$$" \
88 || mv -- "${cache}.$$" "${cache}"
95 if [ $size -gt $((1024 * 1024 * 1024)) ]; then
96 size=$((size / 1024 / 1024 / 1024 * 10 + size / 1024 / 1024 % 1024 / 100))
97 printf "%i.%i GB" "$((size / 10))" "$((size % 10))"
99 elif [ $size -gt $((1024 * 1024)) ]; then
100 size=$((size / 1024 / 1024 * 10 + size / 1024 % 1024 / 100))
101 printf "%i.%i MB" "$((size / 10))" "$((size % 10))"
103 elif [ $size -gt $((1024)) ]; then
104 size=$((size / 1024 * 10 + size % 1024 / 100))
105 printf "%i.%i KB" "$((size / 10))" "$((size % 10))"
108 printf "%i B" "$size"
113 local pattern="${1%/}" IFS=''
114 local glob page pagedir
117 [ "$page" = "$pattern" ] && page=.
118 [ ! "$page" ] && page=/
119 pattern="${pattern##*/}"
120 [ ! "$pattern" ] && pattern="*"
124 for glob in "$_DATA/pages/$page/#attachments"/$pattern; do printf '%s\n' "${glob#"$_DATA/pages"}"; done
125 for glob in "$_EXEC/pages/$page/#attachments"/$pattern; do printf '%s\n' "${glob#"$_EXEC/pages"}"; done
128 for glob in "$_DATA/pages/$PATH_INFO/$page/#attachments"/$pattern; do printf '%s\n' "${glob#"$_DATA/pages/$PATH_INFO/"}"; done
129 for glob in "$_EXEC/pages/$PATH_INFO/$page/#attachments"/$pattern; do printf '%s\n' "${glob#"$_EXEC/pages/$PATH_INFO/"}"; done
133 | while read -r glob; do
134 [ -e "$glob" ] || continue
135 pagedir="$(page_abs "${glob%%/#attachments/*}/")"
136 [ -d "$_DATA/pages/$pagedir" -o -d "$_EXEC/pages/$pagedir" ] \
137 && printf '%s\n' "${glob%%/#attachments/*}/${glob#*/#attachments/}"
142 local pattern="${1%/}/" depth="${2:-0}" IFS=''
143 local glob page pagedir
147 for glob in "$_DATA/pages"$pattern; do printf '%s\n' "${glob#"$_DATA/pages"}"; done
148 for glob in "$_EXEC/pages"$pattern; do printf '%s\n' "${glob#"$_EXEC/pages"}"; done
151 for glob in "$_DATA/pages/$PATH_INFO"/$pattern; do printf '%s\n' "${glob#"$_DATA/pages/$PATH_INFO/"}"; done
152 for glob in "$_EXEC/pages/$PATH_INFO"/$pattern; do printf '%s\n' "${glob#"$_EXEC/pages/$PATH_INFO/"}"; done
156 | while read -r page; do
157 # Not a page directory (just a metadata dir)
158 [ ! "${page%%#*}" -o ! "${page%%*/#*}" ] && continue
160 # Omit "system" pages unless explicitly wanted
161 [ ! "${page%%\[*\]/*}" -o ! "${page%%*/\[*\]/*}" ] && [ "$glob_system_pages" != true ] && continue
163 # Omit translation pages if translations are enabled
164 [ ! "${page%%:*}" -o ! "${page%%*/:*}" ] && [ "$LANGUAGE_DEFAULT" ] && continue
166 pagedir="$(page_abs "$page")"
168 if [ -d "$_DATA/pages/$pagedir" -o -d "$_EXEC/pages/$pagedir" ]; then
169 printf '%s\n' "$page"
170 if ! [ "$depth" -eq 0 ]; then
171 PATH_INFO="$pagedir" page_glob "*" "$((depth - 1))" \
172 | while read -r glob; do printf %s%s\\n "$page" "$glob"; done
181 *) PATH "${PATH_INFO%/*}/${1%/}/";;
186 # true if PAGE is tagges with all TAGS
187 local page="$(page_abs "$1")"; shift 1;
188 local tdir="$_DATA/tags" tag dt df
191 tag="$(printf %s "$tag" |awk '{ sub(/^[#!]/, ""); gsub(/[^[:alnum:]]/, "_"); print toupper($0); }')"
192 dt="$(DBM "${tdir}/${tag}" get "${page}")" || return 1
193 df="$(stat -c %Y "$(mdfile "$page")")" || return 1
194 if [ "$df" -gt "$dt" ]; then
195 DBM "${tdir}/${tag}" remove "${page}"
203 # true if PAGE is tagged with any of TAGS
204 local page="$(page_abs "$1")"; shift 1;
205 local tdir="$_DATA/tags" tag dt df
208 tag="$(printf %s "$tag" |awk '{ sub(/^[#!]/, ""); gsub(/[^[:alnum:]]/, "_"); print toupper($0); }')"
209 dt="$(DBM "${tdir}/${tag}" get "${page}")" || continue
210 df="$(stat -c %Y "$(mdfile "$page")")" || return 1
211 if [ "$df" -gt "$dt" ]; then
212 DBM "${tdir}/${tag}" remove "${page}"
222 local mdfile='' PAGE_TITLE=''
224 if mdfile="$(mdfile "${1}")"; then
226 # pick title from %title pragma
228 s;^%title[ \t]+([[:graph:]][[:print:]]+)\r?$;\1;p; tQ;
232 [ ! "${PAGE_TITLE}" ] && PAGE_TITLE="$(
233 # pick title from first h1/h2 headline
234 MD_MACROS="" md <"$mdfile" \
236 s;^.*<h1[^>]*>(.*>)?([^<]+)(<.*)?</h1>.*$;\2;; tQ;
237 s;^.*<h2[^>]*>(.*>)?([^<]+)(<.*)?</h2>.*$;\2;; tQ;
239 # reverse escapes of cgilite HTML function,
240 # to prevent later double escaping
241 # later escaping must not be omited
242 s/</</g; s/>/>/g; s/"/'\"'/g; s/'/'\''/g;
243 s/[/[/g; s/]/]/g; s/
/\r/g; s/&/\&/g;
248 if [ ! "${PAGE_TITLE}" ]; then
249 # use last part of page URL as title
251 PAGE_TITLE="${PAGE_TITLE##*/}"
253 printf %s\\n "$PAGE_TITLE"