NAME
App::FuguWeb - a static documentation site for a Perl project
SYNOPSIS
fuguweb build --out web/build
fuguweb check --out web/build
use App::FuguWeb;
my $safe = App::FuguWeb::escape_html($title);
my $file = App::FuguWeb::CONFIG_FILE; # .fuguwebrc
DESCRIPTION
fuguweb renders one static site from the documentation that a Perl project already keeps: mdoc(7) manuals, POD sidecars, and Markdown. There is no templating language and no JavaScript. The tool runs mandoc, lowdown, and pod2man, and wraps each result in one shared chrome.
A project needs no build recipe. It writes one .fuguwebrc at its root, keeps its body fragments and its assets in one source directory, and runs fuguweb build. See fuguweb(1) for the subcommands and the exit codes.
This file holds what more than one module in the namespace needs: two constants and four functions, documented below. The rest of the work is split by concern:
- App::FuguWeb::Config
-
The site description: the settings, the navigation, the pages, and the manual groups.
- App::FuguWeb::Page
-
The chrome around one body fragment.
- App::FuguWeb::Render
-
The three external renderers.
- App::FuguWeb::Manual
-
One manual source: its path, name, section, page, and description.
- App::FuguWeb::Index
-
The body of the manual index.
- App::FuguWeb::Site
-
The whole build.
- App::FuguWeb::Check
-
The checks over a built site.
- App::FuguWeb::CLI
-
Subcommand dispatch over Fugu::CLI.
THE CONFIGURATION FILE
.fuguwebrc sits at the project root and uses the Fugu::Config grammar: a setting on a line of its own, and a block that opens with a brace at the end of its header line. A # starts a comment, and the grammar has no escape for it, so a value may not hold one.
site = OpenHAP
out_dir = web/build
source_dir = web
entry = index.html
nav "fugu.html" {
label = Fugu
}
page "install.html" {
title = Install
markdown = INSTALL.md
}
manuals "Fugu" {
dir = man/fugu
anchor = fugu
namespace = "Fugu::"
}
modules "OpenHAP modules" {
dir = lib/App/OpenHAP
anchor = modules
}
A page block names exactly one source: body for a fragment in the source directory, markdown for a Markdown file, or index = yes for the generated manual index. unlinked = yes marks a page that no other page links to, such as 404.html.
Three rules keep a list out of the file. A manuals block reads its directory. A modules block finds every .pod file below its directory, and the sidecar that names the directory itself. Every file in the source directory that the build does not render is an asset, and the build copies it; "ASSETS" in App::FuguWeb::Site says exactly which those are.
App::FuguWeb::Config documents every setting and every default.
FUNCTIONS
escape_html
my $safe = App::FuguWeb::escape_html($text);
Escape &, < and >, in that order. The function takes bytes and returns bytes: no file in the namespace carries use utf8, so a multi-byte character passes through untouched.
escape_attr
my $safe = App::FuguWeb::escape_attr($text);
The same, plus the double quote. Use it for a value on its way into a double-quoted attribute: a value that holds a quote ends the attribute early, and everything after it becomes markup. "escape_html" alone does not guard an attribute.
list_dir
my $names = App::FuguWeb::list_dir($dir) or die "cannot read: $!";
The names in one directory, sorted, without . and ... The function returns an array reference, or undef with the reason in $!, so a caller can tell an empty directory from one it cannot read.
The sort compares bytes and never reads the locale of the builder: a site must not depend on the machine that built it.
path_below
App::FuguWeb::path_below($path, $root)
Report whether $path is $root or lies below it. A trailing slash on either does not change the answer. Both paths must be of the same kind: both absolute, or both relative to the same directory.
CONSTANTS
CONFIG_FILE
The name of the configuration file, .fuguwebrc. The name and the discovery match .fuguvmrc.
STYLESHEET
The name of the stylesheet in the output directory, style.css. The site is served from one flat directory, so every page links it under that name and the build writes it there.
SEE ALSO
fuguweb(1), Fugu::Config, mandoc(1), lowdown(1), pod2man
AUTHOR
Dick Olsson <hi@senzilla.io>