summaryrefslogtreecommitdiff
path: root/manpages/TDM.el
blob: b4fabc7a3959e4a4cd0db5c093a97a2570aad445 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
;;; TDM.el --- editing Taler docs.git/manpages/*   -*- lexical-binding: t -*-

;; Copyright (C) 2021 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 one command: ‘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.

;;; 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)))))

(provide 'TDM)

;;; TDM.el ends here