add #:omit-tags parameter

main
Matthew Butterick 11 years ago
parent 502ea53fa5
commit 4c2a7c4f0c

@ -151,21 +151,24 @@
(if (char? joiner) (format "~a" joiner) joiner))
;; helper macro that applies proc to all strings found in xexpr input
(define-syntax (apply-xexpr-strings stx)
(syntax-case stx ()
[(_ proc val) #'(let loop ([x val])
(cond
[(string? x) (proc x)]
[(txexpr? x) (map-elements loop x)]
[else x]))]))
(define (apply-xexpr-strings proc x [tags-to-omit '()])
; ((procedure? txexpr?) ((or/c null (listof txexpr-tag?))) . ->* . txexpr?)
(let loop ([x x])
(cond
[(string? x) (proc x)]
[(and (txexpr? x) (not (member (car x) tags-to-omit))) (cons (car x) (map loop (cdr x)))]
[else x])))
;; Hyphenate using a filter procedure.
(define+provide+safe (hyphenatef x proc [joiner default-joiner]
#:exceptions [extra-exceptions '()]
#:min-length [min-length default-min-length])
#:exceptions [extra-exceptions '()]
#:min-length [min-length default-min-length]
#:omit-tags [tags-to-omit '()])
((xexpr? procedure?) ((or/c char? string?)
#:exceptions (listof exception-word?)
#:min-length (or/c integer? #f)) . ->* . xexpr/c)
#:min-length (or/c integer? #f)
#:omit-tags (or/c null (listof txexpr-tag?))) . ->* . xexpr/c)
;; set up module data
;; todo?: change set! to parameterize
@ -178,17 +181,21 @@
(define (insert-hyphens text)
(regexp-replace* word-pattern text (λ(word) (if (proc word) (string-join (word->hyphenation-points word min-length) joiner-string) word))))
(apply-xexpr-strings insert-hyphens x))
(apply-xexpr-strings insert-hyphens x tags-to-omit))
;; Default hyphenate is a special case of hyphenatef.
(define+provide+safe (hyphenate x [joiner default-joiner]
#:exceptions [extra-exceptions '()]
#:min-length [min-length default-min-length])
#:exceptions [extra-exceptions '()]
#:min-length [min-length default-min-length]
#:omit-tags [tags-to-omit '()])
((xexpr/c) ((or/c char? string?)
#:exceptions (listof exception-word?)
#:min-length (or/c integer? #f)) . ->* . xexpr/c)
(hyphenatef x (λ(x) #t) joiner #:exceptions extra-exceptions #:min-length min-length))
#:min-length (or/c integer? #f)
#:omit-tags (or/c null (listof txexpr-tag?))) . ->* . xexpr/c)
(hyphenatef x (λ(x) #t) joiner #:exceptions extra-exceptions #:min-length min-length #:omit-tags tags-to-omit))
;; Remove hyphens.

@ -1,9 +1,9 @@
#lang scribble/manual
@(require scribble/eval (for-label racket "../main.rkt" xml))
@(require scribble/eval (for-label txexpr racket "../main.rkt" xml))
@(define my-eval (make-base-eval))
@(my-eval `(require hyphenate xml))
@(my-eval `(require (submod txexpr safe) (submod hyphenate safe) xml))
@title{Hyphenate}
@ -39,7 +39,8 @@ Safe mode enables the function contracts documented below. Use safe mode by impo
[xexpr xexpr/c]
[joiner (or/c char? string?) (integer->char #x00AD)]
[#:exceptions exceptions (listof string?) empty]
[#:min-length length (or/c integer? false?) 5])
[#:min-length length (or/c integer? false?) 5]
[#:omit-tags tags (or/c null (listof txexpr-tag?)) null])
xexpr/c]
Hyphenate @racket[_xexpr] by calculating hyphenation points and inserting @racket[_joiner] at those points. By default, @racket[_joiner] is the soft hyphen (Unicode 00AD = decimal 173). Words shorter than @racket[#:min-length] @racket[_length] will not be hyphenated. To hyphenate words of any length, use @racket[#:min-length] @racket[#f].
@ -96,14 +97,20 @@ You can send HTML-style X-expressions through @racket[hyphenate]. It will recurs
Don't send raw HTML or XML through @racket[hyphenate]. It can't distinguish tags and attributes from textual content, so everything will be hyphenated, thus goofing up your file. But you can easily convert your HTML or XML to an X-expression, hyphenate it, and then convert back.
@margin-note{In HTML, be careful not to include any @code{<script>} or @code{<style>} blocks, which contain non-hyphenatable data. The easiest way to protect that data — and arguably the right way — is to wrap it in a @code{<![CDATA[]]>} tag.}
@examples[#:eval my-eval
(define html "<body style=\"background: yellow\">Hello</body>")
(hyphenate html #\-)
(xexpr->string (hyphenate (string->xexpr html) #\-))
]
If you're working with HTML, be careful not to include any @code{<script>} or @code{<style>} blocks, which contain non-hyphenatable data. You can protect that data by using the #:omit-tags parameter, which will skip over the listed tags.
@examples[#:eval my-eval
(hyphenate '(body "hyphenate" (script "don't hyphenate")) #\-)
(hyphenate '(body "hyphenate" (script "don't hyphenate")) #\-
#:omit-tags '(script))
]
@defproc[
(hyphenatef
@ -111,7 +118,8 @@ Don't send raw HTML or XML through @racket[hyphenate]. It can't distinguish tags
[pred procedure?]
[joiner (or/c char? string?) (integer->char \#x00AD)]
[#:exceptions exceptions (listof string?) empty]
[#:min-length length (or/c integer? false?) 5])
[#:min-length length (or/c integer? false?) 5]
[#:omit-tags tags (or/c null (listof txexpr-tag?)) null])
xexpr/c]
Like @racket[hyphenate], but only words matching @racket[_pred] are hyphenated. Convenient if you want to prevent hyphenation of certain sets of words, like proper names:

@ -24,3 +24,13 @@
(check-false (exception-word? "foobar!"))
(check-true (exception-word? "foo-bar"))
(check-false (exception-word? "foo bar"))
(check-equal? (hyphenate '(p "circular polymorphism" amp (em "squandering")) #:omit-tags '(em))
'(p "cir\u00ADcu\u00ADlar poly\u00ADmor\u00ADphism" amp (em "squandering")))
(check-equal? (hyphenate '(p "circular polymorphism" amp (em "squandering")) #:omit-tags '(p))
'(p "circular polymorphism" amp (em "squandering")))
(check-equal? (hyphenate '(p (foo "circular") (bar "circular") (zam "circular")) #:omit-tags '(foo zam))
'(p (foo "circular") (bar "cir\u00ADcu\u00ADlar") (zam "circular")))
Loading…
Cancel
Save