build-html.scm 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. ;;; Copyright 2023 David Thompson
  2. ;;;
  3. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  4. ;;; you may not use this file except in compliance with the License.
  5. ;;; You may obtain a copy of the License at
  6. ;;;
  7. ;;; http://www.apache.org/licenses/LICENSE-2.0
  8. ;;;
  9. ;;; Unless required by applicable law or agreed to in writing, software
  10. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  11. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. ;;; See the License for the specific language governing permissions and
  13. ;;; limitations under the License.
  14. ;; Texinfo's 'makeinfo --html' command generates disappointing HTML.
  15. ;; To deal with it, we post-process the HTML files that it generates
  16. ;; to add in syntax highlighting and a better stylesheet.
  17. (use-modules (htmlprag)
  18. (ice-9 ftw)
  19. (ice-9 match)
  20. (srfi srfi-1)
  21. (syntax-highlight)
  22. (syntax-highlight scheme))
  23. (define %html-dir "hoot.html")
  24. (define %image-dir (string-append %html-dir "/images"))
  25. (define %css-file "hoot.css")
  26. ;; Work within the context of the docs directory.
  27. (chdir (dirname (current-filename)))
  28. ;; Generate the docs with makeinfo.
  29. (unless (zero? (system* "makeinfo" "--html" "-o" %html-dir "hoot.texi"))
  30. (error "failed to build manual"))
  31. ;; Copy our CSS file to the build artifact directory.
  32. (copy-file %css-file (string-append %html-dir "/" %css-file))
  33. ;; Gather up all the HTML files that were generated.
  34. (define html-files
  35. (filter-map (lambda (f)
  36. (and (string-suffix? ".html" f)
  37. (string-append %html-dir "/" f)))
  38. (scandir %html-dir)))
  39. ;; Post-process a single document.
  40. (define (prettify-sxml sxml)
  41. (match sxml
  42. ;; Add our stylesheet to the <head> section...
  43. (('head nodes ...)
  44. `(head ,@(map prettify-sxml nodes)
  45. (link (@ (rel "stylesheet")
  46. (href "hoot.css")))))
  47. ;; ...and remove the default style!
  48. (('style _ ...) "")
  49. ;; Highlight Scheme code.
  50. ((or ('pre ('@ ('class "lisp")) lines ...)
  51. ('div ('@ ('class "example lisp"))
  52. "\n"
  53. ('pre ('@ ('class "verbatim")) lines ...)))
  54. (let ((highlights (highlight lex-scheme (string-concatenate lines))))
  55. `(pre (@ (class "lisp"))
  56. ,@(highlights->sxml highlights))))
  57. ;; Leaf nodes.
  58. ((or (? symbol?) (? string?)) sxml)
  59. ;; Recursively descend through SXML nodes. Requires two cases:
  60. ;; One for nodes with attributes, and one for nodes without.
  61. (((? symbol? tag) ('@ attrs ...) nodes ...)
  62. (cons* tag
  63. (cons '@ attrs)
  64. (map prettify-sxml nodes)))
  65. (((? symbol? tag) nodes ...)
  66. (cons tag (map prettify-sxml nodes)))))
  67. ;; Parse HTML strictly.
  68. (%strict-tokenizer? #t)
  69. ;; Apply post-processing to all HTML files, overwriting their original
  70. ;; contents.
  71. (for-each (lambda (f)
  72. (let ((sxml (call-with-input-file f html->sxml)))
  73. (call-with-output-file f
  74. (lambda (port)
  75. (write-sxml-html (prettify-sxml sxml) port)))))
  76. html-files)