lsg.pl (8275B)
1 #!/usr/bin/env perl 2 3 # FIXME: standardize var names (e.g. $pageid, $page) 4 5 # REQUIREMENTS: Text::Markdown 6 7 # lsg.pl - Lumidify Site Generator 8 # Written by lumidify <nobody@lumidify.org> 9 # 10 # To the extent possible under law, the author has dedicated 11 # all copyright and related and neighboring rights to this 12 # software to the public domain worldwide. This software is 13 # distributed without any warranty. 14 # 15 # You should have received a copy of the CC0 Public Domain 16 # Dedication along with this software. If not, see 17 # <http://creativecommons.org/publicdomain/zero/1.0/>. 18 19 use strict; 20 use warnings; 21 use FindBin; 22 use lib "$FindBin::Bin"; 23 use LSG; 24 25 my $path = $#ARGV >= 0 ? $ARGV[0] : "."; 26 LSG::init($path); 27 LSG::generate_site(); 28 29 __END__ 30 31 =head1 NAME 32 33 lsg.pl - Multilingual static site generator 34 35 =head1 SYNOPSIS 36 37 B<lsg.pl> [directory] 38 39 =head1 OPTIONS 40 41 B<directory> specifies the directory of the source files for the site and 42 defaults the the current directory. 43 44 =head1 DESCRIPTION 45 46 lsg.pl is a simple static site generator that is meant to simplify creating 47 multilingual sites. 48 49 This documentation is very rudimentary at the moment and the whole generator 50 should really be rewritten at some point anyways. Contact me if you need help 51 deciphering the meaning of the words written here. 52 53 Do note that the code constituting this piece of software is not something 54 to be proud of. 55 56 =head1 FILES 57 58 =over 8 59 60 =item B<config.ini> 61 62 The configuration for the site, see L</"CONFIGURATION">. 63 64 =item B<modified_dates> 65 66 A list of the timestamps of the source files for the site pages, in order 67 to check which ones need to be regenerated (this is automatically generated) 68 69 =item B<pages> 70 71 The directory containing the source files for the site pages. 72 73 =item B<templates> 74 75 The directory containing the templates for the pages. 76 77 =item B<site> 78 79 The generated html pages. 80 81 =item B<site/static> 82 83 The directory containing static files such as images. 84 85 =back 86 87 =head1 CONFIGURATION 88 89 The configuration file uses the INI format. There are currently only a few 90 options: 91 92 =over 8 93 94 =item B<langs> 95 96 Specifies the languages and their display names, e.g. "en=English". 97 98 =item B<lang_dirs> 99 100 Specifies the directions of the scripts the languages are written in 101 (ltr or rtl). This is currently not used anywhere (I think?) but may 102 come in handy someday. 103 104 =item B<nav> 105 106 This is outside the INI sections and just specifies the files that 107 are supposed to be in the navigation menu, separated by colons. 108 109 =back 110 111 See the example site for more information. 112 113 =head1 TEMPLATES 114 115 The templates are simply html files with certain extra syntax 116 parsed by the site generator. Note that backslashes need to be 117 escaped. 118 119 =over 8 120 121 =item B<{var title}> 122 123 Inserts the variable "title" set in the metadata of the page. 124 125 =item B<{block block_name}> 126 127 Starts a block named "block_name" which can be overwritten in 128 child templates. The block named "content" is filled with the 129 actual content from the page after it is converted to HTML. 130 131 =item B<{func func_name}> 132 133 Executes one of the functions from LSG::UserFuncs with the 134 given arguments. Note that the function is executed separately 135 for every page that is generated and can thus be used, for 136 example, to generate relative links to a CSS file. 137 138 =back 139 140 At the very top of a template file, optional metadata can be 141 specified: 142 143 =over 8 144 145 =item B<extends> 146 147 Used to inherit from a parent template. 148 149 =item B<metadata> 150 151 Specifies the required metadata that needs to be specified in 152 each page using this template. 153 154 =back 155 156 See the example site for details. This really isn't very polished, 157 but I'm just trying to document it somewhat reasonably since I 158 probably won't have time to properly rewrite it for a while. 159 160 VERY IMPORTANT: There always needs to be a blank line between the 161 metadata and the rest of the template, even when there is no 162 metadata. A template with no metadata needs a blank line at the 163 top. I could probably change that, but I don't feel like it at 164 the moment. Fight me! 165 166 =head1 PAGES 167 168 The C<pages> directory contains the directory structure as it will 169 be on the website, except that the pages are named "path/to/page.lang", 170 which is changed to "lang/path/to/page.html" on the final website. 171 172 Each page file contains metadata at the top. The minimum required 173 metadata is "template" and "lang", since the template can then specify 174 what metadata is required. "lang" should actually be redundant, but 175 I don't have time to look into why I kept it that way right now... 176 177 When a template named "article" is specified, the actual template that 178 is loaded is "templates/article.lang.html", so a template needs to 179 exist for every language. 180 181 After the metadata, the rest of the file is the content, written in 182 Markdown. All normal Markdown is supported since this just uses 183 Text::Markdown for the parsing. There are some extra features, though. 184 The special link syntax specified below is meant to provide some 185 convenience and allows the site generator to check if the linked 186 files actually exist on the server. The generated links are relative, 187 so the site can also be browsed locally. Link titles, alt text for images, 188 and reference-style links are not supported by this special format, 189 however. 190 191 (note that this was copied out of an old README and not formatted 192 very well for this documentation page) 193 194 B<Links:> 195 196 [Whatever](@.pdf)-> [Whatever](relative/path/to/static/$name_of_page.pdf) 197 198 [Whatever](#bob.pdf) -> [Whatever](relative/path/to/static/bob.pdf) 199 200 [Whatever]($page.en) -> [Whatever](relative/path/to/en/page.html) 201 202 If a link starts with "=", the HTML5 "download" attribute is added to the 203 link so the file is downloaded directly in browsers that support it. 204 This is a hack. 205 206 B<Images:> 207 208 ![Whatever](@.png)-> [Whatever](relative/path/to/static/$name_of_page.png) 209 210 ![Whatever](#bob.png) -> [Whatever](relative/path/to/static/bob.png) 211 212 B<Functions:> 213 214 Functions can be used for more advanced features. They are written using Perl in the file 215 C<LSG/UserFuncs.pm> and can be called from a markdown file as follows: 216 217 C<{name_of_function}(argument1 argument2 argument3)> 218 219 Note: this format may change in the future if more advanced arguments are needed. 220 221 B<sort_books> 222 223 B<Parameters:> 224 225 - directory to take books from 226 227 - mode 228 229 - attribute(s) to sort by 230 231 B<Purpose:> 232 233 Generate sorted list of all pages in the given directory, first by the given attribute(s), 234 which can be anything in the metadata, then by the titles. The mode argument can be used 235 to either just list all books ("list"), list all books with subheadings for the different 236 sorting attributes ("combined"), or generate different pages for the different values of 237 the sorting attributes. Note that the display names for the attributes need to be defined 238 in the configuration file config.ini. For instance, if a page contains metadata 239 "category:stuff", config.ini must contain a section "[category:$lang]" for each language 240 that contains a line "stuff=Display Name". 241 242 This function was created for a book site, but it could probably be used for articles 243 as well. 244 245 Two more functions, C<gen_nav> and C<gen_lang_selector>, are defined, but they are 246 currently only used internally in the templates and probably aren't needed for the 247 actual pages. 248 249 =head1 BUGS 250 251 The C<modified_dates> behavior is buggy - pages should have proper dependency resolution 252 so that pages which call other functions are still updated if the pages they require 253 are modified but the page itself isn't. For instance, if one page has a list of books 254 that is automatically generated, it won't be updated if the books change because the 255 generator doesn't know that this page actually depends on all other pages. As a small 256 workaround, there is now the C<always_update> metadata, so if C<always_update:true> is 257 specified in the metadata, that page will always be updated. 258 259 =head1 SEE ALSO 260 261 Text::Markdown 262 263 =head1 LICENSE 264 265 Written in 2017-2023 by lumidify <nobody[at]lumidify.org> 266 267 To the extent possible under law, the author has dedicated 268 all copyright and related and neighboring rights to this 269 software to the public domain worldwide. This software is 270 distributed without any warranty. 271 272 You should have received a copy of the CC0 Public Domain 273 Dedication along with this software. If not, see 274 <http://creativecommons.org/publicdomain/zero/1.0/>. 275 276 =cut