@@ -4,10 +4,11 @@ @; This file is licensed under the Blue Oak Model License 1.0.0. @(require "scribble-helpers.rkt") @(require (for-label "../pollen.rkt" "../dust.rkt" + "../cache.rkt" "../crystalize.rkt" racket/base racket/contract racket/string txexpr @@ -20,21 +21,22 @@ @defmodule["pollen.rkt" #:packages ()] The file @filepath{pollen.rkt} is implicitly @code{require}d in every template and every @code{#lang pollen} file in the project. It defines the markup for all Pollen documents, and also re-provides -everything provided by @filepath{cache.rkt} and @filepath{crystalize.rkt}. +everything provided by @seclink["cache-rkt"]{@filepath{cache.rkt}} and +@seclink["crystalize-rkt"]{@filepath{crystalize.rkt}}. The @code{setup} module towards the top of the file is used as described in @racketmodname[pollen/setup]. @section{Markup reference} These are the tags that can be used in any of @italic{The Local Yarn}’s Pollen documents (articles, etc). -@defproc[(title [element xexpr?] ...) txexpr?] +@defproc[(title [element xexpr?] ...) txexpr?]{ @margin-note{The @code{title} function is not actually defined in @filepath{pollen.rkt} or anywhere else. In Pollen, any undefined function @tt{title} defaults to @racket[(default-tag-function title)], which is what I want. It is documented here because its presence or absence has side-effects on the display of the article.} @@ -41,47 +43,54 @@ Supplies a title for the document. You can use any otherwise-valid markup within the title tag. Titles are optional; if you don’t specify a title, the article will appear without one. This is a feature! +} -@defproc[(p [element xexpr?] ...) txexpr?] +@defproc[(p [element xexpr?] ...) txexpr?]{ Wrap text in a paragraph. You almost never need to use this tag explicitly; just separate paragraphs by an empty line. Single newlines within a paragraph will be replaced by spaces, allowing you to use @ext-link["https://scott.mn/2014/02/21/semantic_linewrapping/"]{semantic line wrapping}. +} -@defproc[(newthought [element xexpr?] ...) txexpr?] +@defproc[(newthought [element xexpr?] ...) txexpr?]{ An inline style intended for the first few words of the first paragraph in a new section. Applies a “small caps” style to the text. Any paragraph containing a @code{newthought} tag is given extra vertical leading. Rule of thumb: within an article, use either @code{section}/@code{subsection} or @code{newthought} to separate sections of text, but not both. Even better, keep it consistent across articles within a series. -If you just need small caps without affecting the paragraph, use @code{smallcaps}. +If you just need small caps without affecting the paragraph, use @racket[caps]. +} @deftogether[(@defproc[(section [element xexpr?] ...) txexpr?] - @defproc[(subsection [element xexpr?] ...) txexpr?])] + @defproc[(subsection [element xexpr?] ...) txexpr?])]{ Create second- and third-level headings, respectively. This is counting the article's title as the first-level header (even if the current article has no title). -@defproc[(block [element xexpr?] ...) txexpr?] +} + +@defproc[(block [element xexpr?] ...) txexpr?]{ A container for content that should appear grouped together on larger displays. Intended for use in -Series pages, where the template is very minimal. You would want output from -@racket[listing<>-short/articles] to appear inside a @racket[block], but you would want output from -@racket[listing<>-full/articles] to appear outside it (since each article effectively supplies its own +Series pages, where the template is very minimal to allow for more customization. You would want +output from @racket[] to appear inside a @racket[block], but you would want output +from @racket[] to appear outside it (since each article effectively supplies its own block). Only relevant to HTML output. + +} @deftogether[(@defproc[(link [link-id stringish?] [link-text xexpr?]) txexpr?] - @defproc[(url [link-id stringish?] [url string?]) void?])] + @defproc[(url [link-id stringish?] [url string?]) void?])]{ All hyperlinks are specified reference-style. So, to link some text, use the @code{link} tag with an identifier, which can be a string, symbol or number. Elsewhere in the text, use @code{url} with the same identifier to specify the URL: @@ -94,29 +103,35 @@ The @code{url} tag for a given identifier may be placed anywhere in the document, even before it is referenced. If you create a @code{link} for an identifier that has no corresponding @code{url}, a @code{"Missing reference: [link-id]"} message will be substituted for the URL. Conversely, creating a @code{url} that is never referenced will produce no output and no warnings or errors. + +} @deftogether[(@defproc[(figure [image-file string?] [caption xexpr?] ...) txexpr?] - @defproc[(figure-@2x [image-file string?] [caption xexpr?] ...) txexpr?])] + @defproc[(figure-@2x [image-file string?] [caption xexpr?] ...) txexpr?])]{ Insert a block-level image. The @racket[_image-file] should be supplied as a filename only, with no folder names. It is assumed that the image is located inside an @racket[images-folder] within the same folder as the source document. For web output, using @racket[figure-@2x] will produce an image hard-coded to display at half its actual size, or the width of the text block, whichever is smaller. -@defproc[(image-link [image-file string?] [link-text xexpr?] ...) txexpr?] +} + +@defproc[(image-link [image-file string?] [link-text xexpr?] ...) txexpr?]{ Adds a hyperlink to @racket[_image-file], supplied as a filename only with no folder names. It is assumed that the image is located inside an @racket[images-folder] within the same folder as the source document. + +} @deftogether[(@defproc[(fn [fn-id stringish?]) txexpr?] - @defproc[(fndef [fn-id stringish?] [elements xexpr?] ...) txexpr?])] + @defproc[(fndef [fn-id stringish?] [elements xexpr?] ...) txexpr?])]{ As with hyperlinks, footnotes are specified reference-style. In the output, footnotes will be numbered according to the order in which their identifiers are referenced in the source document. Example: @@ -133,14 +148,16 @@ The @code{fndef} for a given id may be placed anywhere in the source document, even before it is referenced. If you create a @code{fn} reference without a corresponding @code{fndef}, a @code{"Missing footnote definition!"} message will be substituted for the footnote text. Conversely, creating a @code{fndef} that is never referenced will produce no output, warning or error. + +} @deftogether[(@defproc[(dialogue [elements xexpr?] ...) txexpr?] @defproc[(say [interlocutor string?] [elements xexpr?] ...) txexpr?] - @defproc[(saylines [interlocutor string?] [elements xexpr?] ...) txexpr?])] + @defproc[(saylines [interlocutor string?] [elements xexpr?] ...) txexpr?])]{ Use these tags together for transcripts of dialogue, chats, screenplays, interviews and so forth. The @racket[saylines] tag is the same as @racket[say] except that within @racket[saylines], linebreaks within paragraphs are preserved. @@ -153,36 +170,39 @@ ◊say["Tavi"]{You also write fiction, or you used to. Do you still?} ◊say["Lorde"]{The thing is, when I write now, it comes out as songs.} } }| -@defproc[(index [#:key key string? ""] [elements xexpr?] ...) txexpr?] +} + +@defproc[(index [#:key key string? ""] [elements xexpr?] ...) txexpr?]{ Creates a bidirectional link between this spot in the document and an entry in the keyword index under @racket[_key]. If @racket[_key] is not supplied, the string contents of @racket[_elements] are -used as the key. +used as the key. Use @tt{!} to split @racket[_key] into a main entry and a subentry. The example below will create two index entries, one under the heading “compassion” and one under -the heading “cats”: +the main heading "cats" and a subheading “stray”: @codeblock|{ #lang pollen “I have a theory which I suspect is rather immoral,” Smiley went on, more lightly. “Each of us has only a quantum of ◊index{compassion}. That if we lavish our concern on every - stray ◊index[#:key "cats"]{cat} we never get to the centre of - things. What do you think of it?” + stray ◊index[#:key "cats!stray"]{cat} we never get to the + centre of things. What do you think of it?” }| + +} @defproc[(note [#:date date-str non-empty-string?] [#:author author string? ""] [#:author-url author-url string? ""] - [#:disposition disp-str string? ""]) txexpr?] + [#:disposition disp-str string? ""]) txexpr?]{ -Add a note to the “Further Notes” section of the article. Notes are like blog comments but are -more rare and powerful; see @wiki{Differences from blogs}. +Add a @tech{note} to the “Further Notes” section of the article. The @code{#:date} attribute is required and must be of the form @tt{YYYY-MM-DD}. The @code{#:author} and @code{#:author-url} attributes can be used to credit notes from other people. If the @code{#:author} attribute is not supplied then the value of @code{default-authorname} @@ -208,25 +228,36 @@ @itemlist[ @item{Avoid defining new footnotes using @code{fndef} inside a @code{note}; these footnotes will be placed into the main footnote section of the article, which is probably not what you want.} ] + +} @defproc[(verse [#:title title string? ""] [#:italic? italic boolean? #f] [element xexpr?] ...) - txexpr?] + txexpr?]{ Typeset contents as poetry, with line breaks preserved and the block centered on the longest line. To set the whole block in italic, use @code{#:italic? #t} — otherwise, use @code{i} within the block. -@defproc[(blockquote [element xexpr?] ...) txexpr?] +If the first element in an article is a @racket[verse] tag with the @racket[#:title] attribute +specified, that title is used as the article’s title if the normal @racket[title] tag is absent. + +} + +@defproc[(blockquote [element xexpr?] ...) txexpr?]{ Surrounds a block quotation. To cite a source, include a @code{footer} tag at the bottom. -@defproc[(blockcode [element xexpr?] ...) txexpr?] +} + +@defproc[(blockcode [element xexpr?] ...) txexpr?]{ Typeset contents as a block of code using a monospace font. Line breaks are preserved. + +} @deftogether[(@defproc[(i [element xexpr?] ...) txexpr?] @defproc[(em [element xexpr?] ...) txexpr?] @defproc[(b [element xexpr?] ...) txexpr?] @defproc[(strong [element xexpr?] ...) txexpr?] @@ -234,17 +265,20 @@ @defproc[(ol [element xexpr?] ...) txexpr?] @defproc[(ul [element xexpr?] ...) txexpr?] @defproc[(item [element xexpr?] ...) txexpr?] @defproc[(sup [element xexpr?] ...) txexpr?] @defproc[(caps [element xexpr?] ...) txexpr?] - @defproc[(code [element xexpr?] ...) txexpr?])] + @defproc[(code [element xexpr?] ...) txexpr?])]{ + Work pretty much how you’d expect. + +} @section{Convenience macros} @defform[(for/s thing-id listofthings result-exprs ...) - #:contracts ([listofthings (listof any/c)])] + #:contracts ([listofthings (listof any/c)])]{ A shorthand form for Pollen’s @code{for/splice} that uses far fewer brackets when you’re only iterating through a single list. @codeblock|{ @@ -253,22 +287,24 @@ ◊for/s[x '(7 8 9)]{Now once for number ◊x} ◊;Above line is shorthand for this one: ◊for/splice[[(x (in-list '(7 8 9)))]]{Now once for number ◊x} }| + +} @section{Defining new tags} I use a couple of macros to define tag functions that automatically branch into other functions depending on the current output target format. This allows me to put the format-specific tag functions in separate files that have separate places in the dependency chain. So if only the HTML -tag functions have changed and not those for PDF, the @filepath{makefile} can ensure only the HTML files are -rebuilt. +tag functions have changed and not those for PDF, the @filepath{makefile} can ensure only the HTML +files are rebuilt. @defproc[#:kind "syntax" (poly-branch-tag (tag-id symbol?)) - (-> txexpr?)] + (-> txexpr?)]{ Defines a new function @racket[_tag-id] which will automatically pass all of its arguments to a function whose name is the value returned by @racket[current-poly-target], followed by a hyphen, followed by @racket[_tag]. So whenever the current output format is @racket['html], the function defined by @racket[(poly-branch-tag _p)] will branch to a function named @racket[html-p]; when the @@ -285,15 +321,19 @@ arguments, see @racket[poly-branch-kwargs-tag]. @margin-note{The thought behind having two macros so similar is that, by cutting out handling for keyword arguments, @racket[poly-branch-tag] could produce simpler and faster code. I have not verified if this intuition is meaningful or correct.} + +} @defproc[#:kind "syntax" (poly-branch-kwargs-tag (tag-id symbol?)) - (-> txexpr?)] + (-> txexpr?)]{ Works just like @racket[poly-branch-tag], but uses Pollen’s @racket[define-tag-function] so that keyword arguments will automatically be parsed as X-expression attributes. Additionally, the branch functions called from the new function must accept exactly two arguments: a list of attributes and a list of elements. + +}