@soegaard が提供した答えは本当に十分に完全ですが、より一般的なテンプレート システムを探している人のために、これを行う 1 つの方法を示します。
重要なことは、@ フォームは Racket コードを記述する別の方法であることを覚えておくことです。そのため、特定のハッシュ テーブルに基づいて名前を置き換える一般的な方法を実際に探しています。(Racket にはそれを行う方法がたくさんあるので、@ フォームを使用してそれを行う方法はたくさんあります。)
L
これは、パラメーターに保持されているハッシュ テーブルの値を検索するルックアップ関数を使用します。このパラメーターはテキストをレンダリングするときのみ「ライブ」であるため、実際にはサンクを生成して、テキストがレンダリングされるまでルックアップを遅らせます。(より便利なキーのシンボルを保持するために、ハッシュ テーブルを少し変更しました。)output
関数 from
を使用scribble/text
して、テンプレート内の多くの種類の値 (入れ子になったリストなど) を許可する結果を生成します。同じ理由で、結果に文字列を試して使用する必要はありません。これは単なるリストです。次に、with-output-to-string
を使用してテキストを文字列に収集します。
#lang at-exp racket
(require scribble/text)
(define current-replacements (make-parameter #f))
(define (L key) (λ() (hash-ref (current-replacements) key)))
(define (render-with-hash ht template)
(parameterize ([current-replacements ht])
(with-output-to-string (λ() (output template)))))
(define ht (make-hash '([Name . "Simon"])))
(define template @list{Hello @L['Name]})
(render-with-hash ht template) ; => "Hello Simon"
もう少し便利なバリエーションはL
、引用を冗長にするマクロを使用することです。
...
(define-syntax-rule (L key) (λ() (hash-ref (current-replacements) 'key)))
...
(define template @list{Hello @L[Name]})
...
...または、{}
s は文字列の @ 構文にすぎないため、ハッシュ キーに文字列を使用する方法に戻ります。
#lang at-exp racket
(require scribble/text)
(define current-replacements (make-parameter #f))
(define (L key) (λ() (hash-ref (current-replacements) key)))
(define (render-with-hash ht template)
(parameterize ([current-replacements ht])
(with-output-to-string (λ() (output template)))))
(define ht (make-hash '(["Name" . "Simon"])))
(define template @list{Hello @L{Name}})
(render-with-hash ht template) ; => "Hello Simon"
ここで留意すべき 1 つの注意点は{}
、たとえば、テキスト コンテンツに改行がある場合、s はいくつかの文字列になる可能性があるということです。それに対処したい場合は、L
関数を調整して複数の引数を受け入れ、それらを一緒に追加し、ルックアップが完了する前にスペースを正規化できます。
#lang at-exp racket
(require scribble/text)
(define current-replacements (make-parameter #f))
(define (L . keys)
(λ() (hash-ref (current-replacements)
(regexp-replace #px"\\s+" (string-append* keys) " "))))
(define (render-with-hash ht template)
(parameterize ([current-replacements ht])
(with-output-to-string (λ() (output template)))))
(define ht (make-hash '(["First Name" . "Simon"])))
(define template @list{Hello @L{First
Name}})
(render-with-hash ht template) ; => "Hello Simon"
これらすべてで少し厄介なのは、ハッシュ テーブルを保持するパラメーターの使用です。このようなものは、使用するキーが事前にわからない場合にのみ必要です。ほとんどの場合、そうします。そのためには、単純な関数になるテンプレートへの引数として単純な変数を使用できます。
#lang at-exp racket
(require scribble/text)
(define (template Name)
@list{Hello @Name})
(with-output-to-string (λ() (output (template "Simon"))))
; => "Hello Simon"
最後にもう 1 つ注意してください。output
これらのすべてで使用したので、テキスト内にネストされた構造を持つことができます。必要なのは一連の文字列だけである場合は、次を使用できますstring-append
。
#lang at-exp racket
(define (template Name)
@string-append{Hello @Name})
(template "Simon") ; => "Hello Simon"
または、@soegaardの答えのように、関数を使用します。これは、一連の文字列値を追加できる(および文字列以外の値をingする)ことができる(文字列への)~a
安価なバージョンのようなものです。output
display
#lang at-exp racket
(define (template Name)
@~a{Hello @Name})
(template "Simon") ; => "Hello Simon"