/collects/scribble/run.rkt

http://github.com/gmarceau/PLT · Racket · 148 lines · 140 code · 8 blank · 0 comment · 15 complexity · 3350fd4c4500f8d6bff7e226bf3a0d8f MD5 · raw file

  1. #lang racket/base
  2. (require "core.rkt"
  3. "base-render.rkt"
  4. "xref.rkt"
  5. scheme/cmdline
  6. scheme/file
  7. scheme/class
  8. raco/command-name
  9. (prefix-in text: "text-render.rkt")
  10. (prefix-in html: "html-render.rkt")
  11. (prefix-in latex: "latex-render.rkt")
  12. (prefix-in pdf: "pdf-render.rkt"))
  13. (define multi-html:render-mixin
  14. (lambda (%) (html:render-multi-mixin (html:render-mixin %))))
  15. (define current-render-mixin (make-parameter text:render-mixin))
  16. (define current-dest-directory (make-parameter #f))
  17. (define current-dest-name (make-parameter #f))
  18. (define current-info-output-file (make-parameter #f))
  19. (define current-info-input-files (make-parameter null))
  20. (define current-xref-input-modules (make-parameter null))
  21. (define current-prefix-file (make-parameter #f))
  22. (define current-style-file (make-parameter #f))
  23. (define current-style-extra-files (make-parameter null))
  24. (define current-extra-files (make-parameter null))
  25. (define current-redirect (make-parameter #f))
  26. (define current-redirect-main (make-parameter #f))
  27. (define current-quiet (make-parameter #f))
  28. (define (read-one str)
  29. (let ([i (open-input-string str)])
  30. (with-handlers ([exn:fail:read? (lambda (x) #f)])
  31. (let ([v (read i)])
  32. (and (eof-object? (read i)) v)))))
  33. (current-render-mixin html:render-mixin)
  34. (define (run)
  35. (command-line
  36. #:program (short-program+command-name)
  37. #:once-any
  38. [("--text") "generate text-format output (the default)"
  39. (current-render-mixin text:render-mixin)]
  40. [("--html") "generate HTML-format output file"
  41. (current-render-mixin html:render-mixin)]
  42. [("--htmls") "generate HTML-format output directory"
  43. (current-render-mixin multi-html:render-mixin)]
  44. [("--latex") "generate LaTeX-format output"
  45. (current-render-mixin latex:render-mixin)]
  46. [("--pdf") "generate PDF-format output (with PDFLaTeX)"
  47. (current-render-mixin pdf:render-mixin)]
  48. [("--latex-section") n "generate LaTeX-format output for section depth <n>"
  49. (let ([v (string->number n)])
  50. (unless (exact-nonnegative-integer? v)
  51. (raise-user-error 'scribble (format "bad section depth: ~a" n)))
  52. (current-render-mixin (latex:make-render-part-mixin v)))]
  53. #:once-each
  54. [("--dest") dir "write output in <dir>"
  55. (current-dest-directory dir)]
  56. [("--dest-name") name "write output as <name>"
  57. (current-dest-name name)]
  58. #:multi
  59. [("++style") file "add given .css/.tex file after others"
  60. (current-style-extra-files (cons file (current-style-extra-files)))]
  61. #:once-each
  62. [("--style") file "use given base .css/.tex file"
  63. (current-style-file file)]
  64. [("--prefix") file "use given .html/.tex prefix (for doctype/documentclass)"
  65. (current-prefix-file file)]
  66. #:multi
  67. [("++extra") file "add given file"
  68. (current-extra-files (cons file (current-extra-files)))]
  69. [("--redirect-main") url "redirect main doc links to <url>"
  70. (current-redirect-main url)]
  71. [("--redirect") url "redirect external links to tag search via <url>"
  72. (current-redirect url)]
  73. [("++xref-in") module-path proc-id "load format-specific cross-ref info by"
  74. "calling <proc-id> as exported by <module-path>"
  75. (let ([mod (read-one module-path)]
  76. [id (read-one proc-id)])
  77. (unless (module-path? mod)
  78. (raise-user-error
  79. 'scribble "bad module path for ++ref-in: ~s" module-path))
  80. (unless (symbol? id)
  81. (raise-user-error
  82. 'scribble "bad procedure identifier for ++ref-in: ~s" proc-id))
  83. (current-xref-input-modules
  84. (cons (cons mod id) (current-xref-input-modules))))]
  85. [("--info-out") file "write format-specific cross-ref info to <file>"
  86. (current-info-output-file file)]
  87. [("++info-in") file "load format-specific cross-ref info from <file>"
  88. (current-info-input-files
  89. (cons file (current-info-input-files)))]
  90. #:once-each
  91. [("--quiet") "suppress output-file reporting"
  92. (current-quiet #t)]
  93. #:args (file . another-file)
  94. (let ([files (cons file another-file)])
  95. (build-docs (map (lambda (file) (dynamic-require `(file ,file) 'doc))
  96. files)
  97. files))))
  98. (define (build-docs docs files)
  99. (define dir (current-dest-directory))
  100. (when dir (make-directory* dir))
  101. (let ([renderer (new ((current-render-mixin) render%)
  102. [dest-dir dir]
  103. [prefix-file (current-prefix-file)]
  104. [style-file (current-style-file)]
  105. [style-extra-files (reverse (current-style-extra-files))]
  106. [extra-files (reverse (current-extra-files))])])
  107. (when (current-redirect)
  108. (send renderer set-external-tag-path (current-redirect)))
  109. (when (current-redirect-main)
  110. (send renderer set-external-root-url (current-redirect-main)))
  111. (unless (current-quiet)
  112. (send renderer report-output!))
  113. (let* ([fns (map (lambda (fn)
  114. (let-values ([(base name dir?) (split-path fn)])
  115. (let ([fn (path-replace-suffix
  116. (or (current-dest-name) name)
  117. (send renderer get-suffix))])
  118. (if dir (build-path dir fn) fn))))
  119. files)]
  120. [fp (send renderer traverse docs fns)]
  121. [info (send renderer collect docs fns fp)])
  122. (for ([file (in-list (reverse (current-info-input-files)))])
  123. (let ([s (with-input-from-file file read)])
  124. (send renderer deserialize-info s info)))
  125. (for ([mod+id (in-list (reverse (current-xref-input-modules)))])
  126. (let* ([get-xref (dynamic-require (car mod+id) (cdr mod+id))]
  127. [xr (get-xref)])
  128. (unless (xref? xr)
  129. (raise-user-error
  130. 'scribble "result from `~s' of `~s' is not an xref: ~e"
  131. (cdr mod+id) (car mod+id) xr))
  132. (xref-transfer-info renderer info xr)))
  133. (let ([r-info (send renderer resolve docs fns info)])
  134. (send renderer render docs fns r-info)
  135. (when (current-info-output-file)
  136. (let ([s (send renderer serialize-info r-info)])
  137. (with-output-to-file (current-info-output-file)
  138. #:exists 'truncate/replace
  139. (lambda () (write s)))))))))
  140. (run)