From: Nicolas Goaziou <n.goaziou@gmail.com>
To: Org Mode List <emacs-orgmode@gnu.org>
Subject: [RFC] Simplify attributes syntax
Date: Sat, 09 Mar 2013 01:18:19 +0100 [thread overview]
Message-ID: <87ppz9zar8.fsf@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 587 bytes --]
Hello,
The following patch simplifies syntax for attributes.
From the user POV, it removes necessity to quote or escape characters.
For example, these are now valid:
#+attr_latex: :font \footnotesize :align |l|c|c|
#+attr_foo: :prop var="value" :another-prop nil
From the developer POV, each non-nil value is now read as a string by
`org-export-read-attribute'. So:
#+attr_something: :width 70
will be read as:
'(:width "70")
If there's no major problem with it, I'll apply it before Monday.
Though, I think ox-odt needs double-checking.
Regards,
--
Nicolas Goaziou
[-- Attachment #2: simplify attributes syntax --]
[-- Type: text/x-patch, Size: 17642 bytes --]
From e3a89f40f497297fd7c0ffe9273ede724684b4b9 Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Sat, 9 Mar 2013 00:58:31 +0100
Subject: [PATCH 1/2] ox: Simplify syntax for attributes
* lisp/ox.el (org-export-read-attribute): Do not use `read' to read
attributes. Instead, extract keywords and values from it, which
means each value will be a string when non-nil.
* contrib/lisp/ox-groff.el (org-groff-link--inline-image): Use new
attribute syntax. Small refactoring.
* lisp/ox-ascii.el (org-ascii-horizontal-rule): Use new attribute
syntax.
* lisp/ox-beamer.el (org-beamer-plain-list): Use new attribute syntax.
* lisp/ox-html.el (org-html--textarea-block): Use new attribute
syntax.
* lisp/ox-latex.el (org-latex--inline-image, org-latex--org-table,
org-latex--math-table): Use new attribute syntax.
* lisp/ox-man.el (org-man-table--org-table): Use new attribute syntax.
Small refactoring.
* lisp/ox-odt.el (org-odt-link--inline-image, org-odt-table-cell): Use
new attribute syntax.
* testing/lisp/test-ox.el: Add tests.
This patch introduces two changes. To begin with, it removes the need
for quoting and escaping characters. Also, all non-nil values are
stored as strings. As an exception "nil" is stored as nil.
---
contrib/lisp/ox-groff.el | 45 ++++++++++++++-------------------------------
lisp/ox-ascii.el | 4 +++-
lisp/ox-beamer.el | 6 +++---
lisp/ox-html.el | 6 +++---
lisp/ox-latex.el | 47 +++++++++++++++++++++++------------------------
lisp/ox-man.el | 30 ++++++++----------------------
lisp/ox-odt.el | 22 +++++++++++++++-------
lisp/ox.el | 19 ++++++++++++++++---
testing/lisp/test-ox.el | 25 +++++++++++++++++++++++--
9 files changed, 108 insertions(+), 96 deletions(-)
diff --git a/contrib/lisp/ox-groff.el b/contrib/lisp/ox-groff.el
index 96a688a..5e64023 100644
--- a/contrib/lisp/ox-groff.el
+++ b/contrib/lisp/ox-groff.el
@@ -1209,11 +1209,11 @@ used as a communication channel."
(expand-file-name raw-path))))
(attr (org-export-read-attribute :attr_groff link))
(placement
- (case (plist-get attr :position)
- ('center "")
- ('left "-L")
- ('right "-R")
- (t "")))
+ (let ((pos (plist-get attr :position)))
+ (cond ((string= pos 'center) "")
+ ((string= pos 'left) "-L")
+ ((string= pos 'right) "-R")
+ (t ""))))
(width (or (plist-get attr :width) ""))
(height (or (plist-get attr :height) ""))
(caption (and (not (plist-get attr :disable-caption))
@@ -1223,7 +1223,7 @@ used as a communication channel."
(concat
(cond
((and org-groff-raster-to-ps
- (or (string-match ".\.png$" path)
+ (or (string-match ".\.png$" path)
(string-match ".\.jpg$" path)))
(let ((eps-path (concat path ".eps")))
(shell-command (format org-groff-raster-to-ps path eps-path))
@@ -1658,37 +1658,20 @@ This function assumes TABLE has `org' as its `:type' attribute."
(lines (org-split-string contents "\n"))
(attr-list
- (let (result-list)
- (dolist (attr-item
- (list
- (if (plist-get attr :expand)
- "expand" nil)
-
- (case (plist-get attr :placement)
- ('center "center")
- ('left nil)
- (t
- (if org-groff-tables-centered
- "center" "")))
-
- (case (plist-get attr :boxtype)
- ('box "box")
- ('doublebox "doublebox")
- ('allbox "allbox")
- ('none nil)
- (t "box"))))
-
- (if (not (null attr-item))
- (add-to-list 'result-list attr-item)))
- result-list))
+ (delq nil
+ (list (and (plist-get attr :expand) "expand")
+ (let ((placement (plist-get attr :placement)))
+ (cond ((string= placement 'center) "center")
+ ((string= placement 'left) nil)
+ (t (if org-groff-tables-centered "center" ""))))
+ (or (plist-get attr :boxtype) "box"))))
(title-line (plist-get attr :title-line))
(long-cells (plist-get attr :long-cells))
(table-format
(concat
- (format "%s"
- (or (car attr-list) ""))
+ (or (car attr-list) "")
(or
(let (output-list)
(when (cdr attr-list)
diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el
index 76da33a..6eb96b3 100644
--- a/lisp/ox-ascii.el
+++ b/lisp/ox-ascii.el
@@ -1218,7 +1218,9 @@ information."
(spec-width
(org-export-read-attribute :attr_ascii horizontal-rule :width)))
(org-ascii--justify-string
- (make-string (if (wholenump spec-width) spec-width text-width)
+ (make-string (if (and spec-width (string-match "^[0-9]+$" spec-width))
+ (string-to-number spec-width)
+ text-width)
(if (eq (plist-get info :ascii-charset) 'utf-8) ?― ?-))
text-width 'center)))
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 282da7c..f0f5ef0 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -783,7 +783,7 @@ contextual information."
(org-export-read-attribute :attr_latex plain-list)
(org-export-read-attribute :attr_beamer plain-list)))
(latex-type (let ((env (plist-get attributes :environment)))
- (cond (env (format "%s" env))
+ (cond (env)
((eq type 'ordered) "enumerate")
((eq type 'descriptive) "description")
(t "itemize")))))
@@ -793,11 +793,11 @@ contextual information."
latex-type
;; Default overlay specification, if any.
(org-beamer--normalize-argument
- (format "%s" (or (plist-get attributes :overlay) ""))
+ (or (plist-get attributes :overlay) "")
'defaction)
;; Second optional argument depends on the list type.
(org-beamer--normalize-argument
- (format "%s" (or (plist-get attributes :options) ""))
+ (or (plist-get attributes :options) "")
'option)
;; Eventually insert contents and close environment.
contents
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 829fe28..8c3a993 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -1214,9 +1214,9 @@ When STANDALONE-P is t, wrap the <img.../> into a <div>...</div>."
(defun org-html--textarea-block (element)
"Transcode ELEMENT into a textarea block.
ELEMENT is either a src block or an example block."
- (let ((code (car (org-export-unravel-code element)))
- (attr (org-export-read-attribute :attr_html element)))
- (format "<p>\n<textarea cols=\"%d\" rows=\"%d\">\n%s</textarea>\n</p>"
+ (let* ((code (car (org-export-unravel-code element)))
+ (attr (org-export-read-attribute :attr_html element)))
+ (format "<p>\n<textarea cols=\"%s\" rows=\"%s\">\n%s</textarea>\n</p>"
(or (plist-get attr :width) 80)
(or (plist-get attr :height) (org-count-lines code))
code)))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 3d3fc3a..fa66bb4 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1814,17 +1814,17 @@ used as a communication channel."
(comment-include (if (plist-get attr :comment-include) "%" ""))
;; It is possible to specify width and height in the
;; ATTR_LATEX line, and also via default variables.
- (width (format "%s" (cond ((plist-get attr :width))
- ((plist-get attr :height) "")
- ((eq float 'figure) "0.7\\textwidth")
- ((eq float 'wrap) "0.48\\textwidth")
- (t org-latex-image-default-width))))
- (height (format "%s" (cond ((plist-get attr :height))
- ((or (plist-get attr :width)
- (memq float '(figure wrap))) "")
- (t org-latex-image-default-height))))
- (options (let ((opt (format "%s" (or (plist-get attr :options)
- org-latex-image-default-option))))
+ (width (cond ((plist-get attr :width))
+ ((plist-get attr :height) "")
+ ((eq float 'figure) "0.7\\textwidth")
+ ((eq float 'wrap) "0.48\\textwidth")
+ (t org-latex-image-default-width)))
+ (height (cond ((plist-get attr :height))
+ ((or (plist-get attr :width)
+ (memq float '(figure wrap))) "")
+ (t org-latex-image-default-height)))
+ (options (let ((opt (or (plist-get attr :options)
+ org-latex-image-default-option)))
(if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt
(match-string 1 opt))))
image-code)
@@ -2421,9 +2421,8 @@ This function assumes TABLE has `org' as its `:type' property and
;; Determine alignment string.
(alignment (org-latex--align-string table info))
;; Determine environment for the table: longtable, tabular...
- (table-env (let ((env (plist-get attr :environment)))
- (if env (format "%s" env)
- org-latex-default-table-environment)))
+ (table-env (or (plist-get attr :environment)
+ org-latex-default-table-environment))
;; If table is a float, determine environment: table, table*
;; or sidewaystable.
(float-env (unless (equal "longtable" table-env)
@@ -2436,7 +2435,7 @@ This function assumes TABLE has `org' as its `:type' property and
"table")))))
;; Extract others display options.
(fontsize (let ((font (plist-get attr :font)))
- (and font (concat (org-trim (format "%s" font)) "\n"))))
+ (and font (concat font "\n"))))
(width (plist-get attr :width))
(placement (or (plist-get attr :placement)
(format "[%s]" org-latex-default-figure-position)))
@@ -2527,9 +2526,8 @@ This function assumes TABLE has `org' as its `:type' property and
(let* ((caption (org-latex--caption/label-string table info))
(attr (org-export-read-attribute :attr_latex table))
(inlinep (eq (plist-get attr :mode) 'inline-math))
- (env (let ((env (plist-get attr :environment)))
- (if env (format "%s" env)
- org-latex-default-table-environment)))
+ (env (or (plist-get attr :environment)
+ org-latex-default-table-environment))
(contents
(mapconcat
(lambda (row)
@@ -2566,19 +2564,20 @@ This function assumes TABLE has `org' as its `:type' property and
(inlinep "\\(")
((org-string-nw-p caption) (concat "\\begin{equation}\n" caption))
(t "\\["))
- ;; Prefix (make sure it is a string).
- (format "%s" (or (plist-get attr :math-prefix) ""))
+ ;; Prefix.
+ (or (plist-get attr :math-prefix) "")
;; Environment. Also treat special cases.
(cond ((equal env "array")
(let ((align (org-latex--align-string table info)))
(format "\\begin{array}{%s}\n%s\\end{array}" align contents)))
((assoc env org-latex-table-matrix-macros)
- (format "\\%s%s{\n%s}" env
- (format "%s" (or (plist-get attr :math-arguments) ""))
+ (format "\\%s%s{\n%s}"
+ env
+ (or (plist-get attr :math-arguments) "")
contents))
(t (format "\\begin{%s}\n%s\\end{%s}" env contents env)))
- ;; Suffix (make sure it is a string).
- (format "%s" (or (plist-get attr :math-suffix) ""))
+ ;; Suffix.
+ (or (plist-get attr :math-suffix) "")
;; Closing string. If TABLE is in the middle of a table cluster,
;; do not insert any. If it closes such a cluster, be sure to
;; close the cluster with a string matching the opening string.
diff --git a/lisp/ox-man.el b/lisp/ox-man.el
index 4c17e49..7fc7f02 100644
--- a/lisp/ox-man.el
+++ b/lisp/ox-man.el
@@ -945,28 +945,14 @@ This function assumes TABLE has `org' as its `:type' attribute."
(lines (org-split-string contents "\n"))
(attr-list
- (let ((result-list '()))
- (dolist (attr-item
- (list
- (if (plist-get attr :expand)
- "expand" nil)
-
- (case (plist-get attr :placement)
- ('center "center")
- ('left nil)
- (t (if org-man-tables-centered "center" "")))
-
- (case (plist-get attr :boxtype)
- ('box "box")
- ('doublebox "doublebox")
- ('allbox "allbox")
- ('none nil)
- (t "box"))))
-
- (if attr-item
- (add-to-list 'result-list attr-item)))
- result-list ))
-
+ (delq nil
+ (list
+ (and (plist-get attr :expand) "expand")
+ (let ((placement (plist-get attr :placement)))
+ (cond ((string= placement 'center) "center")
+ ((string= placement 'left) nil)
+ (t (if org-man-tables-centered "center" ""))))
+ (or (plist-get attr :boxtype) "box"))))
(title-line (plist-get attr :title-line))
(long-cells (plist-get attr :long-cells))
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index a1caff7..d9dd525 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -2341,12 +2341,19 @@ used as a communication channel."
(list user-frame-style user-frame-attrs user-frame-anchor))
;; (embed-as (or embed-as user-frame-anchor "paragraph"))
;; extrac
- ;; handle `:width', `:height' and `:scale' properties.
+ ;;
+ ;; Handle `:width', `:height' and `:scale' properties. Read
+ ;; them as numbers since we need them for computations.
(size (org-odt--image-size
- src-expanded (plist-get attr-plist :width)
- (plist-get attr-plist :height)
- (plist-get attr-plist :scale) nil ;; embed-as
- "paragraph" ; FIXME
+ src-expanded
+ (let ((width (plist-get attr-plist :width)))
+ (and width (read width)))
+ (let ((length (plist-get attr-plist :length)))
+ (and length (read length)))
+ (let ((scale (plist-get attr-plist :scale)))
+ (and scale (read scale)))
+ nil ; embed-as
+ "paragraph" ; FIXME
))
(width (car size)) (height (cdr size))
(standalone-link-p (org-odt--standalone-link-p element info))
@@ -3351,8 +3358,9 @@ channel."
"OrgTableHeading")
((let* ((table (org-export-get-parent-table table-cell))
(table-attrs (org-export-read-attribute :attr_odt table))
- (table-header-columns (plist-get table-attrs
- :header-columns)))
+ (table-header-columns
+ (let ((cols (plist-get table-attrs :header-columns)))
+ (and cols (read cols)))))
(<= c (cond ((wholenump table-header-columns)
(- table-header-columns 1))
(table-header-columns 0)
diff --git a/lisp/ox.el b/lisp/ox.el
index 40c0617..92be8f7 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -3257,11 +3257,24 @@ that property within attributes.
This function assumes attributes are defined as \":keyword
value\" pairs. It is appropriate for `:attr_html' like
-properties."
+properties. All values will become strings except the empty
+string and \"nil\", which will become nil."
(let ((attributes
(let ((value (org-element-property attribute element)))
- (and value
- (read (format "(%s)" (mapconcat 'identity value " ")))))))
+ (when value
+ (let ((s (mapconcat 'identity value " ")) result)
+ (while (string-match
+ "\\(?:^\\|[ \t]+\\)\\(:[-a-zA-Z0-9_]+\\)\\([ \t]+\\|$\\)"
+ s)
+ (let ((value (substring s 0 (match-beginning 0))))
+ (push (and (not (member value '("nil" ""))) value) result))
+ (push (intern (match-string 1 s)) result)
+ (setq s (substring s (match-end 0))))
+ ;; Ignore any string before the first property with `cdr'.
+ (cdr (nreverse (cons (and (org-string-nw-p s)
+ (not (equal s "nil"))
+ s)
+ result))))))))
(if property (plist-get attributes property) attributes)))
(defun org-export-get-caption (element &optional shortp)
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 6fa1f25..754c657 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -645,12 +645,33 @@ body\n")))
:attr_html
(org-test-with-temp-text "#+ATTR_HTML: :a 1 :b 2\nParagraph"
(org-element-at-point)))
- '(:a 1 :b 2)))
+ '(:a "1" :b "2")))
;; Return nil on empty attribute.
(should-not
(org-export-read-attribute
:attr_html
- (org-test-with-temp-text "Paragraph" (org-element-at-point)))))
+ (org-test-with-temp-text "Paragraph" (org-element-at-point))))
+ ;; Return nil on "nil" string.
+ (should
+ (equal '(:a nil :b nil)
+ (org-export-read-attribute
+ :attr_html
+ (org-test-with-temp-text "#+ATTR_HTML: :a nil :b nil\nParagraph"
+ (org-element-at-point)))))
+ ;; Return nil on empty string.
+ (should
+ (equal '(:a nil :b nil)
+ (org-export-read-attribute
+ :attr_html
+ (org-test-with-temp-text "#+ATTR_HTML: :a :b\nParagraph"
+ (org-element-at-point)))))
+ ;; Ignore text before first property.
+ (should-not
+ (member "ignore"
+ (org-export-read-attribute
+ :attr_html
+ (org-test-with-temp-text "#+ATTR_HTML: ignore :a 1\nParagraph"
+ (org-element-at-point))))))
(ert-deftest test-org-export/get-caption ()
"Test `org-export-get-caption' specifications."
--
1.8.1.5
next reply other threads:[~2013-03-09 0:18 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-09 0:18 Nicolas Goaziou [this message]
2013-03-09 0:44 ` [RFC] Simplify attributes syntax Thomas S. Dye
2013-03-09 13:55 ` Bastien
2013-03-09 14:45 ` Nicolas Goaziou
2013-03-09 19:55 ` Aaron Ecay
2013-03-09 21:19 ` Nicolas Goaziou
2013-03-11 7:40 ` Nicolas Goaziou
2013-03-13 8:47 ` Christian Egli
2013-03-13 15:28 ` Nicolas Goaziou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ppz9zar8.fsf@gmail.com \
--to=n.goaziou@gmail.com \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).