mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-18 20:10:29 +01:00
Website: Create script to generate the HTML version of the man pages
When running the 'make website' command, it will call groff to convert the man pages into HTML and post-process them to get them in the style of the site, then place them in the Website Git Repository. Signed-off-by: Christophe CURIS <christophe.curis@free.fr>
This commit is contained in:
committed by
Carlos R. Mafra
parent
351e05dca9
commit
a2bf67f54c
313
script/generate-html-from-man.sh
Executable file
313
script/generate-html-from-man.sh
Executable file
@@ -0,0 +1,313 @@
|
||||
#!/bin/sh
|
||||
###########################################################################
|
||||
#
|
||||
# Window Maker window manager
|
||||
#
|
||||
# Copyright (c) 2021 Christophe CURIS
|
||||
# Copyright (c) 2021 Window Maker Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
# generate-html-from-man.sh:
|
||||
# Convert a man page into HTML using Groff, then post-process it to make
|
||||
# it fit the Window Maker site's theme and install it into the website
|
||||
# Git repository.
|
||||
#
|
||||
# The pages are generated as xhtml because that's the most convenient
|
||||
# format at current time that Groff can provide. The post-processing of the
|
||||
# page includes:
|
||||
#
|
||||
# - the basic style sheet included by groff is replaced by a call to "manpage.css";
|
||||
#
|
||||
# - if a menu list is provided with "--with-menu", then it is added at the
|
||||
# beginning of the <body> inside an "ul" with class="menu";
|
||||
#
|
||||
# - the list of sections at the beginning is enclosed in a div with class="toc";
|
||||
#
|
||||
# - emails addresses in the form "<name@example.com>" are obfuscated (to
|
||||
# not help spambots) and a mailto: link is added;
|
||||
#
|
||||
# - a link is added when an url of the form "http://..." is encountered;
|
||||
#
|
||||
# - when a man-page reference is found, in the form "name(section)", a link
|
||||
# is added, either to a local page if in the "--local-pages" list or to the
|
||||
# external url provided in "--external-url";
|
||||
#
|
||||
# - if the package name and version is provided with "--package", then a div with
|
||||
# class="footer" is added at the end of the <body>.
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
# For portability, we stick to the same sh+awk constraint as Autotools to
|
||||
# limit problems, see for example:
|
||||
# http://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Portable-Shell.html
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Report an error on stderr and exit with status 2 to tell make that we could
|
||||
# not do what we were asked
|
||||
arg_error() {
|
||||
echo "`basename $0`: $@" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# print help and exit with success status
|
||||
print_help() {
|
||||
echo "$0: convert man page into HTML"
|
||||
echo "Usage: $0 options... man-page-file"
|
||||
echo "valid options are:"
|
||||
echo " --external-url tmpl : use tmpl as URL template for non-local man pages"
|
||||
echo " --groff name : name of groff binary to use"
|
||||
echo " --local-pages names : list of man pages that are available locally"
|
||||
echo " --output filename : name of the HTML file to generate"
|
||||
echo " --with-menu code : insert the specified code to add a navigation menu"
|
||||
echo " --package name : name of package, added in the footer of page"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Sets the default values
|
||||
GROFF=groff
|
||||
|
||||
# Extract command line arguments
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--external-url)
|
||||
shift
|
||||
[ "x$external_template" = "x" ] || arg_error "only 1 template for URL can be specified (option: --external-url)"
|
||||
external_template=$1
|
||||
;;
|
||||
|
||||
--groff)
|
||||
shift
|
||||
GROFF=$1
|
||||
;;
|
||||
|
||||
--local-pages)
|
||||
shift
|
||||
local_pages="$local_pages $1 "
|
||||
;;
|
||||
|
||||
--output)
|
||||
shift
|
||||
[ -z "$output_file" ] || arg_error "only 1 target file can be specified (option: --output)"
|
||||
output_file="$1"
|
||||
;;
|
||||
|
||||
--with-menu)
|
||||
shift
|
||||
[ -z "$menu_line" ] || arg_error "only 1 code for the menu can be specified (option: --with-menu)"
|
||||
menu_line=`echo "$1" | sed -e 's/"/\\\"/g' `
|
||||
;;
|
||||
|
||||
--package)
|
||||
shift
|
||||
[ -z "$package_line" ] || arg_error "package name can be specified only once (option: --package)"
|
||||
package_line="$1"
|
||||
;;
|
||||
|
||||
-h|-help|--help) print_help ;;
|
||||
-*) arg_error "unknow option '$1'" ;;
|
||||
|
||||
*)
|
||||
[ -z "$input_file" ] || arg_error "only 1 man page can be specified"
|
||||
input_file=$1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Check consistency of command-line
|
||||
[ -z "$input_file" ] && arg_error "no source man page given"
|
||||
[ -f "$input_file" ] || arg_error "man page \"$input_file\" cannot be read"
|
||||
|
||||
if [ -n "$external_template" ]; then
|
||||
echo "$external_template" | grep '%[plu]' > /dev/null \
|
||||
|| arg_error "no marker %p, %l or %u for the page name in the URL template (option: --external-url)"
|
||||
fi
|
||||
|
||||
# Generate the name of the output file from the man page file name
|
||||
if [ -z "$output_file" ]; then
|
||||
output_file=`echo "$input_file" | sed 's,^.*/,,g ; s/\.[^.]*$//' `.html
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
|
||||
# Pass the configuration to the AWK script; remove the path information
|
||||
awk_init="BEGIN {
|
||||
external_template = \"$external_template\";
|
||||
known_pages = \" $local_pages \";
|
||||
menu_code = \"$menu_line\";
|
||||
package_line = \"$package_line\";
|
||||
source_name = \"`basename "$input_file" `\";
|
||||
}"
|
||||
|
||||
# This AWK script is post-processing the HTML generated by Groff
|
||||
awk_process_html='
|
||||
/<html>/ {
|
||||
print;
|
||||
$0 = "<!-- This file is generated automatically by a script, do not edit -->";
|
||||
}
|
||||
|
||||
# Groff is generating a title with the name of the command, followed by a table of content
|
||||
# We detect all this and embed it into a <div> section for presentation purpose
|
||||
/<h1/ {
|
||||
header = gensub(/<h1[^>]*>([^<]*)<\/h1>/, "\\1", 1);
|
||||
print " <div class=\"toc\">";
|
||||
print " <label for=\"toc-checkbutton\">" header "</label>";
|
||||
print " <input type=\"checkbox\" id=\"toc-checkbutton\" checked=\"true\">";
|
||||
print " <div id=\"toc-list\">";
|
||||
getline;
|
||||
while (!/<hr>/) {
|
||||
if (length($0) > 0) {
|
||||
print " " $0;
|
||||
}
|
||||
getline;
|
||||
}
|
||||
print " <hr>";
|
||||
print " <a href=\".\" class=\"return\">Return to list</a><br>";
|
||||
print " </div>";
|
||||
print " </div>";
|
||||
print "";
|
||||
$0 = "<article>";
|
||||
}
|
||||
|
||||
# Groff is adding an horizontal line at the end of the page, we remove it;
|
||||
# we take the opportunity to close the <article> that we opened after the toc
|
||||
/<hr>/ {
|
||||
$0 = "</article>"
|
||||
}
|
||||
|
||||
# Groff includes a basic CSS style, we want to replace it with our own to be consitent with
|
||||
# the general website style
|
||||
/<style/ {
|
||||
while (!/<\/style>/) {
|
||||
getline;
|
||||
}
|
||||
print "<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">";
|
||||
$0 = "<link rel=\"stylesheet\" type=\"text/css\" href=\"/manpage.css\">"
|
||||
}
|
||||
|
||||
# Detect the email address and add a link; take the opportunity to conceal it the same way it is
|
||||
# done for the mailing list, to make spammers work less easy
|
||||
/<[^@ ]*@[^<@> ]*>/ && inside_body {
|
||||
line = "";
|
||||
while (1) {
|
||||
idx_start = match($0, /<[^@ ]*@[^<@> ]*>/);
|
||||
if (idx_start == 0) break;
|
||||
|
||||
email = substr($0, idx_start + 4, RLENGTH - 8);
|
||||
gsub(/@/, " (at) ", email);
|
||||
gsub(/\./, " (dot) ", email);
|
||||
|
||||
line = line substr($0, 1, idx_start - 1) "<";
|
||||
line = line "<a href=\"mailto:" email "\">" email "</a>>";
|
||||
$0 = substr($0, idx_start + RLENGTH);
|
||||
}
|
||||
$0 = line $0;
|
||||
}
|
||||
|
||||
# Detect urls and add a link
|
||||
/http:\/\// && inside_body {
|
||||
line = "";
|
||||
while (1) {
|
||||
idx_start = index($0, "http://");
|
||||
if (idx_start == 0) break;
|
||||
|
||||
line = line substr($0, 1, idx_start - 1);
|
||||
$0 = substr($0, idx_start);
|
||||
idx_end = match($0, /[ \t&]/);
|
||||
if (idx_end == 0) idx_end = length($0) + 1;
|
||||
|
||||
line = line "<a href=\"" substr($0, 1, idx_end - 1) "\">";
|
||||
line = line substr($0, 1, idx_end - 1) "</a>";
|
||||
|
||||
$0 = substr($0, idx_end);
|
||||
}
|
||||
$0 = line $0;
|
||||
}
|
||||
|
||||
# Detect references to other man pages and add a link
|
||||
/<b>[A-Za-z_0-9]*<\/b>\([1-9][a-z]*\)/ {
|
||||
line = "";
|
||||
while (1) {
|
||||
idx_start = match($0, /<b>[A-Za-z_0-9]*<\/b>\([1-9][a-z]*\)/);
|
||||
if (idx_start == 0) break;
|
||||
|
||||
line = line substr($0, 1, idx_start - 1);
|
||||
split(substr($0, idx_start + 3), elements, /<\/b>\(|\)/);
|
||||
# elements[1] contains the name of the man-page
|
||||
# elements[2] contains the section
|
||||
$0 = substr($0, idx_start + RLENGTH);
|
||||
|
||||
idx_known = match(known_pages, " ([^ ]*/)*" elements[1] "\\." elements[2]);
|
||||
if (idx_known == 0) {
|
||||
if (external_template == "") {
|
||||
print "Error: no URL provided for external man page, needed for \"" elements[1] "(" elements[2] ")\" at line " NR > "/dev/stderr";
|
||||
exit(2);
|
||||
}
|
||||
url = gensub(/%s/, elements[2], "g", external_template);
|
||||
url = gensub(/%p/, elements[1], "g", url);
|
||||
url = gensub(/%l/, tolower(elements[1]), "g", url);
|
||||
url = gensub(/%u/, toupper(elements[1]), "g", url);
|
||||
} else {
|
||||
# When it is a known page, use the data from known_pages to have possible path information
|
||||
url = substr(known_pages, idx_known + 1, RLENGTH - length(elements[2]) - 2) ".html";
|
||||
}
|
||||
|
||||
line = line "<a href=\"" url "\"><tt>" elements[1] "</tt>(" elements[2] ")</a>";
|
||||
}
|
||||
$0 = line $0;
|
||||
}
|
||||
|
||||
# Detect the start of the page to insert the navigation menu code
|
||||
/<body>/ {
|
||||
inside_body = 1;
|
||||
print;
|
||||
print "<div id=\"wrapper\">";
|
||||
if (menu_code) {
|
||||
while (getline < menu_code) {
|
||||
print;
|
||||
}
|
||||
}
|
||||
next;
|
||||
}
|
||||
/<\/body>/ {
|
||||
if (package_line) {
|
||||
print "<div class=\"footer\">"
|
||||
print " This man page is part of <div id=\"pkgname\">" package_line "</div>";
|
||||
print "</div>"
|
||||
}
|
||||
print " <div id=\"titlebar\">";
|
||||
print " <div id=\"minimize\"></div>";
|
||||
print " <div id=\"titlebar-inner\">Window Maker Manual: " gensub(/\.(.*)$/, "(\\1)", 1, source_name) "</div>";
|
||||
print " <div id=\"close\"></div>";
|
||||
print " </div>";
|
||||
print " <div id=\"resizebar\">";
|
||||
print " <div id=\"resizel\"></div>";
|
||||
print " <div id=\"resizebar-inner\"></div>";
|
||||
print " <div id=\"resizer\"></div>";
|
||||
print " </div>";
|
||||
print "</div>"; # close "wrapper"
|
||||
inside_body = 0;
|
||||
}
|
||||
|
||||
{ print }
|
||||
'
|
||||
|
||||
###########################################################################
|
||||
$GROFF -man -Dutf8 -Thtml < "$input_file" | \
|
||||
awk "$awk_init$awk_process_html" > "$TARGET/$output_file" \
|
||||
|| exit $?
|
||||
Reference in New Issue
Block a user