PageRenderTime 62ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lisp/nxml/rng-maint.el

https://gitlab.com/RobertCochran/emacs
Emacs Lisp | 270 lines | 217 code | 26 blank | 27 comment | 0 complexity | 6490558b4d865cadcbb25e79303b40cb MD5 | raw file
  1. ;;; rng-maint.el --- commands for RELAX NG maintainers -*- lexical-binding:t -*-
  2. ;; Copyright (C) 2003, 2007-2019 Free Software Foundation, Inc.
  3. ;; Author: James Clark
  4. ;; Keywords: wp, hypermedia, languages, XML, RelaxNG
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;; Code:
  18. (require 'xmltok)
  19. (require 'nxml-mode)
  20. (require 'texnfo-upd)
  21. (defvar rng-dir (file-name-directory load-file-name))
  22. ;;; Conversion from XML to texinfo.
  23. ;; This is all a hack and is just enough to make the conversion work.
  24. ;; It's not intended for public use.
  25. (defvar rng-manual-base "nxml-mode")
  26. (defvar rng-manual-xml (concat rng-manual-base ".xml"))
  27. (defvar rng-manual-texi (concat rng-manual-base ".texi"))
  28. (defvar rng-manual-info (concat rng-manual-base ".info"))
  29. (defun rng-format-manual ()
  30. "Create manual.texi from manual.xml."
  31. (interactive)
  32. (let ((xml-buf (find-file-noselect (expand-file-name rng-manual-xml
  33. rng-dir)))
  34. (texi-buf (find-file-noselect (expand-file-name rng-manual-texi
  35. rng-dir))))
  36. (with-current-buffer texi-buf
  37. (erase-buffer)
  38. (let ((standard-output texi-buf))
  39. (princ (format "\\input texinfo @c -*- texinfo -*-\n\
  40. @c %%**start of header\n\
  41. @setfilename %s\n\
  42. @settitle \n\
  43. @c %%**end of header\n" rng-manual-info))
  44. (set-buffer xml-buf)
  45. (goto-char (point-min))
  46. (xmltok-save
  47. (xmltok-forward-prolog)
  48. (rng-process-tokens))
  49. (princ "\n@bye\n"))
  50. (set-buffer texi-buf)
  51. (rng-manual-fixup)
  52. (texinfo-insert-node-lines (point-min) (point-max) t)
  53. (texinfo-all-menus-update)
  54. (save-buffer))))
  55. (defun rng-manual-fixup ()
  56. (goto-char (point-min))
  57. (search-forward "@top ")
  58. (let ((pos (point)))
  59. (search-forward "\n")
  60. (let ((title (buffer-substring-no-properties pos (1- (point)))))
  61. (goto-char (point-min))
  62. (search-forward "@settitle ")
  63. (insert title)
  64. (search-forward "@node")
  65. (goto-char (match-beginning 0))
  66. (insert "@dircategory Emacs\n"
  67. "@direntry\n* "
  68. title
  69. ": ("
  70. rng-manual-info
  71. ").\n@end direntry\n\n"))))
  72. (defvar rng-manual-inline-elements '(kbd key samp code var emph uref point))
  73. (defun rng-process-tokens ()
  74. (let ((section-depth 0)
  75. ;; stack of per-element space treatment
  76. ;; t means keep, nil means discard, fill means no blank lines
  77. (keep-space-stack (list nil))
  78. (ignore-following-newline nil)
  79. (want-blank-line nil)
  80. name startp endp data keep-space-for-children)
  81. (while (xmltok-forward)
  82. (cond ((memq xmltok-type '(start-tag empty-element end-tag))
  83. (setq startp (memq xmltok-type '(start-tag empty-element)))
  84. (setq endp (memq xmltok-type '(end-tag empty-element)))
  85. (setq name (intern (if startp
  86. (xmltok-start-tag-qname)
  87. (xmltok-end-tag-qname))))
  88. (setq keep-space-for-children nil)
  89. (setq ignore-following-newline nil)
  90. (cond ((memq name rng-manual-inline-elements)
  91. (when startp
  92. (when want-blank-line
  93. (rng-manual-output-force-blank-line)
  94. (when (eq want-blank-line 'noindent)
  95. (princ "@noindent\n"))
  96. (setq want-blank-line nil))
  97. (setq keep-space-for-children t)
  98. (princ (format "@%s{" name)))
  99. (when endp (princ "}")))
  100. ((eq name 'ulist)
  101. (when startp
  102. (rng-manual-output-force-blank-line)
  103. (setq want-blank-line nil)
  104. (princ "@itemize @bullet\n"))
  105. (when endp
  106. (rng-manual-output-force-new-line)
  107. (setq want-blank-line 'noindent)
  108. (princ "@end itemize\n")))
  109. ((eq name 'item)
  110. (rng-manual-output-force-new-line)
  111. (setq want-blank-line endp)
  112. (when startp (princ "@item\n")))
  113. ((memq name '(example display))
  114. (when startp
  115. (setq ignore-following-newline t)
  116. (rng-manual-output-force-blank-line)
  117. (setq want-blank-line nil)
  118. (setq keep-space-for-children t)
  119. (princ (format "@%s\n" name)))
  120. (when endp
  121. (rng-manual-output-force-new-line)
  122. (setq want-blank-line 'noindent)
  123. (princ (format "@end %s\n" name))))
  124. ((eq name 'para)
  125. (rng-manual-output-force-new-line)
  126. (when startp
  127. (when want-blank-line
  128. (setq want-blank-line t))
  129. (setq keep-space-for-children 'fill))
  130. (when endp (setq want-blank-line t)))
  131. ((eq name 'section)
  132. (when startp
  133. (rng-manual-output-force-blank-line)
  134. (when (eq section-depth 0)
  135. (princ "@node Top\n"))
  136. (princ "@")
  137. (princ (nth section-depth '(top
  138. chapter
  139. section
  140. subsection
  141. subsubsection)))
  142. (princ " ")
  143. (setq want-blank-line nil)
  144. (setq section-depth (1+ section-depth)))
  145. (when endp
  146. (rng-manual-output-force-new-line)
  147. (setq want-blank-line nil)
  148. (setq section-depth (1- section-depth))))
  149. ((eq name 'title)
  150. (when startp
  151. (setq keep-space-for-children 'fill))
  152. (when endp
  153. (setq want-blank-line t)
  154. (princ "\n"))))
  155. (when startp
  156. (setq keep-space-stack (cons keep-space-for-children
  157. keep-space-stack)))
  158. (when endp
  159. (setq keep-space-stack (cdr keep-space-stack))))
  160. ((memq xmltok-type '(data
  161. space
  162. char-ref
  163. entity-ref
  164. cdata-section))
  165. (setq data nil)
  166. (cond ((memq xmltok-type '(data space))
  167. (setq data (buffer-substring-no-properties xmltok-start
  168. (point))))
  169. ((and (memq xmltok-type '(char-ref entity-ref))
  170. xmltok-replacement)
  171. (setq data xmltok-replacement))
  172. ((eq xmltok-type 'cdata-section)
  173. (setq data
  174. (buffer-substring-no-properties (+ xmltok-start 9)
  175. (- (point) 3)))))
  176. (when (and data (car keep-space-stack))
  177. (setq data (replace-regexp-in-string "[@{}]"
  178. "@\\&"
  179. data
  180. t))
  181. (when ignore-following-newline
  182. (setq data (replace-regexp-in-string "\\`\n" "" data t)))
  183. (setq ignore-following-newline nil)
  184. ;; (when (eq (car keep-space-stack) 'fill)
  185. ;; (setq data (replace-regexp-in-string "\n" " " data t)))
  186. (when (eq want-blank-line 'noindent)
  187. (setq data (replace-regexp-in-string "\\`\n*" "" data t)))
  188. (when (> (length data) 0)
  189. (when want-blank-line
  190. (rng-manual-output-force-blank-line)
  191. (when (eq want-blank-line 'noindent)
  192. (princ "@noindent\n"))
  193. (setq want-blank-line nil))
  194. (princ data))))
  195. ))))
  196. (defun rng-manual-output-force-new-line ()
  197. (with-current-buffer standard-output
  198. (unless (eq (char-before) ?\n)
  199. (insert ?\n))))
  200. (defun rng-manual-output-force-blank-line ()
  201. (with-current-buffer standard-output
  202. (if (eq (char-before) ?\n)
  203. (unless (eq (char-before (1- (point))) ?\n)
  204. (insert ?\n))
  205. (insert "\n\n"))))
  206. ;;; Timing
  207. (defun rng-time-function (function &rest args)
  208. (let* ((start (current-time))
  209. (val (apply function args)))
  210. (message "%s ran in %g seconds"
  211. function (float-time (time-since start)))
  212. val))
  213. (defun rng-time-tokenize-buffer ()
  214. (interactive)
  215. (rng-time-function 'rng-tokenize-buffer))
  216. (defun rng-tokenize-buffer ()
  217. (save-excursion
  218. (goto-char (point-min))
  219. (xmltok-save
  220. (xmltok-forward-prolog)
  221. (while (xmltok-forward)))))
  222. (defun rng-time-validate-buffer ()
  223. (interactive)
  224. (rng-time-function 'rng-validate-buffer))
  225. (defvar rng-error-count)
  226. (defvar rng-validate-up-to-date-end)
  227. (declare-function rng-clear-cached-state "rng-valid" (start end))
  228. (declare-function rng-clear-overlays "rng-valid" (beg end))
  229. (declare-function rng-clear-conditional-region "rng-valid" ())
  230. (declare-function rng-do-some-validation "rng-valid"
  231. (&optional continue-p-function))
  232. (defun rng-validate-buffer ()
  233. (save-restriction
  234. (widen)
  235. (with-silent-modifications
  236. (rng-clear-cached-state (point-min) (point-max)))
  237. ;; 1+ to clear empty overlays at (point-max)
  238. (rng-clear-overlays (point-min) (1+ (point-max))))
  239. (setq rng-validate-up-to-date-end 1)
  240. (rng-clear-conditional-region)
  241. (setq rng-error-count 0)
  242. (while (rng-do-some-validation
  243. (lambda () t))))
  244. ;;; rng-maint.el ends here