bkyk8rc3zvpnsf5inmcqq4n3k98cv6hj-my-site-hyper-literate-git.test.suzanne.soy-0.0.1

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

renderer.scrbl (31287B)


      1 #lang scribble/doc
      2 @(require scribble/manual 
      3           "utils.rkt" 
      4           (for-label racket/class
      5                      scribble/render
      6                      scribble/xref
      7                      setup/dirs))
      8 
      9 @(define-syntax-rule (defmodule/local lib . content)
     10    (begin
     11      (define-syntax-rule (intro)
     12        (begin
     13          (require (for-label lib))
     14          (defmodule lib)
     15          . content))
     16      (intro)))
     17 
     18 @(begin
     19   (define-syntax-rule (def-html-render-mixin id mid)
     20     (begin
     21       (require (for-label scribble/html-render))
     22       (define id @racket[render-mixin])
     23       (define mid @racket[render-multi-mixin])))
     24   (def-html-render-mixin html:render-mixin html:render-multi-mixin))
     25 @(begin
     26   (define-syntax-rule (def-latex-render-mixin id)
     27     (begin
     28       (require (for-label scribble/latex-render))
     29       (define id @racket[render-mixin])))
     30   (def-latex-render-mixin latex:render-mixin))
     31 
     32 @title[#:tag "renderer"]{Renderers}
     33 
     34 A renderer is an object that provides four main methods:
     35 @racket[traverse], @racket[collect], @racket[resolve], and
     36 @racketidfont{render}. Each method corresponds to a pass described in
     37 @secref["core"], and they are chained together by the @racket[render]
     38 function to render a document.
     39 
     40 @section{Rendering Driver}
     41 
     42 @defmodule[scribble/render]
     43 
     44 @defproc[(render [docs (listof part?)]
     45                  [names (listof path-string?)]
     46                  [#:render-mixin render-mixin (class? . -> . class?) @#,html:render-mixin]
     47                  [#:dest-dir dest-dir (or/c #f path-string?) #f]
     48                  [#:helper-file-prefix helper-file-prefix (or/c #f string?) #f]
     49                  [#:prefix-file prefix-file (or/c #f path-string?) #f]
     50                  [#:style-file style-file (or/c #f path-string?) #f]
     51                  [#:style-extra-files style-extra-files (listof path-string?) #f]
     52                  [#:extra-files extra-files (listof path-string?) #f]
     53                  [#:image-preferences image-preferences (listof (or/c 'ps 'pdf 'png 'svg 'gif)) null]
     54                  [#:xrefs xrefs (listof xref?) null]
     55                  [#:info-in-files info-in-files (listof path-string?) null]
     56                  [#:info-out-file info-out-file (or/c #f path-string?) #f]
     57                  [#:redirect redirect (or/c #f string?) #f]
     58                  [#:redirect-main redirect-main (or/c #f string?) #f]
     59                  [#:directory-depth directory-depth exact-nonnegative-integer? 0]
     60                  [#:quiet? quiet? any/c #t]
     61                  [#:warn-undefined? warn-undefined? any/c (not quiet?)])
     62           void?]{
     63 
     64 Renders the given @racket[docs], each with an output name derived from
     65 the corresponding element of @racket[names]. A directory path (if any)
     66 for a name in @racket[names] is discarded, and the file suffix is
     67 replaced (if any) with a suitable suffix for the output format.
     68 
     69 The @racket[render-mixin] argument determines the output format. By
     70 default, it is @html:render-mixin from @racketmodname[scribble/html-render].
     71 
     72 The @racket[dest-dir] argument determines the output directory, which
     73 is created using @racket[make-directory*] if it is non-@racket[#f] and
     74 does not exist already.
     75 
     76 The @racket[helper-file-prefix], @racket[prefix-file],
     77 @racket[style-file], @racket[style-extra-files], and
     78 @racket[extra-files] arguments are passed on to the @racket[render%]
     79 constructor.
     80 
     81 The @racket[image-preferences] argument specified preferred formats
     82 for image files and conversion, where formats listed earlier in the
     83 list are more preferred. The renderer specified by
     84 @racket[render-mixin] may not support all of the formats listed in
     85 @racket[image-preferences].
     86 
     87 The @racket[xrefs] argument provides extra cross-reference information
     88 to be used during the documents' @tech{resolve pass}. The
     89 @racket[info-in-files] arguments supply additional cross-reference
     90 information in serialized form. When the @racket[info-out-file]
     91 argument is not @racket[#f], cross-reference information for the
     92 rendered documents is written in serialized for to the specified file.
     93 
     94 The @racket[redirect] and @racket[redirect-main] arguments correspond
     95 to the @racket[set-external-tag-path] and
     96 @racket[set-external-root-url] methods of @|html:render-mixin| from
     97 @racketmodname[scribble/html-render], so they should be
     98 non-@racket[#f] only for HTML rendering.
     99 
    100 The @racket[directory-depth] arguments correspond to the
    101 @racket[set-directory-depth] method of @|html:render-multi-mixin|.
    102 
    103 If @racket[quiet?] is a false value, output-file information is
    104 written to the current output port.
    105 
    106 If @racket[warn-undefined?] is a true value, then references to
    107 missing cross-reference targets trigger a warning message on the
    108 current error port.
    109 
    110 @history[#:changed "1.4" @elem{Added the @racket[#:image-preferences] argument.}]}
    111 
    112 
    113 @section{Base Renderer}
    114 
    115 @defmodule[scribble/base-render]{The
    116 @racketmodname[scribble/base-render] module provides @racket[render%],
    117 which implements the core of a renderer. This rendering class must be
    118 refined with a mixin from @racketmodname[scribble/text-render],
    119 @racketmodname[scribble/markdown-render], or
    120 @racketmodname[scribble/html-render], or
    121 @racketmodname[scribble/latex-render].}
    122 
    123 The mixin structure is meant to support document-specific extensions
    124 to the renderers. For example, the @exec{scribble} command-line tool
    125 might, in the future, extract rendering mixins from a document module
    126 (in addition to the document proper).
    127 
    128 See the @filepath{base-render.rkt} source for more information about
    129 the methods of the renderer. Documents built with higher layers, such
    130 as @racketmodname[scribble/manual], generally do not call the render
    131 object's methods directly.
    132 
    133 @definterface[render<%> ()]{
    134 
    135 @defmethod[(traverse [srcs (listof part?)]
    136                      [dests (listof path-string?)])
    137            (and/c hash? immutable?)]{
    138 
    139 Performs the @techlink{traverse pass}, producing a hash table that
    140 contains the replacements for and @racket[traverse-block]s and
    141 @racket[traverse-elements]s. See @method[render<%> render] for
    142 information on the @racket[dests] argument.}
    143 
    144 @defmethod[(collect [srcs (listof part?)]
    145                     [dests (listof path-string?)]
    146                     [fp (and/c hash? immutable?)]
    147                     [demand (tag? collect-info? . -> . any/c) (lambda (_tag _ci) #f)])
    148            collect-info?]{
    149 
    150 Performs the @techlink{collect pass}. See @method[render<%> render] for
    151 information on the @racket[dests] arguments. The @racket[fp] argument
    152 is a result from the @method[render<%> traverse] method.
    153 
    154 The @racket[demand] argument supplies external tag mappings on demand.
    155 When the @racket[collect-info] result is later used to find a mapping
    156 for a tag and no mapping is already available, @racket[demand] is
    157 called with the tag and the @racket[collect-info]. The @racket[demand]
    158 function returns true to indicate when it adds information to the
    159 @racket[collect-info] so that the lookup should be tried again; the
    160 @racket[demand] function should return @racket[#f] if it does not
    161 extend @racket[collect-info].}
    162 
    163 @defmethod[(resolve [srcs (listof part?)]
    164                     [dests (listof path-string?)]
    165                     [ci collect-info?])
    166            resolve-info?]{
    167 
    168 Performs the @techlink{resolve pass}. See @method[render<%> render] for
    169 information on the @racket[dests] argument.  The @racket[ci] argument
    170 is a result from the @method[render<%> collect] method.}
    171 
    172 @defmethod[(render [srcs (listof part?)]
    173                    [dests (listof (or/c path-string? #f))]
    174                    [ri resolve-info?])
    175            list?]{
    176 
    177 Produces the final output.  The @racket[ri] argument is a result from
    178 the @method[render<%> render] method.
    179 
    180 The @racket[dests] provide names of files for Latex or single-file
    181 HTML output, or names of sub-directories for multi-file HTML output.
    182 If the @racket[dests] are relative, they're relative to the current
    183 directory; normally, they should indicates a path within the
    184 @racket[_dest-dir] supplied on initialization of the @racket[render%]
    185 object.
    186 
    187 If an element of @racket[dests] is @racket[#f], then the corresponding
    188 position of the result list contains a string for rendered document.
    189 Some renderers require that @racket[dest] contains all path strings.}
    190 
    191 
    192 @defmethod[(serialize-info [ri resolve-info?])
    193            any/c]{
    194 
    195 Serializes the collected info in @racket[ri].}
    196 
    197 
    198 @defmethod[(serialize-infos [ri resolve-info?] 
    199                             [count exact-positive-integer?] 
    200                             [doc part?])
    201            list?]{
    202 
    203 Like @method[render<%> serialize-info], but produces @racket[count] results
    204 that together have the same information as produced by
    205 @method[render<%> serialize-info]. The structure of @racket[doc] is used to
    206 drive the partitioning (on the assumption that @racket[ri] is derived
    207 from @racket[doc]).}
    208 
    209 
    210 @defmethod[(deserialize-info [v any/c]
    211                              [ci collect-info?]
    212                              [#:root root-path (or/c path-string? false/c) #f])
    213            void?]{
    214 
    215 Adds the deserialized form of @racket[v] to @racket[ci].
    216 
    217 If @racket[root-path] is not @racket[#f], then file paths that are
    218 recorded in @racket[ci] as relative to an instantiation-supplied
    219 @racket[root-path] are deserialized as relative instead to the given
    220 @racket[root-path].}
    221 
    222 
    223 @defmethod[(get-defined [ci collect-info?]) (listof tag?)]{
    224 
    225 Returns a list of tags that were defined within the documents
    226 represented by @racket[ci].}
    227 
    228 
    229 @defmethod[(get-defineds [ci collect-info?] 
    230                          [count exact-positive-integer?] 
    231                          [doc part?])
    232            (listof (listof tag?))]{
    233 
    234 Analogous to @method[render<%> serialize-infos]: returns a list of
    235 tags for each of @racket[count] partitions of the result of
    236 @method[render<%> get-defined], using the structure of @racket[doc] to
    237 drive the partitioning.}
    238 
    239 
    240 @defmethod[(get-external [ri resolve-info?]) (listof tag?)]{
    241 
    242 Returns a list of tags that were referenced but not defined within the
    243 documents represented by @racket[ri] (though possibly found in
    244 cross-reference information transferred to @racket[ri] via
    245 @racket[xref-transfer-info]).}
    246 
    247 
    248 @defmethod[(get-undefined [ri resolve-info?]) (listof tag?)]{
    249 
    250 Returns a list of tags that were referenced by the resolved documents
    251 with no target found either in the resolved documents represented by
    252 @racket[ri] or cross-reference information transferred to @racket[ri]
    253 via @racket[xref-transfer-info].
    254 
    255 If multiple tags were referenced via @racket[resolve-search] and a
    256 target was found for any of the tags using the same dependency key,
    257 then no tag in the set is included in the list of undefined tags.}
    258 
    259 }
    260 
    261 @defclass[render% object% (render<%>)]{
    262 
    263 Represents a renderer.
    264 
    265 @defconstructor[([dest-dir path-string?]
    266                  [refer-to-existing-files any/c #f]
    267                  [root-path (or/c path-string? #f) #f]
    268                  [prefix-file (or/c path-string? #f) #f]
    269                  [style-file (or/c path-string? #f) #f]
    270                  [style-extra-files (listof path-string?) null]
    271                  [extra-files (listof path-string?) null]
    272                  [image-preferences (listof (or/c 'ps 'pdf 'png 'svg 'gif)) null])]{
    273 
    274 Creates a renderer whose output will go to @racket[dest-dir]. For
    275 example, @racket[dest-dir] could name the directory containing the
    276 output Latex file, the HTML file for a single-file output, or the
    277 output sub-directory for multi-file HTML output.
    278 
    279 If @racket[refer-to-existing-files] is true, then when a document
    280 refers to external files, such as an image or a style file, then the
    281 file is referenced from its source location instead of copied to the
    282 document destination.
    283 
    284 If @racket[root-path] is not @racket[#f], it is normally the same as
    285 @racket[dest-dir] or a parent of @racket[dest-dir]. It causes
    286 cross-reference information to record destination files relative to
    287 @racket[root-path]; when cross-reference information is serialized, it
    288 can be deserialized via @method[render<%> deserialize-info] with a
    289 different root path (indicating that the destination files have
    290 moved).
    291 
    292 The @racket[prefix-file], @racket[style-file], and
    293 @racket[style-extra-files] arguments set files that control output
    294 styles in a formal-specific way; see @secref["config-style"] for more
    295 information.
    296 
    297 The @racket[extra-files] argument names files to be copied to the
    298 output location, such as image files or extra configuration files.
    299 
    300 The @racket[image-preferences] argument specified preferred formats
    301 for image files and conversion, where formats listed earlier in the
    302 list are more preferred. The renderer may not support all of the
    303 formats listed in @racket[image-preferences].
    304 
    305 @history[#:changed "1.4" @elem{Added the @racket[image-preferences]
    306                                initialization argument.}]}
    307 
    308 @defmethod[(traverse [parts (listof part?)]
    309                      [dests (listof path-string?)])
    310            (and/c hash? immutable?)]
    311 @defmethod[(start-traverse [parts (listof part?)]
    312                            [dests (listof path-string?)]
    313                            [fp (and/c hash? immutable?)])
    314            (and/c hash? immutable?)]
    315 @defmethod[(traverse-part [p part?]
    316                           [fp (and/c hash? immutable?)])
    317             (and/c hash? immutable?)]
    318 @defmethod[(traverse-flow [bs (listof block?)]
    319                           [fp (and/c hash? immutable?)])
    320            (and/c hash? immutable?)]
    321 @defmethod[(traverse-block [b block?]
    322                            [fp (and/c hash? immutable?)])
    323            (and/c hash? immutable?)]
    324 @defmethod[(traverse-nested-flow [nf nested-flow?]
    325                                  [fp (and/c hash? immutable?)])
    326            (and/c hash? immutable?)]
    327 @defmethod[(traverse-table [t table?]
    328                            [fp (and/c hash? immutable?)])
    329            (and/c hash? immutable?)]
    330 @defmethod[(traverse-itemization [i itemization?] 
    331                                  [fp (and/c hash? immutable?)])
    332            (and/c hash? immutable?)]
    333 @defmethod[(traverse-compound-paragraph [cp compound-paragraph?]
    334                                         [fp (and/c hash? immutable?)])
    335            (and/c hash? immutable?)]
    336 @defmethod[(traverse-paragraph [p paragraph?]
    337                                [fp (and/c hash? immutable?)])
    338            (and/c hash? immutable?)]
    339 @defmethod[(traverse-content [c content?]
    340                              [fp (and/c hash? immutable?)])
    341            (and/c hash? immutable?)]
    342 @defmethod[(traverse-target-element [e target-element?]
    343                                     [fp (and/c hash? immutable?)])
    344            (and/c hash? immutable?)]
    345 @defmethod[(traverse-index-element [e index-element?]
    346                                    [fp (and/c hash? immutable?)])
    347            (and/c hash? immutable?)]{
    348 
    349 These methods implement the @tech{traverse pass} of document rendering.
    350 Except for the entry point @method[render% traverse] as described by
    351 as described at @xmethod[render<%> traverse], these methods
    352 generally would not be called to render a document, but instead
    353 provide natural points to interpose on the default implementation.
    354 
    355 A renderer for a specific format is relatively unlikely to override
    356 any of these methods. Each method accepts the information accumulated
    357 so far and returns augmented information as a result.}
    358 
    359 
    360 @defmethod[(collect [parts (listof part?)]
    361                     [dests (listof path-string?)]
    362                     [fp (and/c hash? immutable?)]
    363                     [demand (tag? collect-info? . -> . any/c) (lambda (_tag _ci) #f)])
    364            collect-info?]
    365 @defmethod[(start-collect [parts (listof part?)]
    366                           [dests (listof path-string?)]
    367                           [ci collect-info?])
    368            void?]
    369 @defmethod[(collect-part [p part?]
    370                          [parent (or/c #f part?)]
    371                          [ci collect-info?]
    372                          [number (listof part-number-item?)]
    373                          [init-sub-number part-number-item?]
    374                          [init-sub-numberers (listof numberer?)])
    375             (values part-number-item? numberer?)]
    376 @defmethod[(collect-part-tags [p part?]
    377                               [ci collect-info?]
    378                               [number (listof part-number-item?)])
    379            void?]
    380 @defmethod[(collect-flow [bs (listof block?)]
    381                          [ci collect-info?])
    382            void?]
    383 @defmethod[(collect-block [b block?]
    384                           [ci collect-info?])
    385            void?]
    386 @defmethod[(collect-nested-flow [nf nested-flow?]
    387                                 [ci collect-info?])
    388            void?]
    389 @defmethod[(collect-table [t table?]
    390                           [ci collect-info?])
    391            void?]
    392 @defmethod[(collect-itemization [i itemization?]
    393                                 [ci collect-info?])
    394            void?]
    395 @defmethod[(collect-compound-paragraph [cp compound-paragraph?]
    396                                        [ci collect-info?])
    397            void?]
    398 @defmethod[(collect-paragraph [p paragraph?]
    399                               [ci collect-info?])
    400            void?]
    401 @defmethod[(collect-content [c content?]
    402                             [ci collect-info?])
    403            void?]
    404 @defmethod[(collect-target-element [e target-element?]
    405                                    [ci collect-info?])
    406            void?]
    407 @defmethod[(collect-index-element [e index-element?]
    408                                   [ci collect-info?])
    409            void?]{
    410 
    411 These methods implement the @tech{collect pass} of document rendering.
    412 Except for the entry point @method[render% collect] as described at
    413 @xmethod[render<%> collect], these methods generally would not be
    414 called to render a document, but instead provide natural points to
    415 interpose on the default implementation.
    416 
    417 A renderer for a specific format is most likely to override
    418 @method[render% collect-part-tags], @method[render%
    419 collect-target-element], and perhaps @method[render% start-collect] to
    420 set up and record cross-reference information in a way that is
    421 suitable for the target format.}
    422 
    423 @defmethod[(resolve [parts (listof part?)]
    424                     [dests (listof path-string?)]
    425                     [ci collect-info?])
    426            resolve-info?]
    427 @defmethod[(start-resolve [parts (listof part?)]
    428                           [dests (listof path-string?)]
    429                           [ri resolve-info?])
    430            void?]
    431 @defmethod[(resolve-part [p part?]
    432                          [ri resolve-info?])
    433             void?]
    434 @defmethod[(resolve-flow [bs (listof block?)]
    435                          [enclosing-p part?]
    436                          [ri resolve-info?])
    437            void?]
    438 @defmethod[(resolve-block [b block?]
    439                          [enclosing-p part?]
    440                           [ri resolve-info?])
    441            void?]
    442 @defmethod[(resolve-nested-flow [nf nested-flow?]
    443                                 [enclosing-p part?]
    444                                 [ri resolve-info?])
    445            void?]
    446 @defmethod[(resolve-table [t table?]
    447                           [enclosing-p part?]
    448                           [ri resolve-info?])
    449            void?]
    450 @defmethod[(resolve-itemization [i itemization?]
    451                                 [enclosing-p part?]
    452                                 [ri resolve-info?])
    453            void?]
    454 @defmethod[(resolve-compound-paragraph [cp compound-paragraph?]
    455                                        [enclosing-p part?]
    456                                        [ri resolve-info?])
    457            void?]
    458 @defmethod[(resolve-paragraph [p paragraph?]
    459                               [enclosing-p part?]
    460                               [ri resolve-info?])
    461            void?]
    462 @defmethod[(resolve-content [c content?]
    463                             [enclosing-p part?]
    464                             [ri resolve-info?])
    465            void?]{
    466 
    467 These methods implement the @tech{resolve pass} of document rendering.
    468 Except for the entry point @method[render% resolve] as described at
    469 @xmethod[render<%> resolve], these methods generally would not be
    470 called to render a document, but instead provide natural points to
    471 interpose on the default implementation.
    472 
    473 A renderer for a specific format is unlikely to override any of these
    474 methods. Each method for a document fragment within a part receives
    475 the enclosing part as an argument, as well as resolve information as
    476 @racket[ri] to update.}
    477 
    478 
    479 @defmethod[(render [parts (listof part?)]
    480                    [dests (listof (or/c path-string? #f))]
    481                    [ri resolve-info?])
    482            list?]
    483 @defmethod[(render-one [part part?]
    484                        [ri resolve-info?]
    485                        [dest (or/c path-string? #f)])
    486            any/c]
    487 @defmethod[(render-part [p part?]
    488                         [ri resolve-info?])
    489            any/c]
    490 @defmethod[(render-part-content [p part?]
    491                                 [ri resolve-info?])
    492            any/c]
    493 @defmethod[(render-flow [bs (listof block?)]
    494                         [enclosing-p part?]
    495                         [ri resolve-info?]
    496                         [first-in-part-or-item? boolean?])
    497            any/c]
    498 @defmethod[(render-block [b block?]
    499                          [enclosing-p part?]
    500                          [ri resolve-info?]
    501                          [first-in-part-or-item? boolean?])
    502            any/c]
    503 @defmethod[(render-nested-flow [nf nested-flow?]
    504                                [enclosing-p part?]
    505                                [ri resolve-info?]
    506                                [first-in-part-or-item? boolean?])
    507            any/c]
    508 @defmethod[(render-table [t table?]
    509                          [enclosing-p part?]
    510                          [ri resolve-info?]
    511                          [first-in-part-or-item? boolean?])
    512            any/c]
    513 @defmethod[(render-auxiliary-table [t table?]
    514                                    [enclosing-p part?]
    515                                    [ri resolve-info?])
    516            any/c]
    517 @defmethod[(render-itemization [i itemization?]
    518                                [enclosing-p part?]
    519                                [ri resolve-info?])
    520            any/c]
    521 @defmethod[(render-compound-paragraph [cp compound-paragraph?]
    522                                       [enclosing-p part?]
    523                                       [ri resolve-info?]
    524                                       [first-in-part-or-item? boolean?])
    525            any/c]
    526 @defmethod[(render-intrapara-block [p paragraph?]
    527                                    [enclosing-p part?]
    528                                    [ri resolve-info?]
    529                                    [first-in-compound-paragraph? boolean?]
    530                                    [last-in-compound-paragraph? boolean?]
    531                                    [first-in-part-or-item? boolean?])
    532            any/c]
    533 @defmethod[(render-paragraph [p paragraph?]
    534                              [enclosing-p part?]
    535                              [ri resolve-info?])
    536            any/c]
    537 @defmethod[(render-content [c content?]
    538                            [enclosing-p part?]
    539                            [ri resolve-info?])
    540            any/c]
    541 @defmethod[(render-other [c (and/c content? (not/c element?) (not/c convertible?))]
    542                          [enclosing-p part?]
    543                          [ri resolve-info?])
    544            any/c]{
    545 
    546 These methods implement the @tech{render pass} of document rendering.
    547 Except for the entry point @method[render% render] as described at
    548 @xmethod[render<%> render], these methods generally would not be
    549 called to render a document, but instead provide natural points to
    550 interpose on the default implementation.
    551 
    552 A renderer for a specific format is likely to override most or all of
    553 these methods. The result of each method can be anything, and the
    554 default implementations of the methods propagate results and collect
    555 them into a list as needed. The value of @racket[current-output-port]
    556 is set by @method[render% render] for each immediate @racket[part]
    557 before calling @method[render% render-one], so methods might
    558 individually print to render, or they might return values that are
    559 used both other methods to print. The interposition points for this
    560 pass are somewhat different than for other passes:
    561 
    562 @itemlist[
    563 
    564  @item{@method[render% render-one] is called by the @method[render%
    565        render] method on each immediate @racket[part] in the list for
    566        its first argument.}
    567 
    568  @item{@method[render% render-auxiliary-table] is called by the
    569        default @method[render% render-block] on any @racket[table]
    570        that has the @racket['aux] @tech{style property}.}
    571 
    572  @item{@method[render% render-intrapara-block] is called on blocks
    573        within a @racket[compound-paragraph], where the default
    574        implementation just chains to @racket[render% render-block].}
    575 
    576 
    577  @item{@method[render% render-other] is called by the default
    578        implementation of @racket[render-content] for any content that
    579        does not satisfy @racket[element?] or @racket[convertible?].}
    580 
    581 ]}
    582 
    583 }
    584 
    585 @; ----------------------------------------
    586 
    587 @section{Text Renderer}
    588 
    589 @defmodule/local[scribble/text-render]{
    590 
    591 @defmixin[render-mixin (render<%>) ()]{
    592 
    593 Specializes a @racket[render<%>] class for generating plain text.}}
    594 
    595 @; ----------------------------------------
    596 
    597 @section{Markdown Renderer}
    598 
    599 @defmodule/local[scribble/markdown-render]{
    600 
    601 @defmixin[render-mixin (render<%>) ()]{
    602 
    603 Specializes a @racket[render<%>] class for generating Markdown text.
    604 
    605 Code blocks are marked using the
    606 @hyperlink["http://github.github.com/github-flavored-markdown/"
    607 "Github convention"] @verbatim{```racket} so that they are lexed and
    608 formatted as Racket code.}}
    609 
    610 @defboolparam[current-markdown-link-sections enabled?]{
    611 
    612 Determines whether section links within an output document are
    613 rendered as a section link. The default is @racket[#f].
    614 
    615 @history[#:added "1.31"]}
    616 
    617 @; ----------------------------------------
    618 
    619 @section{HTML Renderer}
    620 
    621 @defmodule/local[scribble/html-render]{
    622 
    623 @defmixin[render-mixin (render<%>) ()]{
    624 
    625   @defconstructor/auto-super[([search-box? boolean? #f])]{
    626    Specializes a @racket[render<%>] class for generating
    627    HTML output. The arguments are the same as 
    628    @racket[render<%>], except for the addition of 
    629    @racket[search-box].
    630 
    631    If @racket[search-box?] is @racket[#t] and the document
    632    is created with @racket[scribble/manual], then it will be
    633    rendered with a search box, similar to this page. Note
    634    that the @racket[search-box?] argument does not create
    635    the search page itself. Rather, it passes the search
    636    query to whatever page is located at
    637    @tt{search/index.html}. The query is passed as an HTTP
    638    query string in the @tt{q} field.}
    639 
    640 @defmethod[(set-external-tag-path [url string?]) void?]{
    641 
    642 Configures the renderer to redirect links to external documents via
    643 @racket[url], adding a @tt{tag} query element to the end of the
    644 URL that contains the Base64-encoded, @racket[print]ed, serialized
    645 original tag (in the sense of @racket[link-element]) for the link.
    646 The result of @racket[get-doc-search-url] is intended for use as @racket[url].
    647 
    648 If the link is based on a cross-reference entry that has a
    649 document-identifying string (see @racket[load-xref] and its
    650 @racket[#:doc-id] argument), the document identifier is added as a
    651 @tt{doc} query element, and a path to the target within the
    652 document is added as a @tt{rel} query element.}
    653 
    654 @defmethod[(set-external-root-url [url string?]) void?]{
    655 
    656 Configures the renderer to redirect links to documents installed in
    657 the distribution's documentation directory to the given URL, using the
    658 URL as a replacement to the path of the distribution's document
    659 directory.}
    660 
    661 }
    662 
    663 @defmixin[render-multi-mixin (render<%>) ()]{
    664 
    665 Further specializes a rendering class produced by
    666 @racket[render-mixin] for generating multiple HTML
    667 files.
    668 
    669 @defmethod[(set-directory-depth [depth exact-nonnegative-integer?]) void?]{
    670 
    671 Sets the depth of directory structure used when rendering parts that
    672 are own their own pages. A value of @racket[0] is treated the same as
    673 @racket[1].}
    674 
    675 }
    676 
    677 }
    678 
    679 @; ----------------------------------------
    680 
    681 @section{Latex Renderer}
    682 
    683 @defmodule/local[scribble/latex-render]{
    684 
    685 @defmixin[render-mixin (render<%>) ()]{
    686 
    687 Specializes a @racket[render<%>] class for generating Latex input.}}
    688 
    689 @defparam[extra-character-conversions convs (-> char? (or/c string? #f))]{
    690 Function that maps (special) characters to strings corresponding to the Latex
    691 code that should be used to render them. This function should return false for
    692 any character it does not know how to handle.
    693 
    694 Scribble already converts many special characters to the proper Latex
    695 commands. This parameter should be used in case you need characters it does not
    696 support yet.
    697 }
    698 
    699 @; ----------------------------------------
    700 
    701 @section{PDF Renderer}
    702 
    703 @defmodule/local[scribble/pdf-render]{
    704 
    705 @defmixin[render-mixin (render<%>) ()]{
    706 
    707 Specializes a @racket[render<%>] class for generating PDF output via
    708 Latex, building on @|latex:render-mixin| from @racketmodname[scribble/latex-render].}
    709 
    710 @defmixin[dvi-render-mixin (render<%>) ()]{
    711 
    712 Like @racket[render-mixin], but generates PDF output via @exec{latex},
    713 @exec{dvips}, and @exec{pstopdf}.
    714 
    715 @history[#:added "1.4"]}}
    716 
    717 @defmixin[xelatex-render-mixin (render<%>) ()]{
    718 
    719 Like @racket[render-mixin], but generates PDF output via @exec{xelatex}.
    720 
    721 @history[#:added "1.19"]}
    722 
    723 @; ----------------------------------------
    724 
    725 @section{Contract (Blue boxes) Renderer}
    726 
    727 @defmodule/local[scribble/contract-render]{
    728 
    729 @defmixin[override-render-mixin-multi (render<%>) ()]{
    730 
    731 Overrides the @method[render<%> render] method of 
    732 given renderer to record the content of the 
    733 blue boxes (generated by @racket[defproc], @racket[defform], etc)
    734 that appear in the document. 
    735    
    736 @defmethod[#:mode override
    737                   (render [srcs (listof part?)]
    738                           [dests (listof path?)]
    739                           [ri render-info?])
    740                   void?]{
    741 In addition to doing whatever the @racket[super] method
    742 does, also save the content of the blue boxes (rendered
    743 via a @racketmodname[scribble/text-render] renderer).
    744    
    745 It saves this information in three pieces in a file
    746 inside the @racket[dests] directories called
    747 @filepath{blueboxes.rktd}. The first piece is
    748 a single line containing a (decimal, ASCII) number. That number
    749 is the number of bytes that the second piece of information
    750 occupies in the file. The second piece of information
    751 is a @racket[hash] that maps @racket[tag?] values to
    752 a list of offsets and line numbers that follow the hash table.
    753 For example, if the @racket[hash] maps
    754 @racket['(def ((lib "x/main.rkt") abcdef))] to
    755 @racket['((10 . 3))], then that means that the documentation
    756 for the @racket[abcdef] export from the @racket[x] collection
    757 starts 10 bytes after the end of the hash table and continues for
    758 @racket[3] lines. Multiple elements in the list mean that that
    759 @racket[tag?] has multiple blue boxes and each shows where one
    760 of the boxes appears in the file.
    761 }}
    762  
    763 @defmixin[override-render-mixin-single (render<%>) ()]{
    764 
    765 Just like @racket[override-render-mixin-multi], except
    766 it saves the resulting files in a different place.
    767 
    768 @defmethod[#:mode override
    769                   (render [srcs (listof part?)]
    770                           [dests (listof path?)]
    771                           [ri render-info?])
    772                   void?]{
    773   Just like @method[override-render-mixin-multi render], except
    774   that it saves the file @filepath{blueboxes.rktd} in
    775   the same directory where each @racket[dests] element resides.
    776 }}
    777 }