Merge branch 'master' of orgmode.org:org-mode

This commit is contained in:
Bastien Guerry 2014-08-26 16:23:36 +02:00
commit 671a01c765
5 changed files with 113 additions and 63 deletions

View File

@ -108,6 +108,9 @@ increased. See manual for details.
Inline source code was used to be removed upon exporting. They are
now handled as standard code blocks, i.e., the source code can appear
in the output, depending on the parameters.
*** Extend ~org-export-first-sibling-p~ and ~org-export-last-sibling-p~
These functions now support any element or object, not only headlines.
*** New function: ~org-export-table-row-in-header-p~
** Miscellaneous
*** File names in links accept are now compatible with URI syntax
Absolute file names can now start with =///= in addition to =/=. E.g.,

View File

@ -73,9 +73,9 @@
;; refers to the element or object containing it. Greater elements,
;; elements and objects containing objects will also have
;; `:contents-begin' and `:contents-end' properties to delimit
;; contents. Eventually, greater elements and elements accepting
;; affiliated keywords will have a `:post-affiliated' property,
;; referring to the buffer position after all such keywords.
;; contents. Eventually, All elements have a `:post-affiliated'
;; property referring to the buffer position after all affiliated
;; keywords, if any, or to their beginning position otherwise.
;;
;; At the lowest level, a `:parent' property is also attached to any
;; string, as a text property.
@ -777,7 +777,8 @@ containing `:raw-value', `:title', `:alt-title', `:begin',
`:end', `:pre-blank', `:contents-begin' and `:contents-end',
`:level', `:priority', `:tags', `:todo-keyword',`:todo-type',
`:scheduled', `:deadline', `:closed', `:archivedp', `:commentedp'
`:footnote-section-p' and `:post-blank' keywords.
`:footnote-section-p', `:post-blank' and `:post-affiliated'
keywords.
The plist also contains any property set in the property drawer,
with its name in upper cases and colons added at the
@ -902,7 +903,8 @@ Assume point is at beginning of the headline."
end)
:footnote-section-p footnote-section-p
:archivedp archivedp
:commentedp commentedp)
:commentedp commentedp
:post-affiliated begin)
time-props
standard-props))))
(let ((alt-title (org-element-property :ALT_TITLE headline)))
@ -972,7 +974,7 @@ Return a list whose CAR is `inlinetask' and CDR is a plist
containing `:title', `:begin', `:end', `:contents-begin' and
`:contents-end', `:level', `:priority', `:raw-value', `:tags',
`:todo-keyword', `:todo-type', `:scheduled', `:deadline',
`:closed' and `:post-blank' keywords.
`:closed', `:post-blank' and `:post-affiliated' keywords.
The plist also contains any property set in the property drawer,
with its name in upper cases and colons added at the
@ -1076,7 +1078,8 @@ Assume point is at beginning of the inline task."
:tags tags
:todo-keyword todo
:todo-type todo-type
:post-blank (count-lines before-blank end))
:post-blank (count-lines before-blank end)
:post-affiliated begin)
time-props
standard-props))))
(org-element-put-property
@ -1135,8 +1138,8 @@ STRUCT is the structure of the plain list.
Return a list whose CAR is `item' and CDR is a plist containing
`:bullet', `:begin', `:end', `:contents-begin', `:contents-end',
`:checkbox', `:counter', `:tag', `:structure' and `:post-blank'
keywords.
`:checkbox', `:counter', `:tag', `:structure', `:post-blank' and
`:post-affiliated' keywords.
When optional argument RAW-SECONDARY-P is non-nil, item's tag, if
any, will not be parsed as a secondary string, but as a plain
@ -1195,7 +1198,8 @@ Assume point is at the beginning of the item."
:checkbox checkbox
:counter counter
:structure struct
:post-blank (count-lines contents-end end)))))
:post-blank (count-lines contents-end end)
:post-affiliated begin))))
(org-element-put-property
item :tag
(let ((raw-tag (org-list-get-tag begin struct)))
@ -1483,8 +1487,8 @@ CONTENTS is the contents of the element."
LIMIT bounds the search.
Return a list whose CAR is `section' and CDR is a plist
containing `:begin', `:end', `:contents-begin', `contents-end'
and `:post-blank' keywords."
containing `:begin', `:end', `:contents-begin', `contents-end',
`:post-blank' and `:post-affiliated' keywords."
(save-excursion
;; Beginning of section is the beginning of the first non-blank
;; line after previous headline.
@ -1499,7 +1503,8 @@ and `:post-blank' keywords."
:end end
:contents-begin begin
:contents-end pos-before-blank
:post-blank (count-lines pos-before-blank end))))))
:post-blank (count-lines pos-before-blank end)
:post-affiliated begin)))))
(defun org-element-section-interpreter (section contents)
"Interpret SECTION element as Org syntax.
@ -1629,8 +1634,8 @@ CONTENTS is nil."
LIMIT bounds the search.
Return a list whose CAR is `clock' and CDR is a plist containing
`:status', `:value', `:time', `:begin', `:end' and `:post-blank'
as keywords."
`:status', `:value', `:time', `:begin', `:end', `:post-blank' and
`:post-affiliated' as keywords."
(save-excursion
(let* ((case-fold-search nil)
(begin (point))
@ -1654,7 +1659,8 @@ as keywords."
:duration duration
:begin begin
:end end
:post-blank post-blank)))))
:post-blank post-blank
:post-affiliated begin)))))
(defun org-element-clock-interpreter (clock contents)
"Interpret CLOCK element as Org syntax.
@ -2095,8 +2101,8 @@ CONTENTS is nil."
LIMIT bounds the search.
Return a list whose CAR is `node-property' and CDR is a plist
containing `:key', `:value', `:begin', `:end' and `:post-blank'
keywords."
containing `:key', `:value', `:begin', `:end', `:post-blank' and
`:post-affiliated' keywords."
(save-excursion
(looking-at org-property-re)
(let ((case-fold-search t)
@ -2111,7 +2117,8 @@ keywords."
:value value
:begin begin
:end end
:post-blank (count-lines pos-before-blank end))))))
:post-blank (count-lines pos-before-blank end)
:post-affiliated begin)))))
(defun org-element-node-property-interpreter (node-property contents)
"Interpret NODE-PROPERTY element as Org syntax.
@ -2227,8 +2234,8 @@ CONTENTS is the contents of the element."
LIMIT bounds the search.
Return a list whose CAR is `planning' and CDR is a plist
containing `:closed', `:deadline', `:scheduled', `:begin', `:end'
and `:post-blank' keywords."
containing `:closed', `:deadline', `:scheduled', `:begin',
`:end', `:post-blank' and `:post-affiliated' keywords."
(save-excursion
(let* ((case-fold-search nil)
(begin (point))
@ -2254,7 +2261,8 @@ and `:post-blank' keywords."
:scheduled scheduled
:begin begin
:end end
:post-blank post-blank)))))
:post-blank post-blank
:post-affiliated begin)))))
(defun org-element-planning-interpreter (planning contents)
"Interpret PLANNING element as Org syntax.
@ -2470,7 +2478,7 @@ LIMIT bounds the search.
Return a list whose CAR is `table-row' and CDR is a plist
containing `:begin', `:end', `:contents-begin', `:contents-end',
`:type' and `:post-blank' keywords."
`:type', `:post-blank' and `:post-affiliated' keywords."
(save-excursion
(let* ((type (if (looking-at "^[ \t]*|-") 'rule 'standard))
(begin (point))
@ -2491,7 +2499,8 @@ containing `:begin', `:end', `:contents-begin', `:contents-end',
:end end
:contents-begin contents-begin
:contents-end contents-end
:post-blank 0)))))
:post-blank 0
:post-affiliated begin)))))
(defun org-element-table-row-interpreter (table-row contents)
"Interpret TABLE-ROW element as Org syntax.

View File

@ -22380,7 +22380,7 @@ ELEMENT."
(if level (1+ level) 0))))
((item plain list)
(org-list-item-body-column
(or (org-element-property :post-affiliated element) start)))
(org-element-property :post-affiliated element)))
(otherwise
(goto-char start)
(org-get-indentation))))
@ -22512,8 +22512,7 @@ Also align node properties according to `org-property-format'."
(type (org-element-type element)))
(cond ((and (memq type '(plain-list item))
(= (line-beginning-position)
(or (org-element-property :post-affiliated element)
(org-element-property :begin element))))
(org-element-property :post-affiliated element)))
'noindent)
((and (eq type 'src-block)
org-src-tab-acts-natively
@ -22582,8 +22581,7 @@ assumed to be significant there."
;; according to the element type, or not indented at
;; all. Other parts are indented as a single block.
(let* ((post (copy-marker
(or (org-element-property :post-affiliated element)
(org-element-property :begin element))))
(org-element-property :post-affiliated element)))
(cbeg
(copy-marker
(cond
@ -22744,7 +22742,7 @@ matches in paragraphs or comments, use it."
(org-element-at-point)))
(type (org-element-type element))
(post-affiliated (org-element-property :post-affiliated element)))
(unless (and post-affiliated (< p post-affiliated))
(unless (< p post-affiliated)
(case type
(comment
(save-excursion
@ -22753,10 +22751,7 @@ matches in paragraphs or comments, use it."
(concat (match-string 0) "# ")))
(footnote-definition "")
((item plain-list)
(make-string (org-list-item-body-column
(or post-affiliated
(org-element-property :begin element)))
?\s))
(make-string (org-list-item-body-column post-affiliated) ?\s))
(paragraph
;; Fill prefix is usually the same as the current line,
;; unless the paragraph is at the beginning of an item.
@ -22989,9 +22984,7 @@ region only contains such lines."
((and (memq type '(babel-call clock comment diary-sexp headline
horizontal-rule keyword paragraph
planning))
(or (not (org-element-property :post-affiliated element))
(<= (org-element-property :post-affiliated element)
(point))))
(<= (org-element-property :post-affiliated element) (point)))
(skip-chars-forward " \t")
(insert ": "))
((and (org-looking-at-p "[ \t]*$")
@ -23946,7 +23939,7 @@ item, etc. It also provides some special moves for convenience:
(skip-chars-forward " \r\t\n")
(or (eobp) (beginning-of-line)))
;; On affiliated keywords, move to element's beginning.
((and post-affiliated (< (point) post-affiliated))
((< (point) post-affiliated)
(goto-char post-affiliated))
;; At a table row, move to the end of the table. Similarly,
;; at a node property, move to the end of the property
@ -24025,7 +24018,7 @@ convenience:
((= (point) begin)
(backward-char)
(org-backward-paragraph))
((and post-affiliated (<= (point) post-affiliated)) (goto-char begin))
((<= (point) post-affiliated) (goto-char begin))
((memq type '(node-property table-row))
(goto-char (org-element-property
:post-affiliated (org-element-property :parent element))))
@ -24521,7 +24514,7 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]."
(otherwise t)))))))
(cond
;; Ignore checks in all affiliated keywords but captions.
((and post-affiliated (< (point) post-affiliated))
((< (point) post-affiliated)
(and (save-excursion
(beginning-of-line)
(let ((case-fold-search t)) (looking-at "[ \t]*#\\+CAPTION:")))
@ -24544,8 +24537,7 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]."
((comment quote-section) t)
(comment-block
;; Allow checks between block markers, not on them.
(and (> (line-beginning-position)
(org-element-property :post-affiliated element))
(and (> (line-beginning-position) post-affiliated)
(save-excursion
(end-of-line)
(skip-chars-forward " \r\t\n")

View File

@ -3887,16 +3887,19 @@ title is defined, fall-back to the regular title."
(or (org-element-property :alt-title headline)
(org-element-property :title headline)))
(defun org-export-first-sibling-p (headline info)
"Non-nil when HEADLINE is the first sibling in its sub-tree.
INFO is a plist used as a communication channel."
(not (eq (org-element-type (org-export-get-previous-element headline info))
'headline)))
(defun org-export-first-sibling-p (blob info)
"Non-nil when BLOB is the first sibling in its parent.
BLOB is an element or an object. If BLOB is a headline, non-nil
means it is the first sibling in the sub-tree. INFO is a plist
used as a communication channel."
(memq (org-element-type (org-export-get-previous-element blob info))
'(nil section)))
(defun org-export-last-sibling-p (headline info)
"Non-nil when HEADLINE is the last sibling in its sub-tree.
INFO is a plist used as a communication channel."
(not (org-export-get-next-element headline info)))
(defun org-export-last-sibling-p (blob info)
"Non-nil when BLOB is the last sibling in its parent.
BLOB is an element or an object. INFO is a plist used as
a communication channel."
(not (org-export-get-next-element blob info)))
;;;; For Keywords
@ -4431,9 +4434,10 @@ code."
;; `org-export-table-cell-ends-colgroup-p',
;; `org-export-table-row-starts-rowgroup-p',
;; `org-export-table-row-ends-rowgroup-p',
;; `org-export-table-row-starts-header-p' and
;; `org-export-table-row-ends-header-p' indicate position of current
;; row or cell within the table.
;; `org-export-table-row-starts-header-p',
;; `org-export-table-row-ends-header-p' and
;; `org-export-table-row-in-header-p' indicate position of current row
;; or cell within the table.
(defun org-export-table-has-special-column-p (table)
"Non-nil when TABLE has a special column.
@ -4787,21 +4791,25 @@ INFO is a plist used as a communication channel."
(car (org-element-contents table-row)) info)))
(or (memq 'bottom borders) (memq 'below borders)))))
(defun org-export-table-row-in-header-p (table-row info)
"Non-nil when TABLE-ROW is located within table's header.
INFO is a plist used as a communication channel. Always return
nil for special rows and rows separators."
(and (org-export-table-has-header-p
(org-export-get-parent-table table-row) info)
(eql (org-export-table-row-group table-row info) 1)))
(defun org-export-table-row-starts-header-p (table-row info)
"Non-nil when TABLE-ROW is the first table header's row.
INFO is a plist used as a communication channel."
(and (org-export-table-has-header-p
(org-export-get-parent-table table-row) info)
(org-export-table-row-starts-rowgroup-p table-row info)
(= (org-export-table-row-group table-row info) 1)))
(and (org-export-table-row-in-header-p table-row info)
(org-export-table-row-starts-rowgroup-p table-row info)))
(defun org-export-table-row-ends-header-p (table-row info)
"Non-nil when TABLE-ROW is the last table header's row.
INFO is a plist used as a communication channel."
(and (org-export-table-has-header-p
(org-export-get-parent-table table-row) info)
(org-export-table-row-ends-rowgroup-p table-row info)
(= (org-export-table-row-group table-row info) 1)))
(and (org-export-table-row-in-header-p table-row info)
(org-export-table-row-ends-rowgroup-p table-row info)))
(defun org-export-table-row-number (table-row info)
"Return TABLE-ROW number.

View File

@ -1719,10 +1719,23 @@ Paragraph[fn:1]"
(should
(equal
'(yes yes no)
(org-test-with-parsed-data "* Headline\n** Headline 2\n** Headline 3"
(org-test-with-parsed-data "* H\n** H 2\n** H 3"
(org-element-map tree 'headline
(lambda (h) (if (org-export-first-sibling-p h info) 'yes 'no))
info))))
(should
(equal '(yes no)
(org-test-with-parsed-data "- item\n\n para"
(org-element-map tree 'paragraph
(lambda (h) (if (org-export-first-sibling-p h info) 'yes 'no))
info))))
;; Ignore sections for headlines.
(should
(equal '(yes yes)
(org-test-with-parsed-data "* H\nSection\n** H 2"
(org-element-map tree 'headline
(lambda (h) (if (org-export-first-sibling-p h info) 'yes 'no))
info))))
;; Ignore headlines not exported.
(should
(equal
@ -1743,6 +1756,12 @@ Paragraph[fn:1]"
(org-element-map tree 'headline
(lambda (h) (if (org-export-last-sibling-p h info) 'yes 'no))
info))))
(should
(equal '(no yes)
(org-test-with-parsed-data "- item\n\n para"
(org-element-map tree 'paragraph
(lambda (h) (if (org-export-last-sibling-p h info) 'yes 'no))
info))))
;; Ignore headlines not exported.
(should
(equal
@ -2893,6 +2912,25 @@ Another text. (ref:text)
(if (org-export-table-row-ends-rowgroup-p row info) 'yes 'no))
info)))))
(ert-deftest test-org-export/table-row-in-header-p ()
"Test `org-export-table-row-in-header-p' specifications."
;; Standard test. Separators are always nil.
(should
(equal
'(yes no no)
(org-test-with-parsed-data "| a |\n|---|\n| b |"
(org-element-map tree 'table-row
(lambda (row)
(if (org-export-table-row-in-header-p row info) 'yes 'no)) info))))
;; Nil when there is no header.
(should
(equal
'(no no)
(org-test-with-parsed-data "| a |\n| b |"
(org-element-map tree 'table-row
(lambda (row)
(if (org-export-table-row-in-header-p row info) 'yes 'no)) info)))))
(ert-deftest test-org-export/table-row-starts-header-p ()
"Test `org-export-table-row-starts-header-p' specifications."
;; 1. Only the row starting the first row group starts the table