0

大家好,我正在尝试根据全局定义文件中的开关动态构建 pdf 文件。

在文件 global_defines.rkt 我有

#lang racket/base

(provide (all-defined-out))

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

在文件 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)
        ""]

并在文件 bar.scrbl

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

@title{BAR}

happy marbles

所以使用目前的开关,我希望得到类似于以下内容的东西

入门

1.酒吧

快乐弹珠

虽然我肯定有其他方法可以做到这一点,但我更愿意坚持使用 scribble,因为它使格式化和一切都比我现在能想到的其他方法容易得多。我主要关心的是将开关保持在一个位置,并且能够选择由处于活动状态的开关触发的内容,因为在几个文档之间存在共同的内容,但不是所有文档,而且相当多仅属于一两个地方的内容。

4

1 回答 1

0

尽管这个答案没有我想的那么优雅,但它确实有效。

基本上我认为你在谈论条件编译。在 C 中,您将为此使用宏。在 Racket 中,我们也可以使用宏(一个与 C 宏一样简单的宏)。

我们还需要一个宏,因为 Scribbleinclude-section是语法(不是函数)并且必须出现在顶层。因此,您不能在ifor中使用它when

鉴于:

定义.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))

目前,这设置为显示“alpha”的内容,但忽略“beta”的内容。不幸的是,没有简单的#t#f切换。正如评论中所解释的那样,您需要对每个人的正文进行更多的编辑。

manual.scrbl示例文件有条件地包括文本和另一个文件

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

includee.scrbl示例文件被有条件地包含

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

我不喜欢这个解决方案的一点是,您必须为每个条件创建/更改一宏——一个用于包含文字文本,另一个用于include-section生成 .scrbl 文件。

于 2013-07-29T13:56:20.680 回答