.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "App::DocKnot::Spin::Thread 3pm" .TH App::DocKnot::Spin::Thread 3pm "2022-01-20" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" App::DocKnot::Spin::Thread \- Generate HTML from the macro language thread .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use App::DocKnot::Spin::Thread; \& \& my $input = \*(Aqsome thread\*(Aq; \& my $thread = App::DocKnot::Spin::Thread\->new(); \& my $output = $thread\->spin_thread($input); \& \& use App::DocKnot::Spin::Sitemap; \& use App::DocKnot::Spin::Versions; \& \& my $sitemap = App::DocKnot::Spin::Sitemap\->new(\*(Aq/input/.sitemap\*(Aq); \& my $versions = App::DocKnot::Spin::Versions\->new(\*(Aq/input/.versions\*(Aq); \& $thread = App::DocKnot::Spin::Thread\->new({ \& source => \*(Aq/input\*(Aq, \& output => \*(Aq/output\*(Aq, \& sitemap => $sitemap, \& versions => $versions, \& }); \& $thread\->spin_thread_file(\*(Aq/input/file.th\*(Aq, \*(Aq/output/file.html\*(Aq); \& $thread\->spin_thread_output( \& $input, \*(Aq/path/to/file.pod\*(Aq, \*(AqPOD\*(Aq, \*(Aq/output/file.html\*(Aq \& ); .Ve .SH "REQUIREMENTS" .IX Header "REQUIREMENTS" Perl 5.24 or later and the modules Git::Repository, Image::Size, List::SomeUtils, and Path::Tiny, all of which are available from \s-1CPAN.\s0 .SH "DESCRIPTION" .IX Header "DESCRIPTION" This component of DocKnot implements the macro language thread, which is designed for writing simple \s-1HTML\s0 pages using somewhat nicer syntax, catering to my personal taste, and supporting variables and macros to make writing pages less tedious. .PP For the details of the thread language, see \*(L"\s-1THREAD LANGUAGE\*(R"\s0 below. .SH "CLASS METHODS" .IX Header "CLASS METHODS" .IP "new(\s-1ARGS\s0)" 4 .IX Item "new(ARGS)" Create a new App::DocKnot::Spin::Thread object. A single converter object can be used repeatedly to convert a tree of files, or can convert a single file. \s-1ARGS\s0 should be a hash reference with one or more of the following keys, all of which are optional: .RS 4 .IP "output" 4 .IX Item "output" The path to the root of the output tree when converting a tree of files. This will be used to calculate relative path names for generating inter-page links using the provided \f(CW\*(C`sitemap\*(C'\fR argument. If \f(CW\*(C`sitemap\*(C'\fR is given, this option should also always be given. .IP "sitemap" 4 .IX Item "sitemap" An App::DocKnot::Spin::Sitemap object. This will be used to create inter-page links and implement the \f(CW\*(C`\esitemap\*(C'\fR command. For inter-page links, the \&\f(CW\*(C`output\*(C'\fR argument must also be provided. .IP "source" 4 .IX Item "source" The path to the root of the input tree. If given, and if the input tree appears to be a Git repository, \f(CW\*(C`git log\*(C'\fR will be used to get more accurate last modification timestamps for files, which in turn are used to add last modified dates to the footer of the generated page. .IP "style-url" 4 .IX Item "style-url" The base \s-1URL\s0 for style sheets. A style sheet specified in a \f(CW\*(C`\eheading\*(C'\fR command will be considered to be relative to this \s-1URL\s0 and this \s-1URL\s0 will be prepended to it. If this option is not given, the name of the style sheet will be used verbatim as its \s-1URL,\s0 except with \f(CW\*(C`.css\*(C'\fR appended. .IP "versions" 4 .IX Item "versions" An App::DocKnot::Spin::Versions object. This will be used as the source of data for the \f(CW\*(C`\erelease\*(C'\fR and \f(CW\*(C`\eversion\*(C'\fR commands. .RE .RS 4 .RE .SH "INSTANCE METHODS" .IX Header "INSTANCE METHODS" .IP "spin_thread(THREAD[, \s-1INPUT\s0])" 4 .IX Item "spin_thread(THREAD[, INPUT])" Convert the given thread to \s-1HTML,\s0 returning the result. When run via this \&\s-1API,\s0 App::DocKnot::Spin::Thread will not be able to obtain sitemap information even if a sitemap was provided and therefore will not add inter-page links. \&\s-1INPUT,\s0 if given, is the full path to the original source file, used for relative paths and modification time information. .IP "spin_thread_file([INPUT[, \s-1OUTPUT\s0]])" 4 .IX Item "spin_thread_file([INPUT[, OUTPUT]])" Convert a single thread file to \s-1HTML.\s0 \s-1INPUT\s0 is the path of the thread file and \s-1OUTPUT\s0 is the path of the output file. \s-1OUTPUT\s0 or both \s-1INPUT\s0 and \s-1OUTPUT\s0 may be omitted, in which case standard input or standard output, respectively, will be used. .Sp If \s-1OUTPUT\s0 is omitted, App::DocKnot::Spin::Thread will not be able to obtain sitemap information even if a sitemap was provided and therefore will not add inter-page links. .IP "spin_thread_output(\s-1THREAD, INPUT,\s0 TYPE[, \s-1OUTPUT\s0])" 4 .IX Item "spin_thread_output(THREAD, INPUT, TYPE[, OUTPUT])" Convert the given thread to \s-1HTML,\s0 writing the result to \s-1OUTPUT.\s0 If \s-1OUTPUT\s0 is not given, write the results to standard output. This is like \fBspin_thread()\fR but does use sitemap information and adds inter-page links. It should be used when the thread input is the result of an intermediate conversion step of a known input file. \s-1INPUT\s0 should be the full path to the original source file, used for relative paths and modification time information. \s-1TYPE\s0 should be set to a one-word description of the format of the input file and is used for the page footer. .SH "THREAD LANGUAGE" .IX Header "THREAD LANGUAGE" .SS "Basic Syntax" .IX Subsection "Basic Syntax" A thread file is Unicode text with a blank line between paragraphs. .PP There is no need to explicitly mark paragraphs; paragraph boundaries will be inferred from the blank line between them and the appropriate \f(CW\*(C`

\*(C'\fR tags will be added to the \s-1HTML\s0 output. .PP There is no need to escape any character except \f(CW\*(C`\e\*(C'\fR (which should be written as \f(CW\*(C`\e\e\*(C'\fR) and an unbalanced \f(CW\*(C`[\*(C'\fR or \f(CW\*(C`]\*(C'\fR (which should be written as \&\f(CW\*(C`\eentity[91]\*(C'\fR or \f(CW\*(C`\eentity[93]\*(C'\fR respectively). Escaping \f(CW\*(C`[\*(C'\fR or \f(CW\*(C`]\*(C'\fR is not necessary if the brackets are balanced within the paragraph, and therefore is only rarely needed. .PP Commands begin with \f(CW\*(C`\e\*(C'\fR. For example, the command to insert a line break (corresponding to the \f(CW\*(C`
\*(C'\fR tag in \s-1HTML\s0) is \f(CW\*(C`\ebreak\*(C'\fR. If the command takes arguments, they are enclosed in square brackets after the command. If there are multiple arguments, they are each enclosed in square brackets and follow each other. Any amount of whitespace (but nothing else) is allowed between the command and the arguments, or between the arguments. So, for example, all of the following are entirely equivalent: .PP .Vb 2 \& \elink[index.html][Main page] \& \elink [index.html] [Main page] \& \& \elink[index.html] \& [Main page] \& \& \elink \& [index.html] \& [Main page] .Ve .PP (\f(CW\*(C`\elink\*(C'\fR is a command that takes two arguments.) .PP Command arguments may contain paragraphs of text, other commands, and so forth, nested arbitrarily (although this may not make sense for all arguments of all commands, of course). .PP Some commands take an additional optional formatting instruction argument. That argument is enclosed in parentheses and placed before any other arguments. It specifies the \f(CW\*(C`class\*(C'\fR attribute for that \s-1HTML\s0 tag, for use with style sheets, or the \f(CW\*(C`id\*(C'\fR attribute, for use with style sheets or as an anchor. If the argument begins with \f(CW\*(C`#\*(C'\fR, it will be taken to be an \f(CW\*(C`id\*(C'\fR. Otherwise, it will be taken as a \f(CW\*(C`class\*(C'\fR. .PP For example, a first-level heading is normally written as: .PP .Vb 1 \& \eh1[Heading] .Ve .PP (with one argument). Either of the following will add a class attribute of \&\f(CW\*(C`header\*(C'\fR to that \s-1HTML\s0 container that can be referred to in style sheets: .PP .Vb 2 \& \eh1(header)[Heading] \& \eh1 (header) [Heading] .Ve .PP and the following would add an id attribute of \f(CW\*(C`intro\*(C'\fR to the heading so that it could be referred to with the anchor \f(CW\*(C`#intro\*(C'\fR: .PP .Vb 1 \& \eh1(#intro)[Introduction] .Ve .PP Note that the heading commands have special handling for \f(CW\*(C`id\*(C'\fR attributes; see below for more details. .SS "Basic Format" .IX Subsection "Basic Format" There are two commands that are required to occur in every document. .PP The first is \f(CW\*(C`\eheading\*(C'\fR, which must occur before any regular page text. It takes two arguments: the page title (the title that shows up in the window title bar for the browser and is the default text for bookmarks, not anything that's displayed as part of the body of the page), and the style sheet to use. If there is no style sheet for this page, the second argument is still required but should be empty (\f(CW\*(C`[]\*(C'\fR). .PP The second required command is \f(CW\*(C`\esignature\*(C'\fR, which must be the last command in the file. \f(CW\*(C`\esignature\*(C'\fR will take care of appending the signature, appending navigation links, closing any open blocks, and any other cleanup that has to happen at the end of a generated \s-1HTML\s0 page. .PP You can include other files with the \f(CW\*(C`\einclude\*(C'\fR command, although it has a few restrictions. The \f(CW\*(C`\einclude\*(C'\fR command must appear either at the beginning of the file or after a blank line, and should be followed by a blank line. Be careful not to include the same file recursively as there is no current protection against infinite loops. .PP Thread files will not be automatically respun when included files change, so you will need touch the thread file to force the corresponding output file to be regenerated. .PP All further thread commands are divided into block commands and inline commands. These roughly correspond to \s-1HTML 5\s0's \*(L"flow content\*(R" and \*(L"phrasing content\*(R" respectively. .SS "Block Commands" .IX Subsection "Block Commands" Block commands are commands that should occur in a paragraph by themselves, not contained in a paragraph with other text. They indicate high-level structural elements of the page. \f(CW\*(C`\eheading\*(C'\fR and \f(CW\*(C`\einclude\*(C'\fR were already discussed above, but here is a complete list. Any argument of \s-1TEXT\s0 can be multiple paragraphs and contain other embedded block commands (so you can nest a list inside another list, for example). .IP "\eblock[\s-1TEXT\s0]" 4 .IX Item "block[TEXT]" Put \s-1TEXT\s0 in an indented block, equivalent to \f(CW\*(C`

\*(C'\fR in \s-1HTML.\s0 Used primarily for quotations or license statements embedded in regular text. .IP "\ebullet[\s-1TEXT\s0]" 4 .IX Item "bullet[TEXT]" \&\s-1TEXT\s0 is formatted as an item in a bullet list. This is like \f(CW\*(C`
  • \*(C'\fR inside \f(CW\*(C`