Question

Hello all I am trying to dynamically build pdf files based on switches in a global defines file.

In file global_defines.rkt i have

#lang racket/base

(provide (all-defined-out))

(define alpha #f)
(define beta #t)
(define gamma #f)

in file foo.scrbl

#lang scribble/base
@(require "../../pdf_gen/global_defines.rkt")

@title{Getting Started}

@if[(or alpha)
        @para{Test text}
        ""]

@if[(or beta)
        (begin
            @dynamic-require["bar.scrbl" 'doc]
            doc)
        ""]

and in file bar.scrbl

#lang scribble/base
@(require "../../../pdf_gen/global_defines.rkt")
@(provide (all-defined-out))

@title{BAR}

happy marbles

so with the switches as they are currently i would expect to get something similar to the following out

Getting Started

1.BAR

happy marbles

while there are definitly other ways i can do it i would prefer to stick with scribble as it makes formatting and everything much easier than the other methods i can come up with right now. My main concerns are keeping the switches in one place and being able to pick and choose the content that is triggered by the switches being active, as there is content that will be common between several of the documents but not all of them, and quite a bit of content that only belongs in one or 2 places.

Was it helpful?

Solution

Although this answer isn't as elegant as I'd like, it works.

Basically I think you're talking about conditional compilation. In C you'd use a macro for this. In Racket let's use a macro, too (a macro which is just as brain-dead simple as a C macro).

Also we need a macro because Scribble's include-section is syntax (not a function) and must appear at the top-level. As a result, you can't use it inside of an if or when.

Given that:

define.rkt

#lang racket/base

(provide (all-defined-out))

;; Macros to conditionally include literal text.
;; Each of these should return `text`,
;; or (void) for nothing
(define-syntax-rule (when-alpha text)
  text)
(define-syntax-rule (when-beta text)
  (void))

;; Macros to conditionally include a .scrbl file
;; Each of these should return include-section,
;; or (void) for nothing
(require scribble/base) ;for include-section
(define-syntax-rule (when-alpha/include mod-path)
  (include-section mod-path))
(define-syntax-rule (when-beta/include mod-path)
  (void) #;(include-section mod-path))

Currently, this is set to show things for "alpha" but omit them for "beta". Unfortunately there's not a simple #t or #f to toggle. You need to edit the body of each one a bit more than that, as explained in the comments.

manual.scrbl example file conditionally including text and another file

#lang scribble/base
@(require "defines.rkt")
@title{Getting Started}
@when-alpha{@para{Text for alpha}}
@(when-beta/include "includee.scrbl")

includee.scrbl example file being conditionally included

#lang scribble/base
@title{BETA TEXT}
I am text for beta version.

What I don't love about this solution is that you have to create/change a pair of macros for each condition -- one for including literal text, and another for include-section-ing a .scrbl file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top