[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Startup option to separate macros arguments with an alternat
From: |
Juan Manuel Macías |
Subject: |
Re: [PATCH] Startup option to separate macros arguments with an alternative string |
Date: |
Wed, 21 Apr 2021 16:01:35 +0000 |
Hello again.
I forgot to answer this question on your previous message, sorry...
Nicolas Goaziou writes:
> That being said, we can discuss syntax that is not depending upon some
> variable. For example macro names are written with a limited set of
> characters (alphanumeric, dash, underscore). We might allow the optional
> argument separator to be located right before the opening parenthesis,
> e.g.,
>
> {{{macroname@(latin@Lorem ipsum dolor sit amet, ...)}}}
> {{{macroname|(latin|Lorem ipsum dolor sit amet, ...)}}}
I think it's a very interesting idea. I've made this sketch (at least
as a proof of concept), what do you think of the approach?
Example (and code below):
#+macro: foo (eval (format "%s and %s" $1 $2))
{{{foo(xxx,zzz\, yyy)}}}
{{{foo|(xxx|zzz, aaa)}}}
{{{foo@(xxx@zzz, sss)}}}
{{{foo|(xxx|zzz\| aaa)}}}
{{{foo@(xxx@zzz\@ sss)}}}
#+begin_src emacs-lisp
(defun org-macro-extract-arguments (sep s)
"Extract macro arguments from string S.
S is a string containing comma separated values properly escaped.
Return a list of arguments, as strings. This is the opposite of
`org-macro-escape-arguments'."
;; Do not use `org-split-string' since empty strings are
;; meaningful here.
(split-string
(replace-regexp-in-string
(format "\\(\\\\*\\)%s" sep)
(lambda (str)
(let ((len (length (match-string 1 str))))
(concat (make-string (/ len 2) ?\\)
(if (zerop (mod len 2)) "\000" (format "%s" sep)))))
s nil t)
"\000"))
(defun org-element-macro-parser ()
"Parse macro at point, if any.
When at a macro, return a list whose car is `macro' and cdr
a plist with `:key', `:args', `:begin', `:end', `:value' and
`:post-blank' as keywords. Otherwise, return nil.
Assume point is at the macro."
(save-excursion
(when (looking-at
"{{{\\([a-zA-Z][-a-zA-Z0-9_]*\\)\\([^a-zA-Z]*[^-a-zA-Z0-9_]*\\)\\((\\([^\000]*?\\))\\)?}}}")
(let ((begin (point))
(key (downcase (match-string-no-properties 1)))
(value (match-string-no-properties 0))
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point))
(args (pcase (match-string-no-properties 4)
(`nil nil)
(a (org-macro-extract-arguments
(if (not (equal (match-string-no-properties 2) ""))
(match-string-no-properties 2)
",")
(replace-regexp-in-string
"[ \t\r\n]+" " " (org-trim a)))))))
(list 'macro
(list :key key
:value value
:args args
:begin begin
:end end
:post-blank post-blank))))))
(defun org-macro-extract-arguments (sep s)
"Extract macro arguments from string S.
S is a string containing comma separated values properly escaped.
Return a list of arguments, as strings. This is the opposite of
`org-macro-escape-arguments'."
;; Do not use `org-split-string' since empty strings are
;; meaningful here.
(split-string
(replace-regexp-in-string
(format "\\(\\\\*\\)%s" sep)
(lambda (str)
(let ((len (length (match-string 1 str))))
(concat (make-string (/ len 2) ?\\)
(if (zerop (mod len 2)) "\000" (format "%s" sep)))))
s nil t)
"\000"))
#+end_src