ledger-texi.el 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. ;;; ledger-texi.el --- Helper code for use with the "ledger" command-line tool
  2. ;; Copyright (C) 2003-2016 John Wiegley (johnw AT gnu DOT org)
  3. ;; This file is not part of GNU Emacs.
  4. ;; This is free software; you can redistribute it and/or modify it under
  5. ;; the terms of the GNU General Public License as published by the Free
  6. ;; Software Foundation; either version 2, or (at your option) any later
  7. ;; version.
  8. ;;
  9. ;; This is distributed in the hope that it will be useful, but WITHOUT
  10. ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. ;; for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  16. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. ;; MA 02110-1301 USA.
  18. (defgroup ledger-texi nil
  19. "Options for working on Ledger texi documentation"
  20. :group 'ledger)
  21. (defcustom ledger-texi-sample-doc-path "~/ledger/doc/sample.dat"
  22. "Location for sample data to be used in texi tests"
  23. :type 'file
  24. :group 'ledger-texi)
  25. (defcustom ledger-texi-normalization-args "--args-only --columns 80"
  26. "texi normalization for producing ledger output"
  27. :type 'string
  28. :group 'ledger-texi)
  29. (defun ledger-update-test ()
  30. (interactive)
  31. (goto-char (point-min))
  32. (let ((command (buffer-substring (point-min) (line-end-position)))
  33. input)
  34. (re-search-forward "^<<<\n")
  35. (let ((beg (point)) end)
  36. (re-search-forward "^>>>")
  37. (setq end (match-beginning 0))
  38. (forward-line 1)
  39. (let ((output-beg (point)))
  40. (re-search-forward "^>>>")
  41. (goto-char (match-beginning 0))
  42. (delete-region output-beg (point))
  43. (apply #'call-process-region
  44. beg end (expand-file-name "~/Products/ledger/debug/ledger")
  45. nil t nil
  46. "-f" "-" "--args-only" "--columns=80" "--no-color"
  47. (split-string command " "))))))
  48. (defun ledger-texi-write-test (name command input output &optional category)
  49. (let ((buf (current-buffer)))
  50. (with-current-buffer (find-file-noselect
  51. (expand-file-name (concat name ".test") category))
  52. (erase-buffer)
  53. (let ((case-fold-search nil))
  54. (if (string-match "\\$LEDGER\\s-+" command)
  55. (setq command (replace-match "" t t command)))
  56. (if (string-match " -f \\$\\([-a-z]+\\)" command)
  57. (setq command (replace-match "" t t command))))
  58. (insert command ?\n)
  59. (insert "<<<" ?\n)
  60. (insert input)
  61. (insert ">>>1" ?\n)
  62. (insert output)
  63. (insert ">>>2" ?\n)
  64. (insert "=== 0" ?\n)
  65. (save-buffer)
  66. (unless (eq buf (current-buffer))
  67. (kill-buffer (current-buffer))))))
  68. (defun ledger-texi-update-test ()
  69. (interactive)
  70. (let ((details (ledger-texi-test-details))
  71. (name (file-name-sans-extension
  72. (file-name-nondirectory (buffer-file-name)))))
  73. (ledger-texi-write-test
  74. name (nth 0 details)
  75. (nth 1 details)
  76. (ledger-texi-invoke-command
  77. (ledger-texi-expand-command
  78. (nth 0 details)
  79. (ledger-texi-write-test-data name (nth 1 details)))))))
  80. (defun ledger-texi-test-details ()
  81. (goto-char (point-min))
  82. (let ((command (buffer-substring (point) (line-end-position)))
  83. input output)
  84. (re-search-forward "^<<<")
  85. (let ((input-beg (1+ (match-end 0))))
  86. (re-search-forward "^>>>1")
  87. (let ((output-beg (1+ (match-end 0))))
  88. (setq input (buffer-substring input-beg (match-beginning 0)))
  89. (re-search-forward "^>>>2")
  90. (setq output (buffer-substring output-beg (match-beginning 0)))
  91. (list command input output)))))
  92. (defun ledger-texi-expand-command (command data-file)
  93. (if (string-match "\\$LEDGER" command)
  94. (replace-match (format "%s -f \"%s\" %s" ledger-binary-path
  95. data-file ledger-texi-normalization-args) t t command)
  96. (concat (format "%s -f \"%s\" %s " ledger-binary-path
  97. data-file ledger-texi-normalization-args) command)))
  98. (defun ledger-texi-invoke-command (command)
  99. (with-temp-buffer (shell-command command t (current-buffer))
  100. (if (= (point-min) (point-max))
  101. (progn
  102. (push-mark nil t)
  103. (message "Command '%s' yielded no result at %d" command (point))
  104. (ding))
  105. (buffer-string))))
  106. (defun ledger-texi-write-test-data (name input)
  107. (let ((path (expand-file-name name temporary-file-directory)))
  108. (with-current-buffer (find-file-noselect path)
  109. (erase-buffer)
  110. (insert input)
  111. (save-buffer))
  112. path))
  113. (defun ledger-texi-update-examples ()
  114. (interactive)
  115. (save-excursion
  116. (goto-char (point-min))
  117. (while (re-search-forward "^@c \\(\\(?:sm\\)?ex\\) \\(\\S-+\\): \\(.*\\)" nil t)
  118. (let ((section (match-string 1))
  119. (example-name (match-string 2))
  120. (command (match-string 3)) expanded-command
  121. (data-file ledger-texi-sample-doc-path)
  122. input output)
  123. (goto-char (match-end 0))
  124. (forward-line)
  125. (when (looking-at "@\\(\\(?:small\\)?example\\)")
  126. (let ((beg (point)))
  127. (re-search-forward "^@end \\(\\(?:small\\)?example\\)")
  128. (delete-region beg (1+ (point)))))
  129. (when (let ((case-fold-search nil))
  130. (string-match " -f \\$\\([-a-z]+\\)" command))
  131. (let ((label (match-string 1 command)))
  132. (setq command (replace-match "" t t command))
  133. (save-excursion
  134. (goto-char (point-min))
  135. (search-forward (format "@c data: %s" label))
  136. (re-search-forward "@\\(\\(?:small\\)?example\\)")
  137. (forward-line)
  138. (let ((beg (point)))
  139. (re-search-forward "@end \\(\\(?:small\\)?example\\)")
  140. (setq data-file (ledger-texi-write-test-data
  141. (format "%s.dat" label)
  142. (buffer-substring-no-properties
  143. beg (match-beginning 0))))))))
  144. (let ((section-name (if (string= section "smex")
  145. "smallexample"
  146. "example"))
  147. (output (ledger-texi-invoke-command
  148. (ledger-texi-expand-command command data-file))))
  149. (insert "@" section-name ?\n output
  150. "@end " section-name ?\n))
  151. ;; Update the regression test associated with this example
  152. (ledger-texi-write-test example-name command input output
  153. "../test/manual")))))
  154. (provide 'ledger-texi)