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