Re: [PATCH 2/2] ox-texinfo: Define definition commands using description lists

2022-01-05 Thread Jonas Bernoulli
Nicolas Goaziou  writes:

> Hello,
>
> Jonas Bernoulli  writes:
>
>> Would it be okay to represent e.g. "C-c SPC" as:
>>
>>(export-snippet
>> (:back-end "texinfo" :value "@kbd{C-c @key{SPC}}" :post-blank 0 :parent 
>> #2))
>
> Just use (org-export-raw-string "@kbd{C-c @key{SPC}}") instead.

That works.  I must of done something wrong when first trying that.

>> I think that is one of the things I tried that ox-texinfo insisted on
>> quoting anyway.  I might misremember, so I will have another look.
>
> `org-export-raw-string' is a recent addition in Org.
>
>> Above I suggested using an `export-snippet' element (instead of `raw');
>> to me that seems appropriate too.
>
> I think that's abusing export snippets. They are more user-oriented,
> e.g. filters can apply to them.
>
> Note you can write (org-export-raw-string (some-public-function "C-c
> SPC")) where (some-public-function "C-c SPC") => "@kbd{C-c @key{SPC}}",
> as done currently by the "kbd" macro.

I named it org-texinfo-kbd-macro and wrote it so that it can be used by
the kbd macro.  I have changed doc/doc-setup.org to use it.

DEL was missing from the list of special keys.

 Cheers,
 Jonas



Re: [PATCH 2/2] ox-texinfo: Define definition commands using description lists

2021-12-29 Thread Nicolas Goaziou
Hello,

Jonas Bernoulli  writes:

> Would it be okay to represent e.g. "C-c SPC" as:
>
>(export-snippet
> (:back-end "texinfo" :value "@kbd{C-c @key{SPC}}" :post-blank 0 :parent 
> #2))

Just use (org-export-raw-string "@kbd{C-c @key{SPC}}") instead.

> I think that is one of the things I tried that ox-texinfo insisted on
> quoting anyway.  I might misremember, so I will have another look.

`org-export-raw-string' is a recent addition in Org.

> Above I suggested using an `export-snippet' element (instead of `raw');
> to me that seems appropriate too.

I think that's abusing export snippets. They are more user-oriented,
e.g. filters can apply to them.

Note you can write (org-export-raw-string (some-public-function "C-c
SPC")) where (some-public-function "C-c SPC") => "@kbd{C-c @key{SPC}}",
as done currently by the "kbd" macro.

Regards,
-- 
Nicolas Goaziou



Re: [PATCH 2/2] ox-texinfo: Define definition commands using description lists

2021-12-27 Thread Jonas Bernoulli
Nicolas Goaziou  writes:

> There's a mismatch between the keys.

Fixed.

> Simply put:
>
> Command in parenthesis, as done above, is optional.

Done.

>> +Regardless of which approach you use, you must define the =kbd= macro
>> +(see [[*Macro Replacement]]), which you can then use anywhere in the Org
>> +file:
>> +
>> +#+begin_example
>> +,#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt 
>> '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" 
>> "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format 
>> "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp 
>> "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t
>>  #+end_example
>
> Ouch. I don't think we should expect users to define this in order to
> use the feature being implemented. IOW, it should work out of the box.

Luckily that's already how it works; I just chose to not document the
fallback (done that now).  If the macro is not available, then @code{}
is used instead.

> I think the functions responsible for generating the Texinfo code should
> handle this without relying on the macro.

I tried but could not get it to work that way.  Whatever I tried
ox-texinfo insisted on breaking it by adding quotes.

I didn't go as far as to try injecting export-snippet elements into the
tree because without using org-macro-replace-all it seemed painful to do
that.  But on second thought...

Would it be okay to represent e.g. "C-c SPC" as:

   (export-snippet
(:back-end "texinfo" :value "@kbd{C-c @key{SPC}}" :post-blank 0 :parent #2))

instead of the more painful to construct:

   (export-snippet
(:back-end "texinfo" :value "@kbd{" :begin 317 :end 334 :post-blank 0 
:parent #2))
   #("C-c " 0 4
 (:parent #2))
   (export-snippet
(:back-end "texinfo" :value "@key{" :begin 338 :end 355 :post-blank 0 
:parent #2))
   #("SPC" 0 3
 (:parent #2))
   (export-snippet
(:back-end "texinfo" :value "}" :begin 358 :end 371 :post-blank 0 :parent 
#2))
   (export-snippet
(:back-end "texinfo" :value "}" :begin 371 :end 384 :post-blank 0 :parent 
#2))

> Of course, if that part is
> factored out, the macro might, in turn, make use of it.

>> +(defconst org-texinfo--definition-command-regexp
>> +  (format "\\`%s: \\(.+\\)"
>> +  (regexp-opt
>> +   (delq nil (mapcar #'cdr org-texinfo--definition-command-alist))
>> +   1))
>
> What is 1 meaning here? Do you mean t?

Yes. Done.

>> +(defun org-texinfo--separate-definitions (tree _backend info)
>> +  "Split up descriptive lists that contain Texinfo definition
>> commands."
>
> You need to document the arguments.
>> +  (org-element-map tree 'plain-list
>> +(lambda (plain-list)
>> +  (when (eq (org-element-property :type plain-list) 'descriptive)
>> +(let ((contents (org-element-contents plain-list))
>> +  item items)
>
> Nitpick: (items nil)

Done.

>> +  (while (setq item (pop contents))
>
> nitpick: Use dolist.

Err, that's what I would usually do.  Not sure why not here.

Done.

>> +(if (string-match " +(\\([^()]+\\)) *\\'" args)
>
> Could you use `rx' here?

Done.

(Not a fan personally.  IMO rx is less readable than a plain old
regexp, though that's probably just because I never took the time
to retrain myself.)

>> +(setq key (substring args 0 (match-beginning 0))
>> +  cmd (match-string 1 args))
>> +  (setq key args))
>> +(org-element-put-property
>> + item :tag
>> + (nconc (if (assoc "kbd" org-macro-templates)
>> +(let ((templates org-macro-templates))
>> +  (with-temp-buffer
>> +(insert (format "{{{kbd(%s)}}}" key))
>
> Here, there could be a function building the key chord, and you could
> wrap the result into a raw string (see `org-export-raw-string').

I think that is one of the things I tried that ox-texinfo insisted on
quoting anyway.  I might misremember, so I will have another look.
Above I suggested using an `export-snippet' element (instead of `raw');
to me that seems appropriate too.

 Cheers,
 Jonas



Re: [PATCH 2/2] ox-texinfo: Define definition commands using description lists

2021-12-26 Thread Nicolas Goaziou
Hello,

Thanks.

Jonas Bernoulli  writes:

> +#+begin_example
> +- Key: C-n (do-something) ::
> +  This command does something.
> +
> +- User Option: do-something-somehow ::
> +  This option controls how exactly ~do-something~ does its thing.
> +#+end_example
> +
> +#+texinfo: @noindent
> +becomes
> +
> +#+begin_example
> +@table @asis
> +@item @kbd{C-c C-c} (@code{do-something})
> +@kindex C-c C-c
> +@findex do-something
> +This command does something.
> +@end table

There's a mismatch between the keys.

> +Key items don't have to specify the respective command in parenthesis
> +as done above; that part is optional.

Simply put:

Command in parenthesis, as done above, is optional.

> +Regardless of which approach you use, you must define the =kbd= macro
> +(see [[*Macro Replacement]]), which you can then use anywhere in the Org
> +file:
> +
> +#+begin_example
> +,#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" 
> "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" 
> "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format 
> "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp 
> "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t
>  #+end_example

Ouch. I don't think we should expect users to define this in order to
use the feature being implemented. IOW, it should work out of the box.

I think the functions responsible for generating the Texinfo code should
handle this without relying on the macro. Of course, if that part is
factored out, the macro might, in turn, make use of it.

> +(defconst org-texinfo--definition-command-regexp
> +  (format "\\`%s: \\(.+\\)"
> +  (regexp-opt
> +   (delq nil (mapcar #'cdr org-texinfo--definition-command-alist))
> +   1))

What is 1 meaning here? Do you mean t?


> +(defun org-texinfo--separate-definitions (tree _backend info)
> +  "Split up descriptive lists that contain Texinfo definition
> commands."

You need to document the arguments.
> +  (org-element-map tree 'plain-list
> +(lambda (plain-list)
> +  (when (eq (org-element-property :type plain-list) 'descriptive)
> +(let ((contents (org-element-contents plain-list))
> +  item items)

Nitpick: (items nil)

> +  (while (setq item (pop contents))

nitpick: Use dolist.

> +(pcase-let ((`(,cmd . ,args) (org-texinfo--match-definition 
> item)))
> +  (cond
> +   (cmd
> +(when items
> +  (org-texinfo--split-plain-list plain-list (nreverse items))
> +  (setq items nil))
> +(org-texinfo--split-definition plain-list item cmd args))
> +   (t
> +(when args
> +  (org-texinfo--massage-key-item plain-list item args))
> +(push item items)
> +  (unless (org-element-contents plain-list)
> +(org-element-extract-element plain-list)
> +info)
> +  tree)
> +
> +(defun org-texinfo--match-definition (item)
> +  "Return a cons-cell if ITEM specifies a Texinfo definition command.
> +The car is the command and the cdr is its arguments."
> +  (let ((tag (car-safe (org-element-property :tag item
> +(and tag
> + (stringp tag)
> + (string-match org-texinfo--definition-command-regexp tag)
> + (pcase-let*
> + ((cmd (car (rassoc (match-string-no-properties 1 tag)
> + org-texinfo--definition-command-alist)))
> +  (`(,cmd ,category)
> +   (and cmd (save-match-data (split-string cmd " "
> +  (args (match-string-no-properties 2 tag)))
> +   (cons cmd (if category (concat category " " args) args))
> +
> +(defun org-texinfo--split-definition (plain-list item cmd args)
> +  "Insert a definition command before list PLAIN-LIST.
> +Replace list item ITEM with a special-block that inherits the
> +contents of ITEM and whose type and Texinfo attributes are
> +specified by CMD and ARGS."
> +  (let ((contents (org-element-contents item)))
> +(org-element-insert-before
> + (apply #'org-element-create 'special-block
> +(list :type cmd
> +  :attr_texinfo (list (format ":options %s" args))
> +  :post-blank (if contents 1 0))
> +(mapc #'org-element-extract-element contents))
> + plain-list))
> +  (org-element-extract-element item))
> +
> +(defun org-texinfo--split-plain-list (plain-list items)
> +  "Insert a new plain list before the plain list PLAIN-LIST.
> +Remove ITEMS from PLAIN-LIST and use them as the contents of the
> +new plain list."
> +  (org-element-insert-before
> +   (apply #'org-element-create 'plain-list
> +  (list :type 'descriptive :post-blank 1)
> +  (mapc #'org-element-extract-element items))
> +   plain-list))
> +
> +(defun org-texinfo--massage-key-item (plain-list item args)
> +  "In PLAIN-LIST modify ITEM based on ARGS.
> +Reformat ITEM'