diff options
Diffstat (limited to 'manpages/TDM.el')
-rw-r--r-- | manpages/TDM.el | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/manpages/TDM.el b/manpages/TDM.el new file mode 100644 index 00000000..a58fb1c8 --- /dev/null +++ b/manpages/TDM.el @@ -0,0 +1,172 @@ +;;; TDM.el --- editing Taler docs.git/manpages/* -*- lexical-binding: t -*- + +;; Copyright (C) 2021, 2022 Taler Systems SA +;; +;; This file is part of GNU TALER. +;; +;; TALER is free software; you can redistribute it and/or modify it +;; under the terms of the GNU Affero General Public License as +;; published by the Free Software Foundation; either version 2.1, +;; or (at your option) any later version. +;; +;; TALER is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU Affero General Public License for more details. +;; +;; You should have received a copy of the GNU Affero General Public +;; License along with TALER; see the file COPYING. If not, see +;; <http://www.gnu.org/licenses/>. +;; +;; Author: Thien-Thi Nguyen <ttn@gnu.org> + +;;; Commentary: + +;; This library currently provides two commands: ‘TDM-convert-options’ +;; and ‘TDM-recursive-help’. +;; +;; * ‘TDM-convert-options’ +;; The intended workflow is simple: +;; - Create a new file from template. +;; - Do the <FOO> substitutions / deletions as necessary. +;; - Split the window, one half for Synopsis, one for Description. +;; - Do ‘COMMAND --help’ and copy the portion of its output that +;; describes the options into the buffer in the Synopsis section. +;; + Place point at bol of an option and call ‘TDM-convert-options’. +;; (Personally, I locally bind this to ‘C-c C-o’.) +;; - Set mark at point and move point to the end of the +;; description text (for that option). +;; - Kill the region (with ‘C-w’). +;; - Switch to the other window, find a suitable place, and +;; yank (with ‘C-y’) the text there. +;; - Edit the description as necessary. +;; - Loop from "+" until finished. +;; +;; At the end, you may have to delete some extra blank lines +;; in the Synopsis section. +;; +;; ‘TDM-convert-options’ takes a prefix arg, which inhibits the +;; deletion of the original (--help output) text. This can be +;; useful if you don't trust (yet :-D) the conversion process. +;; +;; There are a couple TODO items, which point to situations that +;; have not yet arisen in practice, but that might theoretically +;; bother us in the future. +;; +;; * ‘TDM-recursive-help’ +;; This command is intended for libeufin programs, specifically +;; libeufin-sandbox, libeufin-nexus, and libeufin-cli. However, +;; it should work with any Java program that uses clikt, or any +;; Python program that uses click, for its command-line handling. +;; +;; You can obtain the --help output (recursively) in a buffer +;; and write it to a file for further analysis / processing. + +;;; Code: + +(require 'cl-lib) + +(defun TDM-parse-option-triple () + "Return a triple formed by parsing option text at point. +The triple has the form (ARG SHORT LONG), where each element +can be either a string or ‘nil’. + +Signal error if parsing fails. +Leave point after the end of the parsed text." + (cl-flet ((peer (regexp) + (re-search-forward regexp (line-end-position) t))) + (cond + ;; Full form: (ARG SHORT LONG). + ((peer " *-\\(.\\), --\\([^=\n]+\\)=\\(\\S +\\)") + (mapcar #'match-string-no-properties (list 3 1 2))) + ;; No argument: (nil SHORT LONG). + ((peer " *-\\(.\\), --\\(\\S +\\)") + (list nil + (match-string-no-properties 1) + (match-string-no-properties 2))) + ;; TODO: Handle other combinations. + (t + (error "Could not parse option text"))))) + +(defun TDM-insert-options (arg short long) + "Insert formatted options, twice (on two lines). +The first is for the Synopsis section, the second for Description." + (unless (zerop (current-column)) + (open-line 1) + (forward-line 1)) + (cl-flet ((ins (short-space sep) + (cond + ;; Both available. + ((and short long) + (insert "**-" short "**") + (when arg + (insert short-space "*" arg "*")) + (insert sep) + (insert "**--" long (if arg "=" "") "**") + (when arg + (insert "\\ \\ *" arg "*"))) + ;; TODO: Handle other combinations. + (t + (error "Could not handle (%S %S %S)" + arg short long))))) + ;; First line. + (insert "[") + (ins " " " | ") + (insert "]\n") + ;; Second line. Leave point at its beginning. + (save-excursion + (ins " " " \\| ") + ;; Add a newline only if necessary. + (unless (eolp) + (insert "\n"))))) + +(defun TDM-convert-options (&optional keep-orig) + "Grok the options at point and insert formatted ones. +If successful, delete the parsed options as well. +Prefix arg KEEP-ORIG means don't delete them." + (interactive "P") + (let* ((p (point)) + (triple (TDM-parse-option-triple)) + (q (point))) + (apply #'TDM-insert-options triple) + (unless keep-orig + (save-excursion + (delete-region p q))))) + +(defun TDM-recursive-help (command) + "Call COMMAND --help and recurse on its subcommands. +Subcommands are identified by \"Commands:\" in column 0 +in the output. + +Collect the output in a new buffer *COMMAND --help*, +with one page per --help output." + (interactive "sCommand: ") + (let ((out (get-buffer-create (format "*%s --help*" command)))) + (with-current-buffer out + (erase-buffer)) + (cl-labels + ;; visit command + ((v (c) (with-temp-buffer + (apply #'call-process (car c) nil t nil + (append (cdr c) (list "--help"))) + (goto-char (point-min)) + (when (re-search-forward "^Commands:\n" nil t) + (while (looking-at "[ ][ ]\\(\\S +\\)") + (let ((sub (match-string 1))) + (v (append c (list sub)))) + (forward-line 1) + (while (looking-at "[ ][ ][ ]") + (forward-line 1)))) + (let ((s (buffer-string))) + (message "c: %s" c) + (with-current-buffer out + (goto-char (point-min)) + (insert "\f\n") + (insert "$ " (substring (format "%s" c) 1 -1) "\n") + (insert s "\n")))))) + (v (list command))) + (switch-to-buffer out))) + +(provide 'TDM) + +;;; TDM.el ends here |