;;; 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
;; .
;;
;; Author: Thien-Thi Nguyen
;;; Commentary:
;; This library currently provides one command: ‘TDM-convert-options’.
;; The intended workflow is simple:
;; - Create a new file from template.
;; - Do the 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