Racket / Scribble动态pdf生成

时间:2013-07-28 03:17:24

标签: pdf dynamic racket scribble

大家好,我试图根据全局定义文件中的开关动态构建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.BAR

快乐的大理石

虽然我确实有其他方法可以做到这一点我宁愿坚持使用scribble,因为它使格式化和一切都比我现在想出的其他方法更容易。我主要担心的是将交换机保持在一个位置,并能够选择由活动交换机触发的内容,因为有些内容在几个文档之间是通用的,但不是全部,并且相当一点内容只属于一个或两个地方。

1 个答案:

答案 0 :(得分:0)

虽然这个答案并不像我想的那么优雅,但它确实有用。

基本上我认为你在谈论条件编译。在C中你会使用一个宏。在Racket中,我们也使用一个宏(一个像C宏一样简单的宏脑)。

我们还需要一个宏,因为Scribble的include-section是语法(不是函数),必须出现在顶层。因此,您无法在ifwhen

中使用它

鉴于:

<强> 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))

目前,这设置为显示“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文件。