slweb

Једноставни генератор статичких веб страна
git clone https://git.sr.ht/~strahinja/slweb
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

slweb.1.in (33349B)


      1 .\" This program is licensed under the terms of GNU GPL v3 or (at your option)
      2 .\" any later version. Copyright (C) 2020-2026  Страхиња Радић.
      3 .\" See the file LICENSE for exact copyright and license details.
      4 .Dd %DATE%
      5 .Dt SLWEB 1
      6 .Os
      7 .Sh NAME
      8 .Nm slweb
      9 .Nd Simple static website generator
     10 .Sh SYNOPSIS
     11 .Nm
     12 .Fl h | \-help | Fl V | \-full\-version | Fl v | \-version
     13 .Nm
     14 .Oo Fl b | Fl \-body\-only Oc Oo Fl d Ar directory | Fl \-basedir Ar directory
     15 .Oc Oo Fl p Ar URL | Fl \-global\-link\-prefix Ar URL Oc Op Ar filename
     16 .
     17 .Sh DESCRIPTION
     18 .Nm
     19 is a static website generator which aims at being simplistic.
     20 It transforms custom Markdown\-like syntax into HTML.
     21 .
     22 .Bl -tag -width Ds
     23 .It Fl b , Fl \-body\-only
     24 Only add the contents of the
     25 .Ql <body>
     26 tag, skipping
     27 .Ql <html>
     28 and
     29 .Ql <head> .
     30 .It Fl d Ar directory , Fl \-basedir Ar directory
     31 Set the base directory for image file paths to pass to
     32 .Xr identify 1 ,
     33 includes
     34 .Pf "(" Ql {include}
     35 and
     36 .Ql {incdir} )
     37 and favicons.
     38 Defaults to the current directory
     39 .Pf "(" Dq "." Ns
     40 ).
     41 .It Fl h , Fl \-help
     42 Print the usage information screen.
     43 .It Fl p Ar URL , Fl \-global\-link\-prefix Ar URL
     44 Set
     45 .Ar URL
     46 as a global prefix for relative links.
     47 .It Fl V , Fl \-full\-version
     48 Print full version (like
     49 .Fl v Ns
     50 ),
     51 followed by copyright notice, and exit.
     52 .It Fl v , Fl \-version
     53 Print program version and commit date, and exit.
     54 .El
     55 .
     56 Files processed by
     57 .Nm
     58 are using a minimal subset of Markdown with added directives.
     59 .
     60 .Ss Supported Markdown features
     61 .
     62 .Bl -bullet -width 1m
     63 .It
     64 .Sy Backticks .
     65 Text inside
     66 .Ql `backticks`
     67 will be put inside
     68 .Ql <code></code> .
     69 Text surrounded by triple backticks
     70 .Pf "(" Ql "```" )
     71 on the lines by themselves will be put inside
     72 .Ql <pre></pre> .
     73 Any
     74 .Dq less\-than
     75 characters inside backticks will be converted to
     76 .Ql &lt;\&
     77 and
     78 .Dq ampersand
     79 characters to
     80 .Ql &amp;\& .
     81 Any text following the first triple backticks until the end of the line will be
     82 ignored.
     83 This is to account for language highlighting specification, which isn't yet
     84 supported.
     85 .
     86 .It
     87 .Sy Blockquotes .
     88 Starting the line with
     89 .Ql >
     90 will surround it with a
     91 .Ql <blockquote>
     92 tag.
     93 Multiple lines are supported.
     94 .
     95 .It
     96 .Sy Bold/italic .
     97 Text inside
     98 .Ql *asterisks*
     99 or
    100 .Ql _underlines_
    101 will be put inside
    102 .Ql <em></em> .
    103 Text inside
    104 .Ql **double asterisks**
    105 or
    106 .Ql __double underlines__
    107 will be put inside
    108 .Ql <strong></strong> .
    109 .Ql ***More than two***
    110 of the
    111 .Ql ___same symbol___
    112 should be avoided.
    113 .
    114 .It
    115 .Tg Break_marks
    116 .Sy Break marks .
    117 To address combinations of lists and
    118 .Dq raw
    119 tags, which are problematic to mix together,
    120 .Nm
    121 supports explicitly marking a tag with a
    122 .Dq break mark .
    123 This currently means that when such a tag is introduced, any running list item
    124 and list will be closed prior to outputting the tag.
    125 Tags with break marks are introduced by prepending the exclamation mark to the
    126 tag name.
    127 For example, without a break mark, the input:
    128 .Bd -literal -offset Ds
    129 - Some list
    130 {break-here}
    131 .Ed
    132 .Pp
    133 produces the following output:
    134 .Bd -literal -offset Ds
    135 <ul><li><p>Some list
    136 <break-here></li></ul>
    137 .Ed
    138 .Pp
    139 When changed to:
    140 .Bd -literal -offset Ds
    141 - Some list
    142 {!break-here}
    143 .Ed
    144 .Pp
    145 .Nm
    146 will output:
    147 .Bd -literal -offset Ds
    148 <ul><li><p>Some list
    149 </li></ul>
    150 <break-here>
    151 .Ed
    152 .Pp
    153 Same for end tags:
    154 .Bd -literal -offset Ds
    155 {dl}{dt}{p}Introduction{/dt}
    156 {dd}
    157 - One
    158 - Two
    159 {/dd}{/dl}
    160 .Ed
    161 .Pp
    162 produces:
    163 .Bd -literal -offset Ds
    164 <dl><dt><p>Introduction</dt>
    165 <dd>
    166 <ul><li><p>One
    167 </li>
    168 <li><p>Two
    169 </dd></dl></li></ul>
    170 .Ed
    171 .Pp
    172 while
    173 .Bd -literal -offset Ds
    174 {dl}{dt}{p}Introduction{/dt}
    175 {dd}
    176 - One
    177 - Two
    178 {/!dd}{/dl}
    179 .Ed
    180 .Pp
    181 produces:
    182 .Bd -literal -offset Ds
    183 <dl><dt><p>Introduction</dt>
    184 <dd>
    185 <ul><li><p>One
    186 </li>
    187 <li><p>Two
    188 </li></ul>
    189 </dd></dl>
    190 .Ed
    191 .It
    192 .Sy Footnotes (regular and inline) .
    193 Two-part regular footnotes can be added in a manner similar to links (see
    194 .Sx Links Ns
    195 ).
    196 Inline footnotes are also supported.
    197 .Bl -dash -width 1m
    198 .It
    199 .Tg Regular_footnotes
    200 .Sy Regular footnotes
    201 have two mandatory parts: first, the footnote mark is represented by
    202 .Ql [^ Ns Ar footnoteid Ns \[rB] ,
    203 where
    204 .Ar footnoteid
    205 is the footnote identifier.
    206 Second, the text of the footnote is represented by
    207 .Ql [^ Ns Ar footnoteid Ns \[rB] : Ar sometext ,
    208 with
    209 .Ar sometext
    210 being the text of the footnote.
    211 Footnote text construct needs to begin at the start of a line, and it is the
    212 most practical to have it placed near the bottom of the file, similar to normal
    213 links.
    214 .Pp
    215 Combined, the input:
    216 .Bd -literal -offset Ds
    217 This is a text[^first].
    218 
    219 [^first]: With a footnote!
    220 .Ed
    221 .Pp
    222 gives (some lines are wrapped for this manual):
    223 .Bd -literal -offset Ds
    224 <p>This is a text<a href="#footnote-1" id="footnote-text-1">
    225 <sup>1</sup></a>.
    226 
    227 <hr>
    228 <p id="footnote-1"><a href="#footnote-text-1">1.</a>
    229 With a footnote!
    230 .Ed
    231 .It
    232 .Tg Inline_footnotes
    233 .Sy Inline footnotes
    234 can be added by using the construct
    235 .Ql ^[ Ns Ar footnotetext Ns \[rB] .
    236 For example, input
    237 .Bd -literal -offset Ds
    238 Inline footnote^[Footnote text] in a paragraph.
    239 .Ed
    240 .Pp
    241 will produce
    242 .Bd -literal -offset Ds
    243 Inline footnote<a href="#inline-footnote-1"
    244 id="inline-footnote-text-1"><sup>1</sup></a> in a
    245 paragraph.
    246 <hr>
    247 <p id="inline-footnote-1"><a href="#inline-footnote-text-1">
    248 1.</a> Footnote text
    249 .Ed
    250 .Pp
    251 The horizontal rule and the list of footnotes is output only once, before the
    252 end of HTML document body.
    253 Rule and the list of footnotes can be surrounded by a div with the
    254 .Dq Dv footnotes
    255 id by setting the YAML variable
    256 .Va add-footnote-div
    257 to
    258 .Dq 1
    259 (see
    260 .Sx add-footnote-div Ns
    261 ).
    262 .Pp
    263 Inline and regular footnotes can be used at the same time, but they don't share
    264 the numbering.
    265 This doesn't affect functionality, but it does affect presentation, as some
    266 footnote numbers will overlap.
    267 As a result, whenever
    268 .Nm
    269 encounters both footnote types in the same document, a warning will be issued to
    270 .Pa stderr .
    271 .El
    272 .It
    273 .Sy Headings .
    274 A line starting with
    275 .Ql #
    276 followed by space will be put inside
    277 .Ql <h?></h?> ,
    278 where
    279 .Ql ?\&
    280 stands for 1-4, depending on the number of hash signs.
    281 Tags will have
    282 .Cm id
    283 attributes set to
    284 .Ql heading-?\& ,
    285 with
    286 .Ql ?\&
    287 set to the number representing its position within the list of all headings.
    288 .It
    289 .Tg Horizontal_rules
    290 .Sy Horizontal rules .
    291 Three dashes at the start of the line will produce a
    292 .Ql <hr>
    293 in the output.
    294 As this Markdown feature clashes with YAML block boundaries, it will work only
    295 if YAML block is present in the input and before the three dashes for the
    296 horizontal rule.
    297 Any text following the three dashes on the same line will be ignored.
    298 .Pp
    299 Alternatively, three asterisks
    300 .Pq Ql "***"
    301 can be used instead of dashes, avoiding the necessity for a YAML block preceding
    302 the asterisks.
    303 .It
    304 .Sy Images .
    305 Similar to links (see
    306 .Sx Links Ns
    307 ),
    308 images can be added by using:
    309 .Bd -literal -offset Ds
    310 ![Some title](/path/to/image.png)
    311 .Ed
    312 .Pp
    313 Which will produce:
    314 .Bd -literal -offset Ds
    315 <figure>
    316 <a href="/path/to/image.png" title="Some title" class="image"
    317   target="_blank"><img src="/path/to/image.png" alt="Some title"
    318   width="100" height="50" ></a><figcaption>Some title</figcaption>
    319 </figure>
    320 .Ed
    321 .Pp
    322 The attributes
    323 .Cm width
    324 and
    325 .Cm height
    326 will be determined automatically using the command
    327 .Xr identify 1
    328 (if present), provided the
    329 .Cm src
    330 attribute contains a valid file path. (Also see
    331 .Va image-file-prefix Ns ).
    332 .Pp
    333 As with links, a form similar to the
    334 .Dq regular form
    335 of links can also be used, using the image id instead of the direct URL.
    336 .Pp
    337 If the additional link or
    338 .Ql <figure> Ns
    339 .Pf / Ns Ql <figcaption>
    340 tags are not desirable, they can be turned off by setting
    341 .Va add-image-links
    342 and
    343 .Va add-figcaption
    344 to
    345 .Dq 0 .
    346 .It
    347 .Tg Keyboard_tags
    348 .Sy Keyboard tags .
    349 Text inside
    350 .Ql ||double bars||\&
    351 will be put inside
    352 .Ql <kbd></kbd>
    353 tags.
    354 As with backticks, any
    355 .Dq less\-than
    356 character will be converted to
    357 .Ql &lt;\& .
    358 .It
    359 .Tg Line_breaks
    360 .Sy Line breaks .
    361 Two spaces followed by a newline will become
    362 .Ql <br> .
    363 .It
    364 .Sy Links .
    365 .Bl -dash -width 1m
    366 .It
    367 .Sy Inline links .
    368 The construct
    369 .Ql [A link](https://example.com)
    370 will be converted into
    371 .Ql <a href="https://example.com">A link</a> .
    372 .Pp
    373 Special case is the form
    374 .Dl [= Ns Ar somemacro No Link title](https://anything)
    375 which prepends the body of a macro
    376 .Ar somemacro
    377 into the
    378 .Ql <a></a>
    379 tag (here broken into multiple lines for clarity):
    380 .Bd -literal -offset Ds
    381 <a href="https://anything">
    382 <!-- contents of somemacro -->
    383 Link title</a>
    384 .Ed
    385 .Pp
    386 This can, for example, be used to add SVG icons to links.
    387 See
    388 .Sx Macros .
    389 .Pp
    390 Also, the form
    391 .Ql [(Link title)](http://asite.com)
    392 will surround the link title (text between
    393 .Ql <a></a>
    394 tags) with
    395 .Ql <span></span> ,
    396 like so:
    397 .Bd -literal -offset Ds
    398 <a href="http://asite.com"><span>Link title</span></a>
    399 .Ed
    400 .Pp
    401 This allows for separate styling of link text.
    402 It can be combined with the macro\-form:
    403 .Bd -literal -offset Ds
    404 .No [= Ns Ar somemacro No (Link title)](http://asite.com)
    405 .Ed
    406 .Pp
    407 It will prepend the body of a macro
    408 .Ar somemacro
    409 outside of the
    410 .Ql <span></span> :
    411 .Bd -literal -offset Ds
    412 <a href="http://asite.com">
    413 .No <!-- contents of Ar somemacro No -->
    414 <span>Link title</span></a>
    415 .Ed
    416 .Pp
    417 Exception is the form
    418 .Dl [Some text (parenthesized)](https://somelink) ,
    419 which won't output
    420 .Ql <span>
    421 tags, and will simply include the parentheses in the output instead.
    422 This form doesn't apply to macro-form
    423 .Dl [=macro Some (text)](http://link) ,
    424 which will always output
    425 .Ql <span>
    426 tags.
    427 .It
    428 .Sy Regular links .
    429 Everything said about inline links applies to regular links, with the exception
    430 that instead of the parenthesized URL, link text inside brackets should be
    431 followed by link id (different than the
    432 .Cm id
    433 .Em attribute!\& )
    434 inside brackets, and a separate definition of that link id is needed, usually
    435 near the end of input.
    436 .Pp
    437 For example:
    438 .Bd -literal -offset Ds
    439 Here's a link to [my website][mw].
    440 
    441 [mw]: https://mysite.com
    442 .Ed
    443 .Pp
    444 will produce:
    445 .Bd -literal -offset Ds
    446 <p>Here's a link to <a href="https://mysite.com">my website</a>.
    447 .Ed
    448 .Pp
    449 This can help reduce the amount of code in the text of the page.
    450 .El
    451 .It
    452 .Sy Lists .
    453 Lines starting with a dash
    454 .Pf "(" Ql "-" Ns
    455 ),
    456 an asterisk
    457 .Pf "(" Ql "*" )
    458 or lowercase
    459 .Dq o ,
    460 followed by a space, will start an unordered list (if used for the first time)
    461 and start a list item.
    462 Input:
    463 .Bd -literal -offset Ds
    464 Colors are:
    465 
    466 - Red
    467 - Green
    468 - Blue
    469 
    470 and so on.
    471 .Ed
    472 .Pp
    473 will produce:
    474 .Bd -literal -offset Ds
    475 <p>Colors are:
    476 
    477 <ul>
    478 <li><p>Red
    479 </li>
    480 <li><p>Green
    481 </li>
    482 <li><p>Blue
    483 </li></ul>
    484 <p>And so on.
    485 .Ed
    486 .Pp
    487 Indenting a line after a blank line with two spaces will create a paragraph
    488 within the list item, otherwise it will end the list:
    489 .Bd -literal -offset Ds
    490 - This is a text inside a list item.
    491 
    492     Remarkably, this paragraph is as well.
    493 - This is already a second item.
    494 
    495 This is after the list.
    496 .Ed
    497 .Pp
    498 will produce:
    499 .Bd -literal -offset Ds
    500 <ul><li><p>This is a text inside a list item.
    501 <p>Remarkably, this paragraph is as well.
    502 </li>
    503 <li><p>This is already a second item.</li></ul>
    504 <p>This is after the list.
    505 .Ed
    506 .Pp
    507 Lists can't be nested, and the characters inside an existing list which would
    508 otherwise start a list shall just be inserted as-is in the output.
    509 .It
    510 .Tg Non-breaking_hyphen
    511 .Sy Non-breaking hyphen .
    512 Tilde followed by a hyphen
    513 .Pf "(" Ql "~-" )
    514 will insert
    515 .Ql &#8209;\&
    516 in the output.
    517 .It
    518 .Tg Non-breaking_space
    519 .Sy Non-breaking space .
    520 Two consecutive tildes
    521 .Pf "(" Ql "~~" )
    522 will produce
    523 .Ql &nbsp;\&
    524 in the output.
    525 .It
    526 .Sy Paragraphs .
    527 Text surrounded by newlines will be prepended by
    528 .Ql <p>
    529 tag.
    530 See
    531 .Sx Known limitations .
    532 .It
    533 .Sy Strikethrough .
    534 Text surrounded by tildes
    535 .Pf "(" Ql "~" )
    536 will be put inside
    537 .Ql <s></s> .
    538 .It
    539 .Sy Tables .
    540 Lines starting with vertical bars
    541 .Pf "(" Ql "|" )
    542 will be transformed into HTML tables.
    543 The first such line is treated as a header row, second as the alignment
    544 specifier (currently ignored), and the rest regular rows.
    545 Table cells and header cells are specified by additional bar characters.
    546 For example, input:
    547 .Bd -literal -offset Ds
    548 | Month | Jan | Feb | Mar | Apr |
    549 |-------|-----|-----|-----|-----|
    550 | Qty   | 2.35| 1.2 |  8  |  15 |
    551 .Ed
    552 .Pp
    553 will be transformed into:
    554 .Bd -literal -offset Ds
    555 <table>
    556 <thead>
    557 <tr><th> Month </th><th> Jan </th><th> Feb </th><th> Mar </th>
    558 <th> Apr </th></tr>
    559 </thead>
    560 <tbody>
    561 <tr><td> Qty   </td><td> 2.35</td><td> 1.2 </td><td>  8  </td>
    562 <td>  15 </td></tr>
    563 </tbody>
    564 </table>
    565 .Ed
    566 .It
    567 .Tg Partial_tables
    568 .Sy Partial tables
    569 are a modification of Markdown tables, allowing them to be combined with the TSV
    570 or CSV directive.
    571 In order for tables to work with templating, they need two additional lines at
    572 the top and the bottom, to mark the start and the end of the table.
    573 All the lines in partial tables need to start with
    574 .Ql | ,
    575 with only the character following at-mark being different:
    576 .Bd -literal -offset Ds
    577 |@\\------|-----|-----|-----|-----|
    578 {tsv "../tsv/sales" 1}
    579 |@#  $#1 | $#2 | $#3 | $#4 | $#5 |
    580 {/tsv}
    581 |@-------|-----|-----|-----|-----|
    582 {tsv "../tsv/sales"}
    583 |@    $1 | $2  | $3  | $4  | $5  |
    584 {/tsv}
    585 |@/------|-----|-----|-----|-----|
    586 .Ed
    587 .Pp
    588 The rest of the line following the third character in top, bottom and lines
    589 separating header from body is ignored by the parser and is included in this
    590 example only for aesthetic purposes.
    591 See
    592 .Sx TSV/CSV templating .
    593 .It
    594 .Tg Zero_width_space
    595 .Sy Zero width space .
    596 Tilde followed by an exclamation mark
    597 .Pf "(" Ql "~!" )
    598 will produce
    599 .Ql &#8203;\&
    600 in the output.
    601 .El
    602 .
    603 .Ss Math mode
    604 Math mode is supported through KaTeX.
    605 With
    606 .Nm katex
    607 installed, anything between dollar signs
    608 .Pf "(" Ql "$" )
    609 will be transformed into MathML and HTML markup.
    610 To generate display math, use double dollar signs
    611 .Pf "(" Ql "$$" Ns
    612 ).
    613 The text between the dollar signs in both cases should be LaTeX source code, and
    614 is passed to
    615 .Nm katex .
    616 The KaTeX stylesheet is not included, and needs to be included separately
    617 through the
    618 .Va stylesheet
    619 or
    620 .Va inline-stylesheet
    621 YAML variables (see
    622 .Sx stylesheet ,
    623 .Sx inline-stylesheet Ns
    624 ).
    625 .
    626 .Ss Directives
    627 .Bl -bullet -width 1m
    628 .It
    629 .Tg Brand_watermark
    630 .Bf Sy
    631 Brand
    632 .Dq watermark Ns
    633 .Ef
    634 \&.
    635 Directive
    636 .Ql {made\-by}
    637 results in a div to be output at the end of the document, with the id
    638 .Ic made\-by
    639 containing the
    640 .Dq watermark
    641 text and a link to the
    642 .Nm
    643 home page.
    644 .It
    645 .Tg General_tags
    646 .Sy General tags .
    647 Directive
    648 .Ql {sometag}{/sometag}
    649 will be transformed into
    650 .Ql <sometag></sometag> .
    651 .It
    652 .Tg Class_attributes
    653 .Sy Class attributes .
    654 Directive
    655 .Ql {tag.myclass mysecondclass}{/tag}
    656 will be transformed into
    657 .Ql <tag class="myclass mysecondclass"></tag> .
    658 Only one class attribute is permitted per tag directive (subsequent dots will be
    659 inserted as part of the
    660 .Cm class
    661 attribute), but you can include multiple classes by separating them with a
    662 space, just like in HTML, and you can have both a class attribute and an id
    663 attribute per tag.
    664 .Pp
    665 A variation of this is to use a special form
    666 .Ql {.myclass}{/.myclass} ,
    667 which will be transformed into
    668 .Ql <div class="myclass"></div> .
    669 .It
    670 .Tg Id_attributes
    671 .Sy Id attributes .
    672 Directive
    673 .Ql {tag#myid}{/tag}
    674 will be transformed into
    675 .Ql <tag id="myid"></tag> .
    676 Only one id attribute is permitted per tag directive (subsequent hash signs will
    677 be included as part of the
    678 .Cm id
    679 attribute), and you can have both an id attribute and a class attribute per tag.
    680 .Pp
    681 A variation of this is to use a special form
    682 .Ql {#myid}{/#myid} ,
    683 which will be transformed into
    684 .Ql <div id="myid"></div> .
    685 .It
    686 .Sy Includes .
    687 Directive
    688 .Ql {include \&"somefile"}
    689 will fork, parse
    690 .Pa somefile.slw
    691 (related to
    692 .Pa basedir )
    693 and output the resulting HTML as if the option
    694 .Fl \-body\-only
    695 was specified.
    696 All YAML variables will be preserved.
    697 .It
    698 .Sy Macros .
    699 Macros can be declared using the directive
    700 .Ql {=! Ns Ar macroname Ns }{/=! Ns Ar macroname Ns } ,
    701 where
    702 .Ar macroname
    703 is the name of the macro.
    704 Anything between those two tags will then become the body of a macro.
    705 Whenever
    706 .Ql {= Ns Ar macroname Ns }
    707 is subsequently encountered in the file, it will be replaced by the macro body.
    708 Macro definitions can't be nested nor can they contain macro calls, and doing so
    709 will produce an error.
    710 Tags won't be processed within the body of a macro.
    711 .It
    712 .Tg Previous_Git_commit_information
    713 .Sy Previous Git commit information .
    714 Directive
    715 .Ql {git\-log}
    716 is converted into a div with the id
    717 .Ql git-log
    718 containing the information about the previous commit (as having information
    719 about the current commit would be impossible).
    720 .It
    721 .Tg Subdirectory_inclusion
    722 .Sy Subdirectory inclusion (blogging directive) .
    723 The directive
    724 .Bd -literal -offset Ds
    725 .Pf { Ns Ic incdir Qo Ar dirname Qc Oo Ar num Oc Oo Cm = Ns Ar macroname Oc Oo Cm listonly Oc Ns }
    726 .Ed
    727 .Pf "(" Ar num ,
    728 .Ar macroname
    729 and the literal
    730 .Ql Cm listonly
    731 are optional) will be expanded as follows:
    732 .Bl -enum -offset Ds
    733 .It
    734 A
    735 .Ql <ul class="incdir">
    736 tag will be inserted into the document instead of the directive.
    737 .It
    738 For every subdirectory of
    739 .Ar dirname ,
    740 relative to current directory and up to
    741 .Ar num
    742 (if present) or 5 (if omitted) total subdirectories, a
    743 .Ql <li>
    744 tag will be inserted into the
    745 .Ql ul
    746 tag.
    747 .Pp
    748 If the parameter
    749 .Cm listonly
    750 was specified, a
    751 .Ql <li>
    752 tag will instead be inserted for every
    753 .Pa .slw
    754 file within each of the subdirectories, sorted in reverse lexicographical order.
    755 In this case, each
    756 .Ql <li>
    757 will contain a permalink with a title preceded by a timestamp formatted
    758 according to
    759 .Va list_timestamp_format .
    760 Title and date are read from each
    761 .Pa .slw
    762 file, as YAML variables
    763 .Va title
    764 and
    765 .Va date .
    766 For this case, processing of the
    767 .Ic incdir
    768 directive stops here.
    769 .It
    770 A
    771 .Ql <details>
    772 tag will be inserted into each
    773 .Ql <li>
    774 tag.
    775 .It
    776 Inside of the
    777 .Ql <details>
    778 tag, a
    779 .Ql <summary>
    780 tag will be inserted with the name of the subdirectory.
    781 If
    782 .Ar macroname
    783 is present, the name of the subdirectory will be prepended with the body of a
    784 macro
    785 .Ar macroname
    786 (for example, this can be used to include custom SVG markup as arrows).
    787 .It
    788 After
    789 .Ql <summary>
    790 tag, a
    791 .Ql <div>
    792 tag will be inserted into
    793 .Ql <details> ,
    794 containing the concatenated output from processing each of the
    795 .Pa .slw
    796 files inside that subdirectory in reverse lexicographical order, in a manner
    797 similar to the
    798 .Ic include
    799 directive.
    800 (See
    801 .Sx Includes
    802 and
    803 .Sx date ,
    804 .Sx ext-in-permalink ,
    805 .Sx permalink-url
    806 variables.)
    807 The output of each file will be surrounded by an
    808 .Ql <article>
    809 tag.
    810 .El
    811 .Pp
    812 If the included file has the variable
    813 .Va incdir-only-summary
    814 set to
    815 .Dq 1 ,
    816 only the text within the summary marks
    817 .Pf "(" Ql /-
    818 and
    819 .Ql "-/" )
    820 will be output, and if the variable
    821 .Va incdir-footer-permalink-text
    822 is also set,
    823 .Ql <footer>
    824 element with a permalink to the article will be added after it.
    825 Example:
    826 .Pp
    827 .Pf "(" Pa posts/blog-post.slw )
    828 .Bd -literal -offset Ds
    829 ---
    830 incdir-only-summary: 1
    831 ---
    832 
    833 /-This article is great!-/ The quick brown fox jumps over the lazy sleeping dog.
    834 The quick brown fox jumps over the lazy sleeping dog. The quick brown fox jumps
    835 over the lazy sleeping dog. The quick brown fox jumps over the lazy sleeping
    836 dog. The quick brown fox jumps over the lazy sleeping dog. The quick brown fox
    837 jumps over the lazy sleeping dog.
    838 .Ed
    839 .Pp
    840 .Pf "(" Pa blog-index.slw )
    841 .Bd -literal -offset Ds
    842 ---
    843 incdir-footer-permalink-text: Click here!
    844 ---
    845 {incdir "."}
    846 .Ed
    847 .Pp
    848 will produce
    849 .Bd -literal -offset Ds
    850 <!DOCTYPE html>
    851 <html lang="en">
    852 <head>
    853 <title></title>
    854 <meta charset="utf-8">
    855 <meta name="viewport" content="width=device-width, initial-scale=1">
    856 <meta name="generator" content="slweb">
    857 </head>
    858 <body>
    859 <ul class="incdir">
    860 <li>
    861 <details open>
    862 <summary>posts</summary>
    863 <div>
    864 <article>
    865 This article is great!<footer>
    866 <a href="././posts/blog-post">Click here!</a>
    867 </footer>
    868 </article>
    869 </div>
    870 </details>
    871 </li>
    872 </ul>
    873 </body>
    874 </html>
    875 .Ed
    876 .Pp
    877 for
    878 .Pa blog-index.slw ,
    879 and
    880 .Bd -literal -offset Ds
    881 <!DOCTYPE html>
    882 <html lang="en">
    883 <head>
    884 <title></title>
    885 <meta charset="utf-8">
    886 <meta name="viewport" content="width=device-width, initial-scale=1">
    887 <meta name="generator" content="slweb">
    888 </head>
    889 <body>
    890 
    891 <p>This article is great! The quick brown fox jumps over the lazy sleeping dog.
    892 The quick brown fox jumps over the lazy sleeping dog. The quick brown fox jumps
    893 over the lazy sleeping dog. The quick brown fox jumps over the lazy sleeping
    894 dog. The quick brown fox jumps over the lazy sleeping dog. The quick brown fox
    895 jumps over the lazy sleeping dog.
    896 </body>
    897 </html>
    898 .Ed
    899 .Pp
    900 for
    901 .Pa posts/blog-post.slw .
    902 .It
    903 .Tg TSV/CSV_templating
    904 .Sy TSV/CSV templating .
    905 Directive
    906 .Bd -literal -offset Ds
    907 .Pf { Ns Ic tsv Qo Ar tsvfile Qc Oo Ar iter Oc Ns }{/ Ns Ic tsv Ns }
    908 .Ed
    909 marks a template.
    910 Whatever is between
    911 .Ql {tsv}
    912 and
    913 .Ql {/tsv}
    914 will be processed by
    915 .Nm
    916 and collected as a template.
    917 Afterwards, file
    918 .Pa tsvfile.tsv
    919 will be read and for each of its lines (up to
    920 .Ar iter ,
    921 if present) the collected template will be output, substituting each occurrence
    922 of a register mark
    923 .Ql $ Ns Ar n
    924 (where
    925 .Ar n
    926 is between 1 and 9, inclusive) with the corresponding TSV field of the read
    927 line.
    928 .Pp
    929 All of this applies to the similar
    930 .Ql {csv}
    931 directive for CSV files.
    932 In the case of CSV files, they need to use semicolons
    933 .Pf "(" Do ";" Dc Ns )
    934 or commas
    935 .Pf "(" Do "," Dc Ns )
    936 as delimiters (or set
    937 .Sx csv-delimiter
    938 as a YAML variable in the calling
    939 .Pa .slw
    940 file) and double quotation marks
    941 .Pf "(" Ql "\(dq" )
    942 as field boundaries.
    943 First line in the TSV file is parsed as a header and associated with register
    944 marks
    945 .Ql $#1
    946 to
    947 .Ql $#9 .
    948 The symbol
    949 .Ql $
    950 is represented as
    951 .Ql $$ .
    952 Consequently, math modes (both inline and display) cannot be used within
    953 templates.
    954 .Pp
    955 Parts of the template can be conditionally rendered by using the construct:
    956 .Bd -literal -offset Ds
    957 .No $? Ns Ar n
    958 .No    <!-- code to include if $ Ns Ar n No nonempty -->
    959 $?!
    960 .No    <!-- code to include if $ Ns Ar n No empty -->
    961 $?/
    962 .Ed
    963 .Pp
    964 where
    965 .Ar n
    966 is between 1 and 9, inclusive.
    967 For example, having a file
    968 .Pa sales.tsv :
    969 .Bd -literal -offset Ds
    970 Item	Q1 2020	Q2 2020	Q3 2020	Q4 2020
    971 Toothpick	15.2	12		10
    972 Teapot	1.2		5	3.5
    973 .Ed
    974 .Pp
    975 We can write
    976 .Bd -literal -offset Ds
    977 {tsv "sales"}
    978 {.sales-segment}
    979 $#1 {q}$1{/q} sales by quarter for the last year in
    980 thousands of units sold (for $$) were as follows:
    981 $?2{.q1}$2{/.q1}$?!{.q1 na}N/A{/.q1}$?/
    982 $?3{.q2}$3{/.q2}$?!{.q2 na}N/A{/.q2}$?/
    983 $?4{.q3}$4{/.q3}$?!{.q3 na}N/A{/.q3}$?/
    984 $?5{.q4}$5{/.q4}$?!{.q4 na}N/A{/.q4}$?/
    985 {/.sales-segment}
    986 {/tsv}
    987 .Ed
    988 .Pp
    989 to get:
    990 .Bd -literal -offset Ds
    991 <div class="sales-segment">
    992 Item <q>Toothpick</q> sales by quarter for the last year in
    993 thousands of units sold (for $) were as follows:
    994 <div class="q1">15.2</div>
    995 <div class="q2">12</div>
    996 <div class="q3 na">N/A</div>
    997 <div class="q4">10</div>
    998 </div>
    999 
   1000 <div class="sales-segment">
   1001 Item <q>Teapot</q> sales by quarter for the last year in
   1002 thousands of units sold (for $) were as follows:
   1003 <div class="q1">1.2</div>
   1004 <div class="q2 na">N/A</div>
   1005 <div class="q3">5</div>
   1006 <div class="q4">3.5</div>
   1007 </div>
   1008 .Ed
   1009 .Pp
   1010 TSV directives can't be nested and doing so will produce an error.
   1011 .Pp
   1012 The directives
   1013 .Ql {csv\-count Qo Ar csvfile Qc Ns }
   1014 and
   1015 .Ql {tsv\-count Qo Ar tsvfile Qc Ns }
   1016 output the number of
   1017 .Dq records
   1018 in the file
   1019 .Pa csvfile.csv
   1020 or
   1021 .Pa tsvfile.tsv
   1022 (number of lines minus one for the header row).
   1023 No newline is output following the number.
   1024 .El
   1025 .
   1026 .Ss Special YAML variables
   1027 .Bl -bullet -width 1m
   1028 .It
   1029 .Va add-article-header .
   1030 If set to
   1031 .Dq 1 ,
   1032 title, date and header text at the beginning of the output body will be enclosed
   1033 in a
   1034 .Ql <header>
   1035 tag.
   1036 .It
   1037 .Va add-figcaption .
   1038 If set to
   1039 .Dq 0 ,
   1040 .Ql <figure>
   1041 and
   1042 .Ql <figcaption>
   1043 tags around images will not be added (otherwise they will by default, see
   1044 .Sx Images Ns
   1045 ).
   1046 .It
   1047 .Va add-footnote-div .
   1048 If set to
   1049 .Dq 1 ,
   1050 list of footnotes preceded by a horizontal rule will be surrounded with a div
   1051 having the id
   1052 .Dq footnotes
   1053 (see
   1054 .Sx Footnotes Ns
   1055 ).
   1056 .It
   1057 .Va add-image-links .
   1058 If set to
   1059 .Dq 0 ,
   1060 links around images will not be added (otherwise they will by default, see
   1061 .Sx Images Ns
   1062 ).
   1063 .It
   1064 .Va author .
   1065 If set, the contents of this variable will be added to the start of the output
   1066 body (inside a
   1067 .Ql <header>
   1068 tag if it is set), surrounded by
   1069 .Ql <address></address> .
   1070 .It
   1071 .Va canonical .
   1072 Contents of this variable will be added as a value of a
   1073 .Ql rel
   1074 attribute for the
   1075 .Ql <link rel="canonical">
   1076 tag.
   1077 .It
   1078 .Va csv-delimiter .
   1079 Changes the delimiter used for
   1080 .Pa .csv
   1081 file parsing.
   1082 By default, this will be a semicolon\ 
   1083 .Pf "(" Ns Ql ";" Ns
   1084 ).
   1085 See
   1086 .Sx TSV/CSV templating .
   1087 .It
   1088 .Va date .
   1089 If present, this variable, assumed to be in ISO\ 8601 UTC datetime format, will
   1090 be parsed to determine the timestamp in permalinks generated by the
   1091 .Ic incdir
   1092 directive.
   1093 The actual values used depend on the source\-level constants
   1094 .Va article_timestamp_format
   1095 (for
   1096 .Ic incdir
   1097 without the argument
   1098 .Cm listonly )
   1099 and
   1100 .Va list_timestamp_format
   1101 (for
   1102 .Ic incdir
   1103 with the argument
   1104 .Cm listonly Ns ).
   1105 .It
   1106 .Va ext-in-permalink .
   1107 If set to
   1108 .Dq 0 ,
   1109 permalinks generated by the
   1110 .Ic incdir
   1111 directive will not have the extension included in the
   1112 .Cm href
   1113 attribute.
   1114 For example, instead of
   1115 .Pa blog/2020/august.html ,
   1116 the resulting permalink will have
   1117 .Pa blog/2020/august .
   1118 .It
   1119 .Va favicon-url .
   1120 If present, this URL will be used as a favicon URL instead of the default,
   1121 .Pa /favicon.ico .
   1122 .It
   1123 .Va feed ,
   1124 .Va feed-type ,
   1125 .Va feed-desc .
   1126 If all are present, contents of those variables will be added as
   1127 .Cm href ,
   1128 .Cm type
   1129 and
   1130 .Cm title
   1131 attributes (respectively) to the
   1132 .Ql <link rel="alternate">
   1133 tag in the page's
   1134 .Ql <head> .
   1135 .It
   1136 .Va header-text .
   1137 The contents of this variable will be added to the start of the output body
   1138 (inside a
   1139 .Ql <header>
   1140 tag if it is set), preceeded by
   1141 .Ql <p> .
   1142 .It
   1143 .Va image-file-prefix .
   1144 If present, the value of
   1145 .Cm src
   1146 attribute will be appended to the contents of this variable, with path separator
   1147 added as necessary, when determining the actual file path to pass to the
   1148 .Xr identify 1
   1149 command.
   1150 Otherwise,
   1151 .Cm src
   1152 is appended to the base directory, specified by the parameter
   1153 .Fl d
   1154 (or
   1155 .Fl \-basedir Ns ),
   1156 and defaulting to
   1157 .Dq .\& .
   1158 .It
   1159 .Va incdir-footer-permalink-text .
   1160 If set, and the variable
   1161 .Va incdir-only-summary
   1162 is set to
   1163 .Dq 1 ,
   1164 when the file where this variable is set is included by the
   1165 .Ql {incdir}
   1166 directive,
   1167 .Ql <footer>
   1168 tag containing the permalink to the calling file will be appended to the text
   1169 between the summary marks
   1170 .Ql /-
   1171 and
   1172 .Ql -/ .
   1173 .It
   1174 .Va incdir-only-summary .
   1175 If set to
   1176 .Dq 1 ,
   1177 when the file where this variable is set is included by the
   1178 .Ql {incdir}
   1179 directive, only the text within the summary marks
   1180 .Ql /-
   1181 and
   1182 .Ql -/
   1183 will be output.
   1184 .It
   1185 .Va inline-stylesheet .
   1186 The contents of this variable will be treated as a CSS file name to be included
   1187 inline in the header using the
   1188 .Ql <style>
   1189 tag.
   1190 You can add more than one
   1191 .Va inline-stylesheet
   1192 declaration per
   1193 .Pa .slw
   1194 file.
   1195 .It
   1196 .Va lang .
   1197 Contents of this variable will be used for the
   1198 .Cm lang
   1199 attribute of the
   1200 .Ql <html>
   1201 tag.
   1202 .It
   1203 .Va link-prefix .
   1204 This variable specifies the prefix which will be prepended to relative URLs in
   1205 links.
   1206 Final slash needs to be included if
   1207 .Va link-prefix
   1208 is a complete path.
   1209 .It
   1210 .Va meta .
   1211 Contents of this variable is treated as a filename specifying the TSV file
   1212 containing a list of values to be inserted into meta tags.
   1213 The first row of this TSV file is treated as the header row and ignored.
   1214 First column in this TSV file contains the meta variable names, and the second
   1215 column contains meta variable values.
   1216 For each row, a
   1217 .Ql <meta name= Ns Qo Ar firstcol Qc content= Ns Qo Ar secondcol Qc Ns >
   1218 is inserted, where
   1219 .Ar firstcol
   1220 is the first column, and
   1221 .Ar secondcol
   1222 is the second column.
   1223 If the values in the second column are surrounded with percent signs
   1224 .Pf "(" Ns Ql % Ns
   1225 ), the value between them is treated as the name of the
   1226 YAML variable to insert.
   1227 For example, having the file
   1228 .Pa m.tsv :
   1229 .Bd -literal -offset Ds
   1230 Name	Content
   1231 og:url	%canonical%
   1232 .Ed
   1233 .Pp
   1234 and
   1235 .Bd -literal -offset Ds
   1236 ---
   1237 canonical: https://example.com/
   1238 meta: m.tsv
   1239 ---
   1240 .Ed
   1241 .Pp
   1242 in the
   1243 .Pa .slw
   1244 file, a
   1245 .Bd -literal -offset Ds
   1246 <meta name="og:url" content="https://example.com/">
   1247 .Ed
   1248 .Pp
   1249 line will be added to the output.
   1250 .It
   1251 .Va permalink-url .
   1252 If present, this URL will completely replace the link used in the
   1253 .Cm href
   1254 attribute of permalinks generated by the
   1255 .Ic incdir
   1256 directive.
   1257 This variable is more useful in individual
   1258 .Pa .slw
   1259 files inside the subdirectories of the
   1260 .Ar dirname
   1261 provided to the
   1262 .Ic incdir
   1263 directive.
   1264 .It
   1265 .Va site-desc .
   1266 The contents of this variable will be inserted as the value of the
   1267 .Cm content
   1268 attribute of the
   1269 .Ql <meta name="description">
   1270 tag.
   1271 .It
   1272 .Va site-name .
   1273 The contents of this variable will be inserted inside the
   1274 .Ql <title></title>
   1275 tags.
   1276 .It
   1277 .Va stylesheet .
   1278 The contents of this variable will be treated as a CSS file name to be included
   1279 using the
   1280 .Ql <link rel="stylesheet">
   1281 tag.
   1282 You can add more than one
   1283 .Va stylesheet
   1284 declaration per
   1285 .Pa .slw
   1286 file.
   1287 .It
   1288 .Va title .
   1289 If present, contents of this variable will be prepended to the body (inside a
   1290 .Ql <header>
   1291 tag if it is set) as a heading with the level determined by the
   1292 .Va title-heading-level
   1293 variable, defaulting to 2.
   1294 .Pf "(" Ns Ql title: Some title
   1295 becomes
   1296 .Ql <h2>Some title</h2> Ns
   1297 ).
   1298 .It
   1299 .Va title-heading-level .
   1300 See
   1301 .Sx title .
   1302 .El
   1303 .
   1304 .Ss Special macros
   1305 .Bl -bullet -width 1m
   1306 .It
   1307 .Ic permalink .
   1308 If present, the body of this macro will be inserted into permalinks generated by
   1309 the
   1310 .Ic incdir
   1311 directive, similar to the macro\-form of links.
   1312 .El
   1313 .
   1314 .Sh EXIT STATUS
   1315 .Ex -std
   1316 .Pp
   1317 For errors caused by the unsuccessful calls to libc functions setting
   1318 .Va errno ,
   1319 that value is returned as the exit status.
   1320 Otherwise, the exit status is one of the following:
   1321 .Bl -tag -width Ds -offset indent -compact
   1322 .It Li 201
   1323 Argument to a function is not numeric.
   1324 .It Li 202
   1325 Argument to a function is not beginning and ending with double quotes (not a
   1326 .Do string Dc Ns ).
   1327 .It Li 203
   1328 Command line argument is not recognized.
   1329 .It Li 204
   1330 Conditional mark is not recognized.
   1331 .It Li 205
   1332 Empty conditional mark is before or without the corresponding nonempty
   1333 conditional.
   1334 .It Li 206
   1335 Header register mark is not recognized.
   1336 .It Li 207
   1337 Register mark is not recognized.
   1338 .It Li 208
   1339 Parsing arguments failed when formatting date.
   1340 .It Li 209
   1341 Macro is not defined.
   1342 .It Li 210
   1343 There are nested CSV/TSV directives.
   1344 .It Li 211
   1345 There are nested macro definitions.
   1346 .It Li 212
   1347 There are nested formulas.
   1348 .It Li 213
   1349 No arguments are supplied to a directive or to a command line argument which
   1350 requires at least one.
   1351 .It Li 214
   1352 The function
   1353 .Xr popen 3
   1354 (which doesn't set
   1355 .Va errno )
   1356 failed.
   1357 .It Li 215
   1358 The function
   1359 .Xr scandir 3
   1360 (which doesn't set
   1361 .Va errno )
   1362 failed.
   1363 .El
   1364 .
   1365 .Sh EXAMPLES
   1366 Given the file
   1367 .Pa index.slw
   1368 in the current directory:
   1369 .Bd -literal -offset Ds
   1370 ---
   1371 site-name: Test website
   1372 site-desc: My first website in slweb
   1373 ---
   1374 
   1375 {main}
   1376 # Hello world
   1377 
   1378 This is an _example_ of a statically generated HTML.
   1379 
   1380 {/main}
   1381 .Ed
   1382 .Pp
   1383 after using the command:
   1384 .Dl $ slweb index.slw > index.html
   1385 file
   1386 .Pa index.html
   1387 contains:
   1388 .Bd -literal -offset Ds
   1389 <!DOCTYPE html>
   1390 <html lang="en">
   1391 <head>
   1392     <title>Test website</title>
   1393     <meta charset="utf-8">
   1394     <meta name="description" content="My first website in slweb">
   1395     <meta name="viewport" content="width=device-width, initial-scale=1">
   1396     <meta name="generator" content="slweb">
   1397 </head>
   1398 <body>
   1399 
   1400 <main>
   1401 <h1>Hello world</h1>
   1402 
   1403 <p>This is an <em>example</em> of a statically generated HTML.
   1404 
   1405 </main>
   1406 </body>
   1407 </html>
   1408 .Ed
   1409 .
   1410 .Sh DIAGNOSTICS
   1411 Error messages output by
   1412 .Nm
   1413 are in the format
   1414 .Bd -ragged -offset Ds
   1415 .Nm : Ns
   1416 .Ar filename : Ns Ar lineno : Ns Ar colno : Ns Ar func : Ns
   1417 .Ar source : Ns Ar line : Ns Ar msg
   1418 .Ed
   1419 .Pp
   1420 where the
   1421 .Ar filename
   1422 is the name of the input file or
   1423 .Ql (init/stdin)
   1424 when no input file is specified or the error happened early on during
   1425 initialization,
   1426 .Ar lineno
   1427 and
   1428 .Ar colno
   1429 are the line and column numbers in the input file where the error occured.
   1430 The arguments
   1431 .Ar func ,
   1432 .Ar source
   1433 and
   1434 .Ar line
   1435 the function, filename and line number in the source code file.
   1436 .Pp
   1437 When the error is caused by an error in the libc function which sets
   1438 .Va errno ,
   1439 .Nm
   1440 calls
   1441 .Xr perror 3
   1442 prior to outputting an error message in the above format.
   1443 .
   1444 .Sh SEE ALSO
   1445 .Xr sed 1
   1446 .
   1447 .Sh AUTHORS
   1448 .An Strahinya Radich Aq Mt sr@strahinja.org ,
   1449 2020\-2026
   1450 .
   1451 .Sh BUGS
   1452 Bugs can be reported using the ticket tracker at:
   1453 .Lk https://\:todo.sr.ht/\:~strahinja/\:slweb
   1454 .
   1455 .Ss Known limitations
   1456 The limitation of Markdown is that there is no clear way to determine where the
   1457 paragraph inside a tag should begin and end.
   1458 Before the addition of
   1459 .Sx Break marks
   1460 and the change of behavior of
   1461 .Nm
   1462 to not output ending
   1463 .Ql </p>
   1464 tags, without adding blank lines or using the
   1465 .Ql {p}{/p}
   1466 notation,
   1467 .Ql <p></p>
   1468 tags in the output would be intertwined together with other tags.
   1469 For example, the code
   1470 .Bd -literal -offset Ds
   1471 {tag}
   1472 First paragraph
   1473 
   1474 Second paragraph
   1475 {/tag}
   1476 .Ed
   1477 .Pp
   1478 would produce
   1479 .Bd -literal -offset Ds
   1480 <tag>
   1481 First paragraph
   1482 
   1483 <p>Second paragraph
   1484 </tag></p>
   1485 .Ed
   1486 .Pp
   1487 One could suppress the paragraph starting/ending tags by prepending blank lines
   1488 with a backslash, like this:
   1489 .Bd -literal -offset Ds
   1490 {tag}
   1491 First paragraph
   1492 \e
   1493 Second paragraph
   1494 {/tag}
   1495 .Ed
   1496 .Pp
   1497 which would produce
   1498 .Bd -literal -offset Ds
   1499 <tag>
   1500 First paragraph
   1501 
   1502 Second paragraph
   1503 </tag>
   1504 .Ed
   1505 .Pp
   1506 Adding blank lines was another option if paragraphs were desired:
   1507 .Bd -literal -offset Ds
   1508 {tag}
   1509 
   1510 First paragraph
   1511 
   1512 Second paragraph
   1513 
   1514 {/tag}
   1515 .Ed
   1516 .Pp
   1517 would produce
   1518 .Bd -literal -offset Ds
   1519 <tag>
   1520 <p>First paragraph</p>
   1521 
   1522 <p>Second paragraph</p>
   1523 </tag>
   1524 .Ed