/collects/scribble/private/manual-vars.rkt

https://bitbucket.org/agocke/racket · Racket · 216 lines · 203 code · 12 blank · 1 comment · 30 complexity · b3b2c1e5ae2bb0bcc5d8cf32e805db72 MD5 · raw file

  1. #lang scheme/base
  2. (require "../decode.rkt"
  3. "../scheme.rkt"
  4. "../struct.rkt"
  5. (only-in "../core.rkt"
  6. make-style style-name style-properties
  7. nested-flow? nested-flow-blocks nested-flow-style
  8. make-nested-flow)
  9. "../html-properties.rkt"
  10. racket/contract/base
  11. (for-syntax scheme/base
  12. syntax/kerncase
  13. syntax/boundmap)
  14. (for-label scheme/base
  15. scheme/class))
  16. (define-struct (box-splice splice) ())
  17. (provide/contract
  18. [struct (box-splice splice) ([run list?])]) ; XXX ugly copying
  19. (provide deftogether *deftogether
  20. with-racket-variables
  21. with-togetherable-racket-variables
  22. vertical-inset-style
  23. boxed-style
  24. add-background-label)
  25. (define vertical-inset-style
  26. (make-style 'vertical-inset null))
  27. (define boxed-style
  28. (make-style 'boxed (list (make-attributes (list (cons 'class "RBoxed"))))))
  29. (define ((add-background-label what) l)
  30. (list
  31. (make-nested-flow
  32. (make-style "RBackgroundLabel" (list 'decorative 'command (alt-tag "div")
  33. (make-attributes '((class . "SIEHidden")))))
  34. (list
  35. (make-nested-flow
  36. (make-style "RBackgroundLabelInner" (list (alt-tag "div")))
  37. (list (make-omitable-paragraph what)))))
  38. (let* ([a (car l)]
  39. [remake (if (paragraph? a)
  40. (lambda (sa)
  41. (paragraph
  42. (sa (paragraph-style a))
  43. (paragraph-content a)))
  44. (lambda (sa)
  45. (table
  46. (sa (table-style a))
  47. (table-blockss a))))])
  48. (remake
  49. (lambda (s)
  50. (make-style (style-name s)
  51. (let ([p (style-properties s)])
  52. (if (ormap attributes? p)
  53. (for/list ([i (in-list p)])
  54. (if (attributes? i)
  55. (let ([al (attributes-assoc i)])
  56. (if (assq 'class al)
  57. (for/list ([a (in-list al)])
  58. (if (eq? (car a) 'class)
  59. (cons 'class (string-append (cdr a) " RForeground"))
  60. a))
  61. (attributes (cons '(class . "RForeground")
  62. al))))
  63. i))
  64. (cons (attributes '((class . "RForeground")))
  65. p)))))))))
  66. (begin-for-syntax (define-struct deftogether-tag () #:omit-define-syntaxes))
  67. (define-syntax (with-togetherable-racket-variables stx)
  68. (syntax-case stx ()
  69. [(_ lits vars decl)
  70. (with-syntax ([vars (syntax-property #'vars 'taint-mode 'none)])
  71. (syntax-property
  72. #'(with-togetherable-racket-variables* lits vars decl)
  73. 'taint-mode
  74. 'transparent))]))
  75. (define-syntax-rule (with-togetherable-racket-variables* . rest)
  76. (with-racket-variables . rest))
  77. (define-syntax (with-racket-variables stx)
  78. (syntax-case stx ()
  79. [(_ lits ([kind s-exp] ...) body)
  80. (let ([ht (make-bound-identifier-mapping)]
  81. [lits (syntax->datum #'lits)])
  82. (for-each (lambda (kind s-exp)
  83. (case (syntax-e kind)
  84. [(proc)
  85. (letrec ([do-proc
  86. (lambda (s-exp)
  87. (let ([s-exp (syntax->list s-exp)])
  88. (for-each
  89. (lambda (arg)
  90. (if (identifier? arg)
  91. (unless (or (eq? (syntax-e arg) '...)
  92. (eq? (syntax-e arg) '...+)
  93. (eq? (syntax-e arg) '_...superclass-args...)
  94. (memq (syntax-e arg) lits))
  95. (bound-identifier-mapping-put! ht arg #t))
  96. (syntax-case arg ()
  97. [(kw arg . rest)
  98. (keyword? (syntax-e #'kw))
  99. (bound-identifier-mapping-put! ht #'arg #t)]
  100. [(arg . rest)
  101. (identifier? #'arg)
  102. (bound-identifier-mapping-put! ht #'arg #t)])))
  103. (cdr s-exp))
  104. (unless (identifier? (car s-exp))
  105. ;; Curried:
  106. (do-proc (car s-exp)))))])
  107. (do-proc s-exp))]
  108. [(form form/none form/maybe non-term)
  109. (define skip-id (case (syntax-e kind)
  110. [(form)
  111. (syntax-case s-exp ()
  112. [(defined-id actual-s-exp) (let ([id #'defined-id])
  113. (and (identifier? id)
  114. id))]
  115. [_ #f])]
  116. [else #f]))
  117. (let loop ([form (case (syntax-e kind)
  118. [(form)
  119. (syntax-case s-exp ()
  120. [(defined-id actual-s-exp) #'actual-s-exp])]
  121. [(form/none) s-exp]
  122. [(form/maybe)
  123. (syntax-case s-exp ()
  124. [(#f form) #'form]
  125. [(#t (id . form)) #'form])]
  126. [(non-term) s-exp])])
  127. (if (identifier? form)
  128. (unless (or (and skip-id
  129. (free-identifier=? skip-id form))
  130. (eq? (syntax-e form) '...)
  131. (eq? (syntax-e form) '...+)
  132. (eq? (syntax-e form) 'code:line)
  133. (eq? (syntax-e form) 'code:blank)
  134. (eq? (syntax-e form) 'code:comment)
  135. (eq? (syntax-e form) '?)
  136. (memq (syntax-e form) lits))
  137. (bound-identifier-mapping-put! ht form #t))
  138. (syntax-case form (unsyntax)
  139. [(unsyntax _) (void)]
  140. [(a . b) (loop #'a) (loop #'b)]
  141. [#(a ...) (loop #'(a ...))]
  142. [_ (void)])))]
  143. [else
  144. (raise-syntax-error
  145. #f
  146. "unknown variable mode"
  147. stx
  148. kind)]))
  149. (syntax->list #'(kind ...))
  150. (syntax->list #'(s-exp ...)))
  151. (with-syntax ([(id ...) (bound-identifier-mapping-map ht (lambda (k v) k))])
  152. #'(letrec-syntaxes ([(id) (make-variable-id 'id)] ...)
  153. body)))]))
  154. (define (*deftogether boxes body-thunk)
  155. (make-box-splice
  156. (cons
  157. (make-blockquote
  158. vertical-inset-style
  159. (list
  160. (make-table
  161. boxed-style
  162. (map
  163. (lambda (box)
  164. (unless (and (box-splice? box)
  165. (= 1 (length (splice-run box)))
  166. (nested-flow? (car (splice-run box)))
  167. (eq? vertical-inset-style (nested-flow-style (car (splice-run box))))
  168. (let ([l (nested-flow-blocks (car (splice-run box)))])
  169. (= 1 (length l))
  170. (table? (car l))
  171. (eq? boxed-style (table-style (car l)))))
  172. (error 'deftogether
  173. "element is not a boxing splice containing a single nested-flow with a single table: ~e"
  174. box))
  175. (list (make-flow (list (make-table
  176. "together"
  177. (table-flowss (car (nested-flow-blocks (car (splice-run box))))))))))
  178. boxes))))
  179. (body-thunk))))
  180. (define-syntax (deftogether stx)
  181. (syntax-case stx ()
  182. [(_ (def ...) . body)
  183. (with-syntax ([((_ (lit ...) (var ...) decl) ...)
  184. (map (lambda (def)
  185. (let ([exp-def (local-expand
  186. def
  187. (list (make-deftogether-tag))
  188. (cons
  189. #'with-togetherable-racket-variables*
  190. (kernel-form-identifier-list)))])
  191. (syntax-case exp-def (with-togetherable-racket-variables*)
  192. [(with-togetherable-racket-variables* lits vars decl)
  193. exp-def]
  194. [_
  195. (raise-syntax-error
  196. #f
  197. "sub-form is not a documentation form that can be combined"
  198. stx
  199. def)])))
  200. (syntax->list #'(def ...)))])
  201. #'(with-togetherable-racket-variables
  202. (lit ... ...)
  203. (var ... ...)
  204. (*deftogether (list decl ...) (lambda () (list . body)))))]))