diff options
author | Kyle Meyer <kyle@kyleam.com> | 2017-11-16 22:11:28 -0500 |
---|---|---|
committer | Kyle Meyer <kyle@kyleam.com> | 2017-11-16 22:11:28 -0500 |
commit | 594201d414e53136b4e6b5531156881ea864cc65 (patch) | |
tree | b100101188ef9a742bb7573b9b5ed21bfe550146 | |
parent | 6ca9068b6f71bfdc4a4f64b1eff55ca5f3f9589b (diff) | |
parent | 946f76d7070f8fbcf5c1072b7f53cea599f2e110 (diff) | |
download | org-mode-594201d414e53136b4e6b5531156881ea864cc65.tar.gz |
Merge branch 'maint' into emacs-sync
31 files changed, 673 insertions, 297 deletions
diff --git a/contrib/lisp/ox-koma-letter.el b/contrib/lisp/ox-koma-letter.el index e029811..24ed38b 100644 --- a/contrib/lisp/ox-koma-letter.el +++ b/contrib/lisp/ox-koma-letter.el @@ -705,7 +705,7 @@ holding export options." (or (if (plist-get info :special-headings) (or heading-val keyword-val) (or keyword-val heading-val)) - "\\\\mbox{}")))) + "\\mbox{}")))) ;; Opening. (format "\\opening{%s}\n\n" (org-koma-letter--keyword-or-headline @@ -717,7 +717,7 @@ holding export options." (format "\\closing{%s}\n" (org-koma-letter--keyword-or-headline :closing (lambda (h i) (eq (org-koma-letter--special-tag h i) - 'closing)) + 'closing)) info)) (org-koma-letter--special-contents-inline (plist-get info :special-tags-after-closing) info) diff --git a/contrib/lisp/ox-s5.el b/contrib/lisp/ox-s5.el index 8f95010..0496aae 100644 --- a/contrib/lisp/ox-s5.el +++ b/contrib/lisp/ox-s5.el @@ -292,7 +292,8 @@ which will make the list into a \"build\"." "<%s class='org-%s%s'>" tag tag (if (org-export-get-node-property :INCREMENTAL plain-list t) " incremental" "")) - contents (org-html-end-plain-list type)))) + contents + (format "</%s>" tag)))) (defun org-s5-inner-template (contents info) "Return body of document string after HTML conversion. diff --git a/doc/org.texi b/doc/org.texi index 72fbbad..e84ce64 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -1461,10 +1461,10 @@ Demote current heading by one level. Promote the current subtree by one level. @orgcmd{M-S-@key{right},org-demote-subtree} Demote the current subtree by one level. -@orgcmd{M-S-@key{up},org-move-subtree-up} +@orgcmd{M-@key{up},org-move-subtree-up} Move subtree up (swap with previous subtree of same level). -@orgcmd{M-S-@key{down},org-move-subtree-down} +@orgcmd{M-@key{down},org-move-subtree-down} Move subtree down (swap with next subtree of same level). @orgcmd{M-h,org-mark-element} Mark the element at point. Hitting repeatedly will mark subsequent elements @@ -7352,6 +7352,7 @@ gnus | %:group, @r{for messages also all email fiel eww, w3, w3m | %:url info | %:file %:node calendar | %:date +org-protocol | %:link %:description %:annotation @end smallexample @noindent @@ -7593,22 +7594,15 @@ javascript:location.href='org-protocol://store-link?url='+ @cindex capture protocol @cindex protocol, capture -@cindex capture, %:url placeholder -@cindex %:url template expansion in capture -@cindex capture, %:title placeholder -@cindex %:title template expansion in capture Activating @code{capture} handler pops up a @samp{Capture} buffer and fills -the capture template associated to the @samp{X} key with them. The template -refers to the data through @code{%:url} and @code{%:title} placeholders. -Moreover, any selected text in the browser is appended to the body of the -entry. +the capture template associated to the @samp{X} key with them. @example emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY @end example -To use this feature, add a bookmark with an arbitrary name, e.g. -@samp{Org: capture} and enter this as @samp{Location}: +To use this feature, add a bookmark with an arbitrary name, e.g. @samp{Org: +capture} and enter this as @samp{Location}: @example javascript:location.href='org-protocol://template=x'+ @@ -7622,6 +7616,21 @@ The result depends on the capture template used, which is set in the bookmark itself, as in the example above, or in @code{org-protocol-default-template-key}. +@cindex capture, %:link placeholder +@cindex %:link template expansion in capture +@cindex capture, %:description placeholder +@cindex %:description template expansion in capture +@cindex capture, %:annotation placeholder +@cindex %:annotation template expansion in capture +The following template placeholders are available: + +@example +%:link The URL +%:description The webpage title +%:annotation Equivalent to [[%:link][%:description]] +%i The selected text +@end example + @node @code{open-source} protocol @subsection @code{open-source} protocol @cindex open-source protocol diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index adc6806..09d011f 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -494,10 +494,9 @@ non-nil, return the full association list to be used by link) source-name params - (org-unescape-code-in-string - (if org-src-preserve-indentation - (org-trim body t) - (org-trim (org-remove-indentation body)))) + (if org-src-preserve-indentation + (org-trim body t) + (org-trim (org-remove-indentation body))) comment))) (if only-this-block (list (cons src-lang (list result))) diff --git a/lisp/org-attach.el b/lisp/org-attach.el index 38b79ce..cd6b413 100644 --- a/lisp/org-attach.el +++ b/lisp/org-attach.el @@ -507,7 +507,7 @@ This can be used after files have been added externally." (let ((attach-dir (org-attach-dir))) (when attach-dir (let ((files (org-attach-file-list attach-dir))) - (and files (org-attach-tag)) + (org-attach-tag (not files)) (when org-attach-file-list-property (dolist (file files) (unless (string-match "^\\.\\.?\\'" file) diff --git a/lisp/org-capture.el b/lisp/org-capture.el index 862cdb2..2222bf4 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -1311,8 +1311,8 @@ Of course, if exact position has been required, just put it there." (defun org-capture-mark-kill-region (beg end) "Mark the region that will have to be killed when aborting capture." - (let ((m1 (move-marker (make-marker) beg)) - (m2 (move-marker (make-marker) end))) + (let ((m1 (copy-marker beg)) + (m2 (copy-marker end t))) (org-capture-put :begin-marker m1) (org-capture-put :end-marker m2))) @@ -1792,11 +1792,10 @@ The template may still contain \"%?\" for cursor positioning." (let* ((upcase? (equal (upcase key) key)) (org-end-time-was-given nil) (time (org-read-date upcase? t nil prompt))) - (let ((org-time-was-given upcase?)) - (org-insert-time-stamp - time org-time-was-given - (member key '("u" "U")) - nil nil (list org-end-time-was-given))))) + (org-insert-time-stamp + time (or org-time-was-given upcase?) + (member key '("u" "U")) + nil nil (list org-end-time-was-given)))) (`nil (push (org-completing-read (concat (or prompt "Enter string") diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 9dc5015..83d0e12 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -487,7 +487,7 @@ to add an effort property.") "10\\.6\\.[[:digit:]]" (shell-command-to-string "sw_vers -productVersion")) - (<= m -1034058203136)) + (<= m -1034058203135)) (ignore-errors (decode-time (list m 0))))))) (low (funcall dichotomy @@ -2725,7 +2725,9 @@ LEVEL is an integer. Indent by two spaces per level above 1." (setq te (float-time (apply #'encode-time (org-parse-time-string te)))))) (setq tsb (if (eq step0 'week) - (- ts (* 86400 (- (nth 6 (decode-time (seconds-to-time ts))) ws))) + (let ((dow (nth 6 (decode-time (seconds-to-time ts))))) + (if (< dow ws) ts + (- ts (* 86400 (- dow ws))))) ts)) (setq p1 (plist-put p1 :header "")) (setq p1 (plist-put p1 :step nil)) @@ -2735,9 +2737,14 @@ LEVEL is an integer. Indent by two spaces per level above 1." (setq p1 (plist-put p1 :tstart (format-time-string (org-time-stamp-format nil t) (seconds-to-time (max tsb ts))))) + (cl-incf tsb (let ((dow (nth 6 (decode-time (seconds-to-time tsb))))) + (if (or (eq step0 'day) + (= dow ws)) + step + (* 86400 (- ws dow))))) (setq p1 (plist-put p1 :tend (format-time-string (org-time-stamp-format nil t) - (seconds-to-time (min te (setq tsb (+ tsb step))))))) + (seconds-to-time (min te tsb))))) (insert "\n" (if (eq step0 'day) "Daily report: " "Weekly report starting on: ") (plist-get p1 :tstart) "\n") diff --git a/lisp/org-element.el b/lisp/org-element.el index f2b3002..c5f656e 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -1308,23 +1308,19 @@ CONTENTS is the contents of the element." (inlinetask-re (and (featurep 'org-inlinetask) "^\\*+ ")) items struct) (save-excursion - (catch 'exit + (catch :exit (while t (cond ;; At limit: end all items. ((>= (point) limit) - (throw 'exit - (let ((end (progn (skip-chars-backward " \r\t\n") - (forward-line) - (point)))) - (dolist (item items (sort (nconc items struct) - 'car-less-than-car)) - (setcar (nthcdr 6 item) end))))) + (let ((end (progn (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) + (dolist (item items) (setcar (nthcdr 6 item) end))) + (throw :exit (sort (nconc items struct) #'car-less-than-car))) ;; At list end: end all items. ((looking-at org-list-end-re) - (throw 'exit (dolist (item items (sort (nconc items struct) - 'car-less-than-car)) - (setcar (nthcdr 6 item) (point))))) + (dolist (item items) (setcar (nthcdr 6 item) (point))) + (throw :exit (sort (nconc items struct) #'car-less-than-car))) ;; At a new item: end previous sibling. ((looking-at item-re) (let ((ind (save-excursion (skip-chars-forward " \t") @@ -1348,7 +1344,7 @@ CONTENTS is the contents of the element." ;; Ending position, unknown so far. nil))) items)) - (forward-line 1)) + (forward-line)) ;; Skip empty lines. ((looking-at "^[ \t]*$") (forward-line)) ;; Skip inline tasks and blank lines along the way. @@ -1360,17 +1356,18 @@ CONTENTS is the contents of the element." (goto-char origin))))) ;; At some text line. Check if it ends any previous item. (t - (let ((ind (save-excursion (skip-chars-forward " \t") - (current-column)))) - (when (<= ind top-ind) - (skip-chars-backward " \r\t\n") - (forward-line)) + (let ((ind (save-excursion + (skip-chars-forward " \t") + (current-column))) + (end (save-excursion + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) (while (<= ind (nth 1 (car items))) (let ((item (pop items))) - (setcar (nthcdr 6 item) (line-beginning-position)) + (setcar (nthcdr 6 item) end) (push item struct) (unless items - (throw 'exit (sort struct #'car-less-than-car)))))) + (throw :exit (sort struct #'car-less-than-car)))))) ;; Skip blocks (any type) and drawers contents. (cond ((and (looking-at "[ \t]*#\\+BEGIN\\(:\\|_\\S-+\\)") diff --git a/lisp/org-faces.el b/lisp/org-faces.el index 53538e6..eab9f3e 100644 --- a/lisp/org-faces.el +++ b/lisp/org-faces.el @@ -291,7 +291,7 @@ determines if it is a foreground or a background color." (defcustom org-priority-faces nil "Faces for specific Priorities. This is a list of cons cells, with priority character in the car -and faces in the cdr. The face can be a symbol, a color as +and faces in the cdr. The face can be a symbol, a color as a string, or a property list of attributes, like (:foreground \"blue\" :weight bold :underline t). If it is a color string, the variable `org-faces-easy-properties' diff --git a/lisp/org-id.el b/lisp/org-id.el index a508e76..09b873c 100644 --- a/lisp/org-id.el +++ b/lisp/org-id.el @@ -539,8 +539,7 @@ When FILES is given, scan these files instead." (with-temp-buffer (condition-case nil (progn - (insert-file-contents-literally org-id-locations-file) - (goto-char (point-min)) + (insert-file-contents org-id-locations-file) (setq org-id-locations (read (current-buffer)))) (error (message "Could not read org-id-values from %s. Setting it to nil." diff --git a/lisp/org-inlinetask.el b/lisp/org-inlinetask.el index 360b1bc..4a8e43d 100644 --- a/lisp/org-inlinetask.el +++ b/lisp/org-inlinetask.el @@ -114,7 +114,7 @@ When nil, the first star is not shown." (defcustom org-inlinetask-default-state nil "Non-nil means make inline tasks have a TODO keyword initially. This should be the state `org-inlinetask-insert-task' should use by -default, or nil of no state should be assigned." +default, or nil if no state should be assigned." :group 'org-inlinetask :version "24.1" :type '(choice diff --git a/lisp/org-macs.el b/lisp/org-macs.el index 1118214..ff6d8c4 100644 --- a/lisp/org-macs.el +++ b/lisp/org-macs.el @@ -51,8 +51,8 @@ Otherwise, return nil." SEPARATORS is a regular expression. When nil, it defaults to \"[ \f\t\n\r\v]+\". -Unlike to `split-string', matching SEPARATORS at the beginning -and end of string are ignored." +Unlike `split-string', matching SEPARATORS at the beginning and +end of string are ignored." (let ((separators (or separators "[ \f\t\n\r\v]+"))) (when (string-match (concat "\\`" separators) string) (setq string (replace-match "" nil nil string))) @@ -108,16 +108,15 @@ text properties." (value (if (stringp display) display (cl-some #'stringp display)))) (when value - (apply - #'propertize - ;; Displayed string could contain - ;; invisible parts, but no nested display. - (funcall prune-invisible value) - (plist-put props - 'display - (and (not (stringp display)) - (cl-remove-if #'stringp - display))))))))))) + (apply #'propertize + ;; Displayed string could contain + ;; invisible parts, but no nested + ;; display. + (funcall prune-invisible value) + 'display + (and (not (stringp display)) + (cl-remove-if #'stringp display)) + props)))))))) ;; `display' property overrides `invisible' one. So we first ;; replace characters with `display' property. Then we remove ;; invisible characters. @@ -125,7 +124,7 @@ text properties." (defun org-string-width (string) "Return width of STRING when displayed in the current buffer. -Unlike to `string-width', this function takes into consideration +Unlike `string-width', this function takes into consideration `invisible' and `display' text properties." (string-width (org-string-display string))) diff --git a/lisp/org-src.el b/lisp/org-src.el index 99d7c6f..4191d9a 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -581,14 +581,15 @@ Escaping happens when a line starts with \"*\", \"#+\", \",*\" or (interactive "r") (save-excursion (goto-char end) - (while (re-search-backward "^[ \t]*,?\\(\\*\\|#\\+\\)" beg t) + (while (re-search-backward "^[ \t]*\\(,*\\(?:\\*\\|#\\+\\)\\)" beg t) (save-excursion (replace-match ",\\1" nil nil nil 1))))) (defun org-escape-code-in-string (s) "Escape lines in string S. Escaping happens when a line starts with \"*\", \"#+\", \",*\" or \",#+\" by appending a comma to it." - (replace-regexp-in-string "^[ \t]*,?\\(\\*\\|#\\+\\)" ",\\1" s nil nil 1)) + (replace-regexp-in-string "^[ \t]*\\(,*\\(?:\\*\\|#\\+\\)\\)" ",\\1" + s nil nil 1)) (defun org-unescape-code-in-region (beg end) "Un-escape lines between BEG and END. @@ -597,7 +598,7 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (interactive "r") (save-excursion (goto-char end) - (while (re-search-backward "^[ \t]*,?\\(,\\)\\(?:\\*\\|#\\+\\)" beg t) + (while (re-search-backward "^[ \t]*,*\\(,\\)\\(?:\\*\\|#\\+\\)" beg t) (save-excursion (replace-match "" nil nil nil 1))))) (defun org-unescape-code-in-string (s) @@ -605,7 +606,7 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." Un-escaping happens by removing the first comma on lines starting with \",*\", \",#+\", \",,*\" and \",,#+\"." (replace-regexp-in-string - "^[ \t]*,?\\(,\\)\\(?:\\*\\|#\\+\\)" "" s nil nil 1)) + "^[ \t]*,*\\(,\\)\\(?:\\*\\|#\\+\\)" "" s nil nil 1)) diff --git a/lisp/org-table.el b/lisp/org-table.el index 8dc648e..d51750f 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -3242,7 +3242,7 @@ existing formula for column %s" (goto-char beg) ;; Mark named fields untouchable. Also check if several ;; field/range formulas try to set the same field. - (remove-text-properties beg end '(org-untouchable t)) + (remove-text-properties beg end '(:org-untouchable t)) (let ((current-line (count-lines org-table-current-begin-pos (line-beginning-position))) seen-fields) diff --git a/lisp/org.el b/lisp/org.el index 35405b4..571a311 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -1284,7 +1284,7 @@ star at the beginning of the headline, you can do this: This list will be checked before `org-speed-commands-default' when the variable `org-use-speed-commands' is non-nil and when the cursor is at the beginning of a headline. -The car if each entry is a string with a single letter, which must +The car of each entry is a string with a single letter, which must be assigned to `self-insert-command' in the global map. The cdr is either a command to be called interactively, a function to be called, or a form to be evaluated. @@ -5290,7 +5290,8 @@ is available. This option applies only if FILE is a URL." ;; Move point to after the url-retrieve header. (search-forward "\n\n" nil :move) ;; Search for the success code only in the url-retrieve header. - (if (save-excursion (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) + (if (save-excursion + (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) ;; Update the cache `org--file-cache' and return contents. (puthash file (buffer-substring-no-properties (point) (point-max)) @@ -5300,13 +5301,14 @@ is available. This option applies only if FILE is a URL." file)))) (t (with-temp-buffer - (condition-case err + (condition-case nil (progn (insert-file-contents file) (buffer-string)) (file-error (funcall (if noerror #'message #'user-error) - (error-message-string err))))))))) + "Unable to read file %S" + file)))))))) (defun org-extract-log-state-settings (x) "Extract the log state setting from a TODO keyword string. @@ -5750,18 +5752,23 @@ This should be called after the variable `org-link-parameters' has changed." (verbatim? (member marker '("~" "=")))) (when (save-excursion (goto-char (match-beginning 0)) - ;; Do not match headline stars. Do not consider - ;; stars of a headline as closing marker for bold - ;; markup either. Do not match table hlines. (and - (not (looking-at-p org-outline-regexp-bol)) + ;; Do not match headline stars. Do not consider + ;; stars of a headline as closing marker for bold + ;; markup either. + (not (and (equal marker "*") + (save-excursion + (forward-char) + (skip-chars-backward "*") + (looking-at-p org-outline-regexp-bol)))) + ;; Do not match table hlines. (not (and (equal marker "+") (org-match-line "^[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$"))) (looking-at (if verbatim? org-verbatim-re org-emph-re)) - (not (string-match-p - (concat org-outline-regexp-bol "\\'") - (match-string 0))))) + ;; At a table row, do not cross cell boundaries. + (not (and (save-match-data (org-match-line "[ \t]*|")) + (string-match-p "|" (match-string 4)))))) (pcase-let ((`(,_ ,face ,_) (assoc marker org-emphasis-alist))) (font-lock-prepend-text-property (match-beginning 2) (match-end 2) 'face face) @@ -7945,8 +7952,7 @@ unchecked check box." (org-insert-heading (or (and (equal arg '(16)) '(16)) force-heading)) (save-excursion - (org-back-to-heading) - (outline-previous-heading) + (org-forward-heading-same-level -1) (let ((case-fold-search nil)) (looking-at org-todo-line-regexp))) (let* ((new-mark-x (if (or (equal arg '(4)) @@ -9845,7 +9851,9 @@ active region." (car org-stored-links))))) (defun org-store-link-props (&rest plist) - "Store link properties, extract names, addresses and dates." + "Store link properties. +The properties are pre-processed by extracting names, addresses +and dates." (let ((x (plist-get plist :from))) (when x (let ((adr (mail-extract-address-components x))) @@ -19327,9 +19335,9 @@ boundaries." ;; "file:" links. Also check link abbreviations since ;; some might expand to "file" links. (file-types-re (format "[][]\\[\\(?:file\\|[./~]%s\\)" - (and link-abbrevs - (format "\\|\\(?:%s:\\)" - (regexp-opt link-abbrevs)))))) + (if (not link-abbrevs) "" + (format "\\|\\(?:%s:\\)" + (regexp-opt link-abbrevs)))))) (while (re-search-forward file-types-re end t) (let ((link (save-match-data (org-element-context)))) ;; Check if we're at an inline image, i.e., an image file @@ -20782,8 +20790,8 @@ This command does many different things, depending on context: '(babel-call clock dynamic-block footnote-definition footnote-reference inline-babel-call inline-src-block inlinetask item keyword node-property paragraph - plain-list property-drawer radio-target src-block - statistics-cookie table table-cell table-row + plain-list planning property-drawer radio-target + src-block statistics-cookie table table-cell table-row timestamp) t)) (type (org-element-type context))) @@ -20935,7 +20943,8 @@ Use `\\[org-edit-special]' to edit table.el tables")) (cond (arg (call-interactively #'org-table-recalculate)) ((org-table-maybe-recalculate-line)) (t (org-table-align)))))) - (`timestamp (org-timestamp-change 0 'day)) + ((or `timestamp (and `planning (guard (org-at-timestamp-p 'lax)))) + (org-timestamp-change 0 'day)) ((and `nil (guard (org-at-heading-p))) ;; When point is on an unsupported object type, we can miss ;; the fact that it also is at a heading. Handle it here. @@ -21568,7 +21577,9 @@ Your bug report will be posted to the Org mailing list. ["Cycle through agenda files" org-cycle-agenda-files t] ["Occur in all agenda files" org-occur-in-agenda-files t] "--") - (mapcar 'org-file-menu-entry (org-agenda-files t)))))))) + (mapcar 'org-file-menu-entry + ;; Prevent initialization from failing. + (ignore-errors (org-agenda-files t))))))))) ;;;; Documentation @@ -23617,7 +23628,9 @@ depending on context." (skip-chars-forward " \r\t\n")))) (narrow-to-region (org-element-property :contents-begin element) contents-end)) - (call-interactively #'forward-sentence)))))) + ;; End of heading is considered as the end of a sentence. + (let ((sentence-end (concat (sentence-end) "\\|^\\*+ .*$"))) + (call-interactively #'forward-sentence))))))) (define-key org-mode-map "\M-a" 'org-backward-sentence) (define-key org-mode-map "\M-e" 'org-forward-sentence) @@ -24230,10 +24243,11 @@ convenience: (backward-char) (org-backward-paragraph)) ((<= (point) post-affiliated) (goto-char begin)) + ;; Special behavior: on a table or a property drawer, move to + ;; its beginning. ((memq type '(node-property table-row)) (goto-char (org-element-property :post-affiliated (org-element-property :parent element)))) - ((memq type '(property-drawer table)) (goto-char begin)) (special? (if (<= (point) contents-begin) (goto-char post-affiliated) ;; Inside a verse block, see blank lines as paragraph @@ -24244,8 +24258,7 @@ convenience: (skip-chars-forward " \r\t\n" origin) (if (= (point) origin) (goto-char contents-begin) (beginning-of-line)))))) - ((eq type 'paragraph) - (goto-char contents-begin) + ((eq type 'paragraph) (goto-char contents-begin) ;; When at first paragraph in an item or a footnote definition, ;; move directly to beginning of line. (let ((parent-contents @@ -24253,9 +24266,9 @@ convenience: :contents-begin (org-element-property :parent element)))) (when (and parent-contents (= parent-contents contents-begin)) (beginning-of-line)))) - ;; At the end of a greater element, move to the beginning of the - ;; last element within. - ((>= (point) contents-end) + ;; At the end of a greater element, move to the beginning of + ;; the last element within. + ((and contents-end (>= (point) contents-end)) (goto-char (1- contents-end)) (org-backward-paragraph)) (t (goto-char (or post-affiliated begin)))) diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el index 9e04387..e83eb19 100644 --- a/lisp/ox-ascii.el +++ b/lisp/ox-ascii.el @@ -177,7 +177,8 @@ Inner margin is applied between each headline." (defcustom org-ascii-quote-margin 6 "Width of margin used for quoting text, in characters. -This margin is applied on both sides of the text." +This margin is applied on both sides of the text. It is also +applied on the left side of contents in descriptive lists." :group 'org-export-ascii :version "24.4" :package-version '(Org . "8.0") @@ -551,79 +552,69 @@ INFO is a plist used as a communication channel." (`inlinetask (plist-get info :ascii-inlinetask-width)) (`headline (- (plist-get info :ascii-text-width) - (let ((low-level-rank (org-export-low-level-p element info))) - (if low-level-rank (* low-level-rank 2) - (plist-get info :ascii-global-margin))))) + (let ((low-level-rank (org-export-low-level-p element info))) + (if low-level-rank (* low-level-rank 2) + (plist-get info :ascii-global-margin))))) ;; Elements with a relative width: store maximum text width in ;; TOTAL-WIDTH. (_ (let* ((genealogy (org-element-lineage element nil t)) - ;; Total width is determined by the presence, or not, of an - ;; inline task among ELEMENT parents. - (total-width - (if (cl-some (lambda (parent) - (eq (org-element-type parent) 'inlinetask)) - genealogy) - (plist-get info :ascii-inlinetask-width) - ;; No inlinetask: Remove global margin from text width. - (- (plist-get info :ascii-text-width) - (plist-get info :ascii-global-margin) - (let ((parent (org-export-get-parent-headline element))) - ;; Inner margin doesn't apply to text before first - ;; headline. - (if (not parent) 0 - (let ((low-level-rank - (org-export-low-level-p parent info))) - ;; Inner margin doesn't apply to contents of - ;; low level headlines, since they've got their - ;; own indentation mechanism. - (if low-level-rank (* low-level-rank 2) - (plist-get info :ascii-inner-margin))))))))) + ;; Total width is determined by the presence, or not, of an + ;; inline task among ELEMENT parents. + (total-width + (if (cl-some (lambda (parent) + (eq (org-element-type parent) 'inlinetask)) + genealogy) + (plist-get info :ascii-inlinetask-width) + ;; No inlinetask: Remove global margin from text width. + (- (plist-get info :ascii-text-width) + (plist-get info :ascii-global-margin) + (let ((parent (org-export-get-parent-headline element))) + ;; Inner margin doesn't apply to text before first + ;; headline. + (if (not parent) 0 + (let ((low-level-rank + (org-export-low-level-p parent info))) + ;; Inner margin doesn't apply to contents of + ;; low level headlines, since they've got their + ;; own indentation mechanism. + (if low-level-rank (* low-level-rank 2) + (plist-get info :ascii-inner-margin))))))))) (- total-width - ;; Each `quote-block' and `verse-block' above narrows text - ;; width by twice the standard margin size. - (+ (* (cl-count-if (lambda (parent) - (memq (org-element-type parent) - '(quote-block verse-block))) - genealogy) - 2 - (plist-get info :ascii-quote-margin)) - ;; Apply list margin once per "top-level" plain-list - ;; containing current line - (* (cl-count-if - (lambda (e) - (and (eq (org-element-type e) 'plain-list) - (not (eq (org-element-type (org-export-get-parent e)) - 'item)))) - genealogy) - (plist-get info :ascii-list-margin)) - ;; Text width within a plain-list is restricted by - ;; indentation of current item. If that's the case, - ;; compute it with the help of `:structure' property from - ;; parent item, if any. - (let ((item - (if (eq (org-element-type element) 'item) element - (cl-find-if (lambda (parent) - (eq (org-element-type parent) 'item)) - genealogy)))) - (if (not item) 0 - ;; Compute indentation offset of the current item, - ;; that is the sum of the difference between its - ;; indentation and the indentation of the top item in - ;; the list and current item bullet's length. Also - ;; remove checkbox length, and tag length (for - ;; description lists) or bullet length. - (let ((struct (org-element-property :structure item)) - (beg-item (org-element-property :begin item))) - (+ (- (org-list-get-ind beg-item struct) - (org-list-get-ind - (org-list-get-top-point struct) struct)) - (string-width (or (org-ascii--checkbox item info) - "")) - (string-width - (let ((tag (org-element-property :tag item))) - (if tag (org-export-data tag info) - (org-element-property :bullet item)))))))))))))) + ;; Each `quote-block' and `verse-block' above narrows text + ;; width by twice the standard margin size. + (+ (* (cl-count-if (lambda (parent) + (memq (org-element-type parent) + '(quote-block verse-block))) + genealogy) + 2 + (plist-get info :ascii-quote-margin)) + ;; Apply list margin once per "top-level" plain-list + ;; containing current line + (* (cl-count-if + (lambda (e) + (and (eq (org-element-type e) 'plain-list) + (not (eq (org-element-type (org-export-get-parent e)) + 'item)))) + genealogy) + (plist-get info :ascii-list-margin)) + ;; Compute indentation offset due to current list. It is + ;; `org-ascii-quote-margin' per descriptive item in the + ;; genealogy, bullet's length otherwise. + (let ((indentation 0)) + (dolist (e genealogy) + (cond + ((not (eq 'item (org-element-type e)))) + ((eq (org-element-property :type (org-export-get-parent e)) + 'descriptive) + (cl-incf indentation org-ascii-quote-margin)) + (t + (cl-incf indentation + (+ (string-width + (or (org-ascii--checkbox e info) "")) + (string-width + (org-element-property :bullet e))))))) + indentation))))))) (defun org-ascii--current-justification (element) "Return expected justification for ELEMENT's contents. @@ -1458,40 +1449,54 @@ contextual information." (bullet ;; First parent of ITEM is always the plain-list. Get ;; `:type' property from it. - (org-list-bullet-string - (pcase list-type - (`descriptive - (concat checkbox - (org-export-data (org-element-property :tag item) info) - ": ")) - (`ordered - ;; Return correct number for ITEM, paying attention to - ;; counters. - (let* ((struct (org-element-property :structure item)) - (bul (org-element-property :bullet item)) - (num (number-to-string - (car (last (org-list-get-item-number - (org-element-property :begin item) - struct - (org-list-prevs-alist struct) - (org-list-parents-alist struct))))))) - (replace-regexp-in-string "[0-9]+" num bul))) - (_ (let ((bul (org-element-property :bullet item))) - ;; Change bullets into more visible form if UTF-8 is active. - (if (not utf8p) bul + (pcase list-type + (`descriptive + (concat checkbox + (org-export-data (org-element-property :tag item) + info))) + (`ordered + ;; Return correct number for ITEM, paying attention to + ;; counters. + (let* ((struct (org-element-property :structure item)) + (bul (org-list-bullet-string + (org-element-property :bullet item))) + (num (number-to-string + (car (last (org-list-get-item-number + (org-element-property :begin item) + struct + (org-list-prevs-alist struct) + (org-list-parents-alist struct))))))) + (replace-regexp-in-string "[0-9]+" num bul))) + (_ (let ((bul (org-list-bullet-string + (org-element-property :bullet item)))) + ;; Change bullets into more visible form if UTF-8 is active. + (if (not utf8p) bul + (replace-regexp-in-string + "-" "•" (replace-regexp-in-string - "-" "•" - (replace-regexp-in-string - "+" "⁃" - (replace-regexp-in-string "*" "‣" bul)))))))))) + "+" "⁃" + (replace-regexp-in-string "*" "‣" bul)))))))) + (indentation (if (eq list-type 'descriptive) org-ascii-quote-margin + (string-width bullet)))) (concat bullet - (unless (eq list-type 'descriptive) checkbox) + checkbox ;; Contents: Pay attention to indentation. Note: check-boxes are ;; already taken care of at the paragraph level so they don't ;; interfere with indentation. - (let ((contents (org-ascii--indent-string contents (string-width bullet)))) - (if (eq (org-element-type (car (org-element-contents item))) 'paragraph) + (let ((contents (org-ascii--indent-string contents indentation))) + ;; Determine if contents should follow the bullet or start + ;; a new line. Do the former when the first contributing + ;; element to contents is a paragraph. In descriptive lists + ;; however, contents always start a new line. + (if (and (not (eq list-type 'descriptive)) + (org-string-nw-p contents) + (eq 'paragraph + (org-element-type + (cl-some (lambda (e) + (and (org-string-nw-p (org-export-data e info)) + e)) + (org-element-contents item))))) (org-trim contents) (concat "\n" contents)))))) diff --git a/lisp/ox-html.el b/lisp/ox-html.el index 8ce4fb6..3073727 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -2154,21 +2154,17 @@ CODE is a string representing the source code to colorize. LANG is the language used for CODE, as a string, or nil." (when code (cond - ;; Case 1: No lang. Possibly an example block. - ((not lang) - ;; Simple transcoding. - (org-html-encode-plain-text code)) - ;; Case 2: No htmlize or an inferior version of htmlize + ;; No language. Possibly an example block. + ((not lang) (org-html-encode-plain-text code)) + ;; Plain text explicitly set. + ((not org-html-htmlize-output-type) (org-html-encode-plain-text code)) + ;; No htmlize library or an inferior version of htmlize. ((not (and (or (require 'htmlize nil t) - (error "Please install htmlize from https://github.com/hniksic/emacs-htmlize")) + (error "Please install htmlize from \ +https://github.com/hniksic/emacs-htmlize")) (fboundp 'htmlize-region-for-paste))) ;; Emit a warning. (message "Cannot fontify src block (htmlize.el >= 1.34 required)") - ;; Simple transcoding. - (org-html-encode-plain-text code)) - ;; Case 3: plain text explicitly set - ((not org-html-htmlize-output-type) - ;; Simple transcoding. (org-html-encode-plain-text code)) (t ;; Map language @@ -2177,7 +2173,6 @@ is the language used for CODE, as a string, or nil." (cond ;; Case 1: Language is not associated with any Emacs mode ((not (functionp lang-mode)) - ;; Simple transcoding. (org-html-encode-plain-text code)) ;; Case 2: Default. Fontify code. (t @@ -2328,15 +2323,7 @@ INFO is a plist used as a communication channel." (org-element-property :priority headline))) (text (org-export-data-with-backend (org-export-get-alt-title headline info) - ;; Create an anonymous back-end that will ignore any - ;; footnote-reference, link, radio-target and target - ;; in table of contents. - (org-export-create-backend - :parent 'html - :transcoders '((footnote-reference . ignore) - (link . (lambda (object c i) c)) - (radio-target . (lambda (object c i) c)) - (target . ignore))) + (org-export-toc-entry-backend 'html) info)) (tags (and (eq (plist-get info :with-tags) t) (org-export-get-tags headline info)))) diff --git a/lisp/ox-man.el b/lisp/ox-man.el index fb8f7be..6fb3041 100644 --- a/lisp/ox-man.el +++ b/lisp/ox-man.el @@ -285,6 +285,10 @@ This function shouldn't be used for floats. See output (concat (format "%s\n.br\n" label) output)))) +(defun org-man--protect-text (text) + "Protect minus and backslash characters in string TEXT." + (replace-regexp-in-string "-" "\\-" text nil t)) + ;;; Template @@ -350,10 +354,9 @@ holding contextual information." ;;; Code (defun org-man-code (code _contents _info) - "Transcode a CODE object from Org to Man. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (format "\\fC%s\\fP" code)) + "Transcode a CODE object from Org to Man." + (format "\\fC%s\\fP" + (org-man--protect-text (org-element-property :value code)))) ;;; Drawer @@ -1029,11 +1032,10 @@ holding contextual information." ;;; Verbatim -(defun org-man-verbatim (_verbatim contents _info) - "Transcode a VERBATIM object from Org to Man. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (format ".nf\n%s\n.fi" contents)) +(defun org-man-verbatim (verbatim _contents _info) + "Transcode a VERBATIM object from Org to Man." + (format "\\fI%s\\fP" + (org-man--protect-text (org-element-property :value verbatim)))) ;;; Verse Block diff --git a/lisp/ox-md.el b/lisp/ox-md.el index 5ba52e7..1218838 100644 --- a/lisp/ox-md.el +++ b/lisp/ox-md.el @@ -240,7 +240,7 @@ a communication channel." (format "<a id=\"%s\"></a>" (or (org-element-property :CUSTOM_ID headline) (org-export-get-reference headline info)))))) - (concat (org-md--headline-title style level title anchor tags) + (concat (org-md--headline-title style level heading anchor tags) contents))))))) @@ -582,16 +582,7 @@ contents according to the current headline." (format "[%s](#%s)" (org-export-data-with-backend (org-export-get-alt-title headline info) - ;; Create an anonymous back-end that will - ;; ignore any footnote-reference, link, - ;; radio-target and target in table of - ;; contents. - (org-export-create-backend - :parent 'md - :transcoders '((footnote-reference . ignore) - (link . (lambda (object c i) c)) - (radio-target . (lambda (object c i) c)) - (target . ignore))) + (org-export-toc-entry-backend 'md) info) (or (org-element-property :CUSTOM_ID headline) (org-export-get-reference headline info)))) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index f00fd99..d585636 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1159,12 +1159,8 @@ table of contents as a string, or nil." ;; Likewise, links, footnote references and regular targets are also ;; suppressed. (let* ((headlines (org-export-collect-headlines info depth scope)) - (backend (org-export-create-backend - :parent (org-export-backend-name (plist-get info :back-end)) - :transcoders '((footnote-reference . ignore) - (link . (lambda (object c i) c)) - (radio-target . (lambda (object c i) c)) - (target . ignore))))) + (backend (org-export-toc-entry-backend + (org-export-backend-name (plist-get info :back-end))))) (when headlines (org-odt--format-toc (and (not scope) (org-export-translate "Table of Contents" :utf-8 info)) diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el index b5903a5..60618c1 100644 --- a/lisp/ox-texinfo.el +++ b/lisp/ox-texinfo.el @@ -83,7 +83,8 @@ :filters-alist '((:filter-headline . org-texinfo--filter-section-blank-lines) (:filter-parse-tree . org-texinfo--normalize-headlines) - (:filter-section . org-texinfo--filter-section-blank-lines)) + (:filter-section . org-texinfo--filter-section-blank-lines) + (:filter-final-output . org-texinfo--untabify)) :menu-entry '(?i "Export to Texinfo" ((?t "As TEXI file" org-texinfo-export-to-texinfo) @@ -405,6 +406,10 @@ If two strings share the same prefix (e.g. \"ISO-8859-1\" and ;;; Internal Functions +(defun org-texinfo--untabify (s _backend _info) + "Remove TAB characters in string S." + (replace-regexp-in-string "\t" (make-string tab-width ?\s) s)) + (defun org-texinfo--filter-section-blank-lines (headline _backend _info) "Filter controlling number of blank lines after a section." (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" "\n\n" headline)) @@ -499,8 +504,12 @@ export state, as a plist." (org-export-create-backend :parent 'texinfo :transcoders '((footnote-reference . ignore) - (link . (lambda (object c i) c)) - (radio-target . (lambda (object c i) c)) + (link . (lambda (l c i) + (or c + (org-export-data + (org-element-property :raw-link l) + i)))) + (radio-target . (lambda (_r c _i) c)) (target . ignore))) info)) @@ -519,18 +528,27 @@ strings (e.g., returned by `org-export-get-caption')." (let* ((backend (org-export-create-backend :parent 'texinfo - :transcoders '((link . (lambda (object c i) c)) - (radio-target . (lambda (object c i) c)) + :transcoders '((link . (lambda (l c i) + (or c + (org-export-data + (org-element-property :raw-link l) + i)))) + (radio-target . (lambda (_r c _i) c)) (target . ignore)))) (short-backend (org-export-create-backend :parent 'texinfo - :transcoders '((footnote-reference . ignore) - (inline-src-block . ignore) - (link . (lambda (object c i) c)) - (radio-target . (lambda (object c i) c)) - (target . ignore) - (verbatim . ignore)))) + :transcoders + '((footnote-reference . ignore) + (inline-src-block . ignore) + (link . (lambda (l c i) + (or c + (org-export-data + (org-element-property :raw-link l) + i)))) + (radio-target . (lambda (_r c _i) c)) + (target . ignore) + (verbatim . ignore)))) (short-str (if (and short caption) (format "@shortcaption{%s}\n" @@ -1017,15 +1035,17 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-texinfo--@ref (datum description info) "Return @ref command for element or object DATUM. -DESCRIPTION is the name of the section to print, as a string." +DESCRIPTION is the printed name of the section, as a string, or +nil." (let ((node-name (org-texinfo--get-node datum info)) ;; Sanitize DESCRIPTION for cross-reference use. In - ;; particular, remove colons as they seem to cause (even - ;; within @asis{...} to the Texinfo reader. - (title (replace-regexp-in-string - "[ \t]*:+" "" - (replace-regexp-in-string "," "@comma{}" description)))) - (if (equal title node-name) + ;; particular, remove colons as they seem to cause pain (even + ;; within @asis{...}) to the Texinfo reader. + (title (and description + (replace-regexp-in-string + "[ \t]*:+" "" + (replace-regexp-in-string "," "@comma{}" description))))) + (if (or (not title) (equal title node-name)) (format "@ref{%s}" node-name) (format "@ref{%s, , %s}" node-name title)))) @@ -1073,20 +1093,8 @@ INFO is a plist holding contextual information. See (org-element-type (org-element-property :parent destination)))))) (let ((headline (org-element-lineage destination '(headline) t))) - (org-texinfo--@ref - headline - (or desc (org-texinfo--sanitize-title - (org-element-property :title headline) info)) - info))) - (_ - (org-texinfo--@ref - destination - (or desc - (pcase (org-export-get-ordinal destination info) - ((and (pred integerp) n) (number-to-string n)) - ((and (pred consp) n) (mapconcat #'number-to-string n ".")) - (_ "???"))) ;cannot guess the description - info))))) + (org-texinfo--@ref headline desc info))) + (_ (org-texinfo--@ref destination desc info))))) ((string= type "mailto") (format "@email{%s}" (concat (org-texinfo--sanitize-content path) @@ -1167,19 +1175,19 @@ is an integer, build the menu recursively, down to this depth." (cond ((not level) (org-texinfo--format-entries (org-texinfo--menu-entries scope info) info)) - ((zerop level) nil) + ((zerop level) "\n") (t - (org-element-normalize-string - (mapconcat - (lambda (h) - (let ((entries (org-texinfo--menu-entries h info))) - (when entries - (concat - (format "%s\n\n%s\n" - (org-export-data (org-export-get-alt-title h info) info) - (org-texinfo--format-entries entries info)) - (org-texinfo--build-menu h info (1- level)))))) - (org-texinfo--menu-entries scope info) "\n"))))) + (mapconcat + (lambda (h) + (let ((entries (org-texinfo--menu-entries h info))) + (when entries + (concat + (format "%s\n\n%s\n" + (org-export-data (org-export-get-alt-title h info) info) + (org-texinfo--format-entries entries info)) + (org-texinfo--build-menu h info (1- level)))))) + (org-texinfo--menu-entries scope info) + "")))) (defun org-texinfo--format-entries (entries info) "Format all direct menu entries in SCOPE, as a string. @@ -5176,7 +5176,7 @@ return nil." info 'first-match))) -;;;; For Tables Of Contents +;;;; For Tables of Contents ;; ;; `org-export-collect-headlines' builds a list of all exportable ;; headline elements, maybe limited to a certain depth. One can then @@ -5186,6 +5186,9 @@ return nil." ;; Once the generic function `org-export-collect-elements' is defined, ;; `org-export-collect-tables', `org-export-collect-figures' and ;; `org-export-collect-listings' can be derived from it. +;; +;; `org-export-toc-entry-backend' builds a special anonymous back-end +;; useful to export table of contents' entries. (defun org-export-collect-headlines (info &optional n scope) "Collect headlines in order to build a table of contents. @@ -5271,6 +5274,32 @@ INFO is a plist used as a communication channel. Return a list of src-block elements with a caption." (org-export-collect-elements 'src-block info)) +(defun org-export-toc-entry-backend (parent &rest transcoders) + "Return an export back-end appropriate for table of contents entries. + +PARENT is an export back-end the returned back-end should inherit +from. + +By default, the back-end removes footnote references and targets. +It also changes links and radio targets into regular text. +TRANSCODERS optional argument, when non-nil, specifies additional +transcoders. A transcoder follows the pattern (TYPE . FUNCTION) +where type is an element or object type and FUNCTION the function +transcoding it." + (declare (indent 1)) + (org-export-create-backend + :parent parent + :transcoders + (append transcoders + `((footnote-reference . ,#'ignore) + (link . ,(lambda (l c i) + (or c + (org-export-data + (org-element-property :raw-link l) + i)))) + (radio-target . ,(lambda (_r c _) c)) + (target . ,#'ignore))))) + ;;;; Smart Quotes ;; @@ -5657,6 +5686,7 @@ them." ("zh-TW" :html "作者" :utf-8 "作者")) ("Continued from previous page" ("ar" :default "تتمة الصفحة السابقة") + ("cs" :default "Pokračování z předchozí strany") ("de" :default "Fortsetzung von vorheriger Seite") ("es" :html "Continúa de la página anterior" :ascii "Continua de la pagina anterior" :default "Continúa de la página anterior") ("fr" :default "Suite de la page précédente") @@ -5669,6 +5699,7 @@ them." ("sl" :default "Nadaljevanje s prejšnje strani")) ("Continued on next page" ("ar" :default "التتمة في الصفحة التالية") + ("cs" :default "Pokračuje na další stránce") ("de" :default "Fortsetzung nächste Seite") ("es" :html "Continúa en la siguiente página" :ascii "Continua en la siguiente pagina" :default "Continúa en la siguiente página") ("fr" :default "Suite page suivante") @@ -5680,6 +5711,7 @@ them." :utf-8 "(Продолжение следует)") ("sl" :default "Nadaljevanje na naslednji strani")) ("Created" + ("cs" :default "Vytvořeno") ("sl" :default "Ustvarjeno")) ("Date" ("ar" :default "بتاريخ") @@ -5709,6 +5741,7 @@ them." ("zh-TW" :html "日期" :utf-8 "日期")) ("Equation" ("ar" :default "معادلة") + ("cs" :default "Rovnice") ("da" :default "Ligning") ("de" :default "Gleichung") ("es" :ascii "Ecuacion" :html "Ecuación" :default "Ecuación") @@ -5727,6 +5760,7 @@ them." ("zh-CN" :html "方程" :utf-8 "方程")) ("Figure" ("ar" :default "شكل") + ("cs" :default "Obrázek") ("da" :default "Figur") ("de" :default "Abbildung") ("es" :default "Figura") @@ -5742,6 +5776,7 @@ them." ("zh-CN" :html "图" :utf-8 "图")) ("Figure %d:" ("ar" :default "شكل %d:") + ("cs" :default "Obrázek %d:") ("da" :default "Figur %d") ("de" :default "Abbildung %d:") ("es" :default "Figura %d:") @@ -5760,7 +5795,7 @@ them." ("Footnotes" ("ar" :default "الهوامش") ("ca" :html "Peus de pàgina") - ("cs" :default "Pozn\xe1mky pod carou") + ("cs" :default "Poznámky pod čarou") ("da" :default "Fodnoter") ("de" :html "Fußnoten" :default "Fußnoten") ("eo" :default "Piednotoj") @@ -5787,6 +5822,7 @@ them." ("zh-TW" :html "腳註" :utf-8 "腳註")) ("List of Listings" ("ar" :default "قائمة بالبرامج") + ("cs" :default "Seznam programů") ("da" :default "Programmer") ("de" :default "Programmauflistungsverzeichnis") ("es" :ascii "Indice de Listados de programas" :html "Índice de Listados de programas" :default "Índice de Listados de programas") @@ -5801,6 +5837,7 @@ them." ("zh-CN" :html "代码目录" :utf-8 "代码目录")) ("List of Tables" ("ar" :default "قائمة بالجداول") + ("cs" :default "Seznam tabulek") ("da" :default "Tabeller") ("de" :default "Tabellenverzeichnis") ("es" :ascii "Indice de tablas" :html "Índice de tablas" :default "Índice de tablas") @@ -5819,6 +5856,7 @@ them." ("zh-CN" :html "表格目录" :utf-8 "表格目录")) ("Listing" ("ar" :default "برنامج") + ("cs" :default "Program") ("da" :default "Program") ("de" :default "Programmlisting") ("es" :default "Listado de programa") @@ -5834,6 +5872,7 @@ them." ("zh-CN" :html "代码" :utf-8 "代码")) ("Listing %d:" ("ar" :default "برنامج %d:") + ("cs" :default "Program %d:") ("da" :default "Program %d") ("de" :default "Programmlisting %d") ("es" :default "Listado de programa %d") @@ -5849,20 +5888,24 @@ them." ("zh-CN" :html "代码%d " :utf-8 "代码%d ")) ("References" ("ar" :default "المراجع") + ("cs" :default "Reference") ("fr" :ascii "References" :default "Références") ("de" :default "Quellen") ("es" :default "Referencias") ("sl" :default "Reference")) ("See figure %s" + ("cs" :default "Viz obrázek %s") ("fr" :default "cf. figure %s" :html "cf. figure %s" :latex "cf.~figure~%s") ("sl" :default "Glej sliko %s")) ("See listing %s" + ("cs" :default "Viz program %s") ("fr" :default "cf. programme %s" :html "cf. programme %s" :latex "cf.~programme~%s") ("sl" :default "Glej izpis programa %s")) ("See section %s" ("ar" :default "انظر قسم %s") + ("cs" :default "Viz sekce %s") ("da" :default "jævnfør afsnit %s") ("de" :default "siehe Abschnitt %s") ("es" :ascii "Vea seccion %s" :html "Vea sección %s" :default "Vea sección %s") @@ -5876,11 +5919,13 @@ them." ("sl" :default "Glej poglavje %d") ("zh-CN" :html "参见第%s节" :utf-8 "参见第%s节")) ("See table %s" + ("cs" :default "Viz tabulka %s") ("fr" :default "cf. tableau %s" :html "cf. tableau %s" :latex "cf.~tableau~%s") ("sl" :default "Glej tabelo %s")) ("Table" ("ar" :default "جدول") + ("cs" :default "Tabulka") ("de" :default "Tabelle") ("es" :default "Tabla") ("et" :default "Tabel") @@ -5893,6 +5938,7 @@ them." ("zh-CN" :html "表" :utf-8 "表")) ("Table %d:" ("ar" :default "جدول %d:") + ("cs" :default "Tabulka %d:") ("da" :default "Tabel %d") ("de" :default "Tabelle %d") ("es" :default "Tabla %d") diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el index 06a73f0..73b7532 100644 --- a/testing/lisp/test-ob-tangle.el +++ b/testing/lisp/test-ob-tangle.el @@ -197,6 +197,31 @@ another block (org-babel-tangle-jump-to-org) (buffer-string))))))) +(ert-deftest ob-tangle/nested-block () + "Test tangling of org file with nested block." + (should + (string= + "#+begin_src org +,#+begin_src emacs-lisp +1 +,#+end_src +#+end_src +" + (org-test-with-temp-text-in-file + "#+header: :tangle \"test-ob-tangle.org\" +#+begin_src org +,#+begin_src org +,,#+begin_src emacs-lisp +1 +,,#+end_src +,#+end_src +#+end_src" + (unwind-protect + (progn (org-babel-tangle) + (with-temp-buffer (insert-file-contents "test-ob-tangle.org") + (buffer-string))) + (delete-file "test-ob-tangle.org")))))) + (provide 'test-ob-tangle) ;;; test-ob-tangle.el ends here diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el index 4d5dfb7..b98166a 100644 --- a/testing/lisp/test-org-capture.el +++ b/testing/lisp/test-org-capture.el @@ -146,5 +146,21 @@ (list file1 file2 (buffer-file-name))))))))) +(ert-deftest test-org-capture/insert-at-end-abort () + "Test that capture can be aborted after inserting at end of capture buffer." + (should + (equal + "* A\n* B\n" + (org-test-with-temp-text-in-file "* A\n* B\n" + (let* ((file (buffer-file-name)) + (org-capture-templates + `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?")))) + (org-capture nil "t") + (goto-char (point-max)) + (insert "Capture text") + (org-capture-kill)) + (buffer-string))))) + + (provide 'test-org-capture) ;;; test-org-capture.el ends here diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el index 30a69ea..98dab5b 100644 --- a/testing/lisp/test-org-clock.el +++ b/testing/lisp/test-org-clock.el @@ -828,5 +828,110 @@ CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 11:09] => 0:00 CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 13:09] => 0:00" (test-org-clock-clocktable-contents ":tcolumns 2"))))) +(ert-deftest test-org-clock/clocktable/step () + "Test \":step\" parameter in Clock table." + ;; Regression test: week crossing month boundary before :wstart + ;; day-of-week. + (should + (equal " +Weekly report starting on: [2017-09-25 Mon] +| Headline | Time | +|--------------+--------| +| *Total time* | *1:00* | +|--------------+--------| +| Foo | 1:00 |" + (org-test-with-temp-text + "* Foo +CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00 +CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00 +CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00" + (let ((system-time-locale "en_US")) + (test-org-clock-clocktable-contents + ":step week :block 2017-09 :stepskip0 t"))))) + (should + (equal " +Weekly report starting on: [2017-10-01 Sun] +| Headline | Time | +|--------------+--------| +| *Total time* | *2:00* | +|--------------+--------| +| Foo | 2:00 | + +Weekly report starting on: [2017-10-02 Mon] +| Headline | Time | +|--------------+--------| +| *Total time* | *7:00* | +|--------------+--------| +| Foo | 7:00 | + +Weekly report starting on: [2017-10-09 Mon] +| Headline | Time | +|--------------+--------| +| *Total time* | *5:00* | +|--------------+--------| +| Foo | 5:00 | +" + (org-test-with-temp-text + "* Foo +CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00 +CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00 +CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00 +CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00 +CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00" + (let ((system-time-locale "en_US")) + (test-org-clock-clocktable-contents + ":step week :block 2017-10 :stepskip0 t"))))) + ;; :step day + (should + (equal " +Daily report: [2017-10-02 Mon] +| Headline | Time | +|--------------+--------| +| *Total time* | *3:00* | +|--------------+--------| +| Foo | 3:00 | + +Daily report: [2017-10-03 Tue] +| Headline | Time | +|--------------+--------| +| *Total time* | *0:00* | + +Daily report: [2017-10-04 Wed] +| Headline | Time | +|--------------+--------| +| *Total time* | *0:00* | + +Daily report: [2017-10-05 Thu] +| Headline | Time | +|--------------+--------| +| *Total time* | *0:00* | + +Daily report: [2017-10-06 Fri] +| Headline | Time | +|--------------+--------| +| *Total time* | *0:00* | + +Daily report: [2017-10-07 Sat] +| Headline | Time | +|--------------+--------| +| *Total time* | *0:00* | + +Daily report: [2017-10-08 Sun] +| Headline | Time | +|--------------+--------| +| *Total time* | *4:00* | +|--------------+--------| +| Foo | 4:00 |" + (org-test-with-temp-text + "* Foo +CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00 +CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00 +CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00 +CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00 +CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00" + (let ((system-time-locale "en_US")) + (test-org-clock-clocktable-contents + ":step day :block 2017-W40")))))) + (provide 'test-org-clock) ;;; test-org-clock.el end here diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index 7d1c55f..7c359aa 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -1444,9 +1444,19 @@ DEADLINE: <2012-03-29 thu.>" 'org-element-contents)))) ;; Block in an item: ignore indentation within the block. (should - (org-test-with-temp-text "- item\n #+begin_src emacs-lisp\n(+ 1 1)\n #+end_src" - (forward-char) - (= (org-element-property :end (org-element-at-point)) (point-max))))) + (org-test-with-temp-text + "-<point> item\n #+begin_src emacs-lisp\n(+ 1 1)\n #+end_src" + (= (org-element-property :end (org-element-at-point)) (point-max)))) + ;; Last item in a list or sub-list has no `:post-blank' lines, since + ;; those belong to the plain-list. + (should + (= 0 + (org-test-with-temp-text "- A\n\n- <point>B\n\nEnd list" + (org-element-property :post-blank (org-element-at-point))))) + (should + (= 0 + (org-test-with-temp-text "- A\n\n - B\n\n<point> - C\n\n End sub-list" + (org-element-property :post-blank (org-element-at-point)))))) ;;;; Keyword @@ -1962,7 +1972,17 @@ e^{i\\pi}+1=0 "Test `plain-list' parser." (org-test-with-temp-text "- item" (should (org-element-map (org-element-parse-buffer) 'plain-list 'identity))) - ;; Blank lines after the list only belong to outer plain list. + ;; Blank lines after a list or sub-list belongs to that list. + (should + (= 1 + (org-test-with-temp-text "- A\n\n- B\n\nEnd list" + (org-element-property :post-blank (org-element-at-point))))) + (should + (= 1 + (org-test-with-temp-text "- A\n\n<point> - B\n\n - C\n\n End sub-list" + (org-element-property :post-blank (org-element-at-point))))) + ;; Blank lines after the list only belong to outer plain list, + ;; however. (should (equal '(t t) diff --git a/testing/lisp/test-org-macs.el b/testing/lisp/test-org-macs.el index 7c54761..79a39f1 100644 --- a/testing/lisp/test-org-macs.el +++ b/testing/lisp/test-org-macs.el @@ -68,7 +68,13 @@ (eq 'foo (get-text-property 1 'face (org-string-display - #("123" 1 2 (display "abc" face foo))))))) + #("123" 1 2 (display "abc" face foo)))))) + ;; Also preserve `display' property in original string. + (should + (equal "abc" + (let ((s #("123" 1 2 (display "abc" face foo)))) + (org-string-display s) + (get-text-property 1 'display s))))) (provide 'test-org-macs) diff --git a/testing/lisp/test-org-src.el b/testing/lisp/test-org-src.el index 1d683ec..86f08ec 100644 --- a/testing/lisp/test-org-src.el +++ b/testing/lisp/test-org-src.el @@ -443,5 +443,43 @@ This is a tab:\t. (org-edit-special) (prog1 foo (org-edit-src-exit)))))) +;;; Code escaping + +(ert-deftest test-org-src/escape-code-in-string () + "Test `org-escape-code-in-string' specifications." + ;; Escape lines starting with "*" or "#+". + (should (equal ",*" (org-escape-code-in-string "*"))) + (should (equal ",#+" (org-escape-code-in-string "#+"))) + ;; Escape lines starting with ",*" and ",#+". Number of leading + ;; commas does not matter. + (should (equal ",,*" (org-escape-code-in-string ",*"))) + (should (equal ",,#+" (org-escape-code-in-string ",#+"))) + (should (equal ",,,*" (org-escape-code-in-string ",,*"))) + (should (equal ",,,#+" (org-escape-code-in-string ",,#+"))) + ;; Indentation does not matter. + (should (equal " ,*" (org-escape-code-in-string " *"))) + (should (equal " ,#+" (org-escape-code-in-string " #+"))) + ;; Do nothing on other cases. + (should (equal "a" (org-escape-code-in-string "a"))) + (should (equal "#" (org-escape-code-in-string "#"))) + (should (equal "," (org-escape-code-in-string ",")))) + +(ert-deftest test-org-src/unescape-code-in-string () + "Test `org-unescape-code-in-string' specifications." + ;; Unescape lines starting with ",*" or ",#+". Number of leading + ;; commas does not matter. + (should (equal "*" (org-unescape-code-in-string ",*"))) + (should (equal "#+" (org-unescape-code-in-string ",#+"))) + (should (equal ",*" (org-unescape-code-in-string ",,*"))) + (should (equal ",#+" (org-unescape-code-in-string ",,#+"))) + ;; Indentation does not matter. + (should (equal " *" (org-unescape-code-in-string " ,*"))) + (should (equal " #+" (org-unescape-code-in-string " ,#+"))) + ;; Do nothing on other cases. + (should (equal "a" (org-unescape-code-in-string "a"))) + (should (equal "#" (org-unescape-code-in-string "#"))) + (should (equal "," (org-unescape-code-in-string ",")))) + + (provide 'test-org-src) ;;; test-org-src.el ends here diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el index 63234e3..92960da 100644 --- a/testing/lisp/test-org-table.el +++ b/testing/lisp/test-org-table.el @@ -1906,6 +1906,27 @@ is t, then new columns should be added as needed" (org-table-calc-current-TBLFM) (buffer-string))))) +(ert-deftest test-org-table/formula-priority () + "Test field formula priority over column formula." + ;; Field formulas bind stronger than column formulas. + (should + (equal + "| 1 | 3 |\n| 2 | 99 |\n" + (org-test-with-temp-text + "| 1 | |\n| 2 | |\n<point>#+tblfm: $2=3*$1::@2$2=99" + (org-table-calc-current-TBLFM) + (buffer-substring-no-properties (point-min) (point))))) + ;; When field formula is removed, table formulas is applied again. + (should + (equal + "| 1 | 3 |\n| 2 | 6 |\n" + (org-test-with-temp-text + "| 1 | |\n| 2 | |\n#+tblfm: $2=3*$1<point>::@2$2=99" + (org-table-calc-current-TBLFM) + (delete-region (point) (line-end-position)) + (org-table-calc-current-TBLFM) + (buffer-substring-no-properties (point-min) (line-beginning-position)))))) + (ert-deftest test-org-table/tab-indent () "Test named fields with tab indentation." (should diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 4023ec4..d067c04 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -1416,6 +1416,13 @@ (org-test-with-temp-text "* H\n- an item\n- another one" (search-forward "an ") (org-insert-todo-heading-respect-content) + (buffer-substring-no-properties (line-beginning-position) (point-max))))) + ;; Use the same TODO keyword as current heading. + (should + (equal + "* TODO \n" + (org-test-with-temp-text "* TODO\n** WAITING\n" + (org-insert-todo-heading-respect-content) (buffer-substring-no-properties (line-beginning-position) (point-max)))))) (ert-deftest test-org/clone-with-time-shift () @@ -3414,8 +3421,8 @@ SCHEDULED: <2017-05-06 Sat> (org-test-with-temp-text "Paragraph 1.<point>\n\nParagraph 2." (org-forward-sentence) (eobp))) - ;; On a headline, stop at the end of the line, unless point is - ;; already there. + ;; Headlines are considered to be sentences by themselves, even if + ;; they do not end with a full stop. (should (equal "* Headline" @@ -3425,7 +3432,11 @@ SCHEDULED: <2017-05-06 Sat> (should (org-test-with-temp-text "* Headline<point>\nSentence." (org-forward-sentence) - (eobp)))) + (eobp))) + (should + (org-test-with-temp-text "Sentence.<point>\n\n* Headline\n\nSentence 2." + (org-forward-sentence) + (and (org-at-heading-p) (eolp))))) (ert-deftest test-org/backward-sentence () "Test `org-backward-sentence' specifications." @@ -3607,6 +3618,11 @@ SCHEDULED: <2017-05-06 Sat> (should (org-test-with-temp-text "#+BEGIN_<point>EXAMPLE\nL1\n#+END_EXAMPLE" (org-backward-paragraph) + (bobp))) + ;; Pathological case: on an empty heading, move to its beginning. + (should + (org-test-with-temp-text "* <point>H" + (org-backward-paragraph) (bobp)))) (ert-deftest test-org/forward-element () diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 72b6c8c..6b5e3a3 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -4320,6 +4320,76 @@ Another text. (ref:text) (let ((scope (org-element-map tree 'headline #'identity info t))) (length (org-export-collect-headlines info 1 scope))))))) +(ert-deftest test-org-export/toc-entry-backend () + "Test `org-export-toc-entry-backend' specifications." + ;; Ignore targets. + (should + (equal "H \n" + (org-test-with-temp-text "* H <<target>>" + (let (org-export-registered-backends) + (org-export-define-backend 'test + '((headline . (lambda (h _c i) (org-export-data-with-backend + (org-element-property :title h) + (org-export-toc-entry-backend 'test) + i))))) + (org-export-as 'test))))) + ;; Ignore footnote references. + (should + (equal "H \n" + (org-test-with-temp-text "[fn:1] Definition\n* H [fn:1]" + (let (org-export-registered-backends) + (org-export-define-backend 'test + '((headline . (lambda (h _c i) (org-export-data-with-backend + (org-element-property :title h) + (org-export-toc-entry-backend 'test) + i))))) + (org-export-as 'test))))) + ;; Replace plain links with contents, or with path. + (should + (equal "H Org mode\n" + (org-test-with-temp-text "* H [[http://orgmode.org][Org mode]]" + (let (org-export-registered-backends) + (org-export-define-backend 'test + '((headline . (lambda (h _c i) (org-export-data-with-backend + (org-element-property :title h) + (org-export-toc-entry-backend 'test) + i))))) + (org-export-as 'test))))) + (should + (equal "H http://orgmode.org\n" + (org-test-with-temp-text "* H [[http://orgmode.org]]" + (let (org-export-registered-backends) + (org-export-define-backend 'test + '((headline . (lambda (h _c i) (org-export-data-with-backend + (org-element-property :title h) + (org-export-toc-entry-backend 'test) + i))))) + (org-export-as 'test))))) + ;; Replace radio targets with contents. + (should + (equal "H radio\n" + (org-test-with-temp-text "* H <<<radio>>>" + (let (org-export-registered-backends) + (org-export-define-backend 'test + '((headline . (lambda (h _c i) (org-export-data-with-backend + (org-element-property :title h) + (org-export-toc-entry-backend 'test) + i))))) + (org-export-as 'test))))) + ;; With optional argument TRANSCODERS, specify other + ;; transformations. + (should + (equal "H bold\n" + (org-test-with-temp-text "* H *bold*" + (let (org-export-registered-backends) + (org-export-define-backend 'test + '((headline . (lambda (h _c i) (org-export-data-with-backend + (org-element-property :title h) + (org-export-toc-entry-backend 'test + '(bold . (lambda (_b c _i) c))) + i))))) + (org-export-as 'test)))))) + ;;; Templates |