App::D...::Spin(3pm)
π NAME π
Okay bestie, so the module you're looking at is App::DocKnot::Spin β a static site builder that supports the thread macro language. That's the whole vibe. It's filed under the manual App::D...::Spin(3pm), and yes, it's User Contributed Perl Documentation, we love a humble queen π«Ά
β¨ SYNOPSIS β¨
use App::DocKnot::Spin;
my $spin = App::DocKnot::Spin->new({ delete => 1 });
$spin->spin('/path/to/input', '/path/to/output');
That's it, that's the whole flex β¨
π REQUIREMENTS π
So before you even think about running this, you need:
- Perl 5.24 or later β not negotiable, bestie, she's a modern girl π
- the modules
Git::Repository,Image::Size,List::SomeUtils,Path::Iterator::Rule,Path::Tiny,Pod::Thread,Sort::Versions,Template(which is part of Template Toolkit), andYAML::XS
All of those are hanging out on CPAN, ready to be installed. πΈ
She also expects to find faq2html, cvs2xhtml, and cl2xhtml on the user's PATH, because those are the little helpers that convert certain types of files. No PATH, no conversion, iykyk.
π¦ DESCRIPTION π¦
App::DocKnot::Spin is a static site builder. You hand it an input tree of files, it generates an output HTML site. Iconic. It's built around the macro language called thread, which exists so you can write simple HTML pages with somewhat nicer syntax β catering to my personal taste, and supporting variables and macros so writing pages is less tedious. Main character energy fr fr.
Every file in the input tree gets examined recursively, and then one of three things happens:
- it's copied verbatim to the same relative path in the output tree (this is the default action),
- it's used as instructions to an external program, or
- it's converted to HTML.
When a file gets converted to HTML, the output file keeps the same name except the extension is replaced with .html. Missing directories get created, no cap.
Real talk: if the timestamp of the output file is the same as or newer than the timestamp of the input file, she assumes it's up-to-date and justβ¦ doesn't regenerate it. That optimization makes updating an existing static site so much quicker. Obsessed. β
Most files in the input tree will normally be thread files ending in .th. Those get processed into HTML using App::DocKnot::Spin::Thread. Go read that module's documentation for the details of the thread macro language, bestie.
Files ending in .spin? Those are pointers to external files that should be converted to HTML and then written to the output tree. These pointers are interpreted by App::DocKnot::Spin::Pointer β check that module's docs for their format and effects.
Files ending in various other extensions are taken to be instructions to run an external converter on a file. For those pointer files:
- line 1 β the path to the source file
- line 2 β any arguments to the converter
- line 3 β the style sheet to use, if not the default
Which converter runs is based on the extension of the file, like this:
.changelog cl2xhtml
.faq faq2html
.log cvs log <file> | cvs2xhtml
.rpod Pod::Thread
All other files that don't begin with a period get copied as-is β except that files or directories named CVS, Makefile, or RCS are ignored. But wait, there's an exception to the exception: .htaccess files are also copied. π And you can add to this list of exclusions with the exclude constructor argument.
If there's a file named .sitemap at the top of the input tree, it gets parsed with App::DocKnot::Spin::Sitemap and used for inter-page links and the \sitemap thread command. That module's documentation has the format of this file. π
If there's a file named .versions at the top of the input tree, it gets parsed with App::DocKnot::Spin::Versions and used to determine when to regenerate certain pages, plus for the \release and \version thread commands. Again: that module's docs, that file's format.
If there's a file named .rss in any directory of the input tree, it gets processed with App::DocKnot::Spin::RSS to generate RSS and possibly other files. And this happens before processing the files in that directory, so the generated files then get processed as normal. Order matters, bestie π
If there's a directory named .git at the top of the input tree, App::DocKnot::Spin assumes the input tree is a Git repository and tries to use git log to figure out the last modification date of files. git girlies rise π«Ά
π CLASS METHODS π
π new(ARGS)
Creates a shiny new App::DocKnot::Spin object. ARGS should be a hash reference with one or more of these keys:
deleteβ if you set it to a true value, then after the output tree is populated with the results of converting or copying all the files in the source tree, she deletes every file and directory in the output tree that has no corresponding file in the source tree. Cleanup queen π§Ήexcludeβ a list of strings, interpreted as regular expressions, matching files to exclude from processing. These patterns get added to a built-in list of exclude patterns.style-urlβ the base URL for style sheets. A style sheet specified in a\headingcommand is considered relative to this URL, and this URL gets prepended to it. If you don't give this option, the name of the style sheet is used verbatim as its URL β except with.cssappended. β¨
πΈ INSTANCE METHODS πΈ
π¦ spin(INPUT, OUTPUT)
Builds the source tree rooted at INPUT into an HTML static site, storing it in the directory OUTPUT. If OUTPUT doesn't exist, it will be created. Slay.
β AUTHOR β
Russ Allbery <rra@cpan.org>
π COPYRIGHT AND LICENSE π
Copyright 1999-2011, 2013, 2021-2023 Russ Allbery <rra@cpan.org>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Like, no warranty bestie, she said what she said π
π SEE ALSO π
cl2xhtml(1), cvs2xhtml(1), docknot(1), faq2html(1), App::DocKnot::Spin::Pointer, App::DocKnot::Spin::RSS, App::DocKnot::Spin::Sitemap, App::DocKnot::Spin::Thread, App::DocKnot::Spin::Versions, Pod::Thread
This module is part of the App-DocKnot distribution. The current version of DocKnot is available from CPAN, or directly from its web site at https://www.eyrie.org/~eagle/software/docknot/ π«Ά
Okay that's the whole page, you made it to the end, so proud of you π₯Ή Just so you know which build you're reading: this was perl v5.40.1, dated 2026-01-16, and the manual it lives in is App::D...::Spin(3pm). Periodt. π
β¨
π¦ where this page comes from
- ubuntu resolute: docknot 8.0.1-1build1 Β· MIT
- ubuntu stonking: docknot 8.0.1-1build1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms