可以Emacs'组织模式识别标题内的标签(而不是仅在标志的末尾)

时间:2016-08-21 09:33:00

标签: emacs tags org-mode

我正在学习如何使用Emacs和org-mode,并且想知道Emacs是否可以在中支持标签而不仅仅是在标题的末尾(无论是原生还是通过包或配置)在〜/ .emacs)。

换句话说,Emacs本身支持这种形式的标签:

* This is a headline. :tag1:tag2:

有没有办法让Emacs另外识别下面格式的标签?

* This is a headline with :tag1: and :tag2:.

我一直在寻找几个小时的答案,并且在其他任何地方都找不到这个问题;我很感激任何建议!

1 个答案:

答案 0 :(得分:0)

这个问题的真正答案在@ lawlist上面的评论中,(引用@lawlist)它“是不可能的[让org-mode识别 行内的标签在没有实质性地修改org-mode的几个方面的情况下,而不是在行尾[而不是在行的末尾]。“

出于这个原因,如果@lawlist将评论作为答案写下来,我会接受它。我也写了这个额外的答案,对于像我这样的人来说,学习这个,想要一种方法来获取一些文本并自动生成org-mode标签。在上面的评论中讨论之后,我在下面的elisp中编写了一个函数,它允许用户突出显示一些文本并自动查找文本中的任何标记(此处,格式为{{tag}})并在第一行末尾以org-mode标签格式连接它们。

(defvar tag-regexp-for-generating-org-mode-tag-list-from-text "{{\\(.*?\\)}}"
"A regular expression, in double-quotes, used for finding 'tags' within lines of text (these can then be translated into org-mode syntax tags.

For example, in the string \"This text contains the 'tags' {{tag1}} and {{tag2}}\", the default regular expression

\"{{\\(.*?\\)}}\"

would find \"tag1\" and \"tag2\", which could then be transformed into org-mode syntax tags, \":tag1:tag2:\"")

;; Following https://emacs.stackexchange.com/a/12335, use just the selected region.
(defun generate-org-mode-tag-list-from-selected-text (beginning-of-selected-region end-of-selected-region)
    "Take a highlighted section of text, find all strings within that text that match the search parameters defined in the variable tag-regexp-for-generating-org-mode-tag-list-from-text (by default, strings of the form {{tag1}} {{tag2}}), and concatenate them into a set of org-mode tags (:tag1:tag2:)

When text is highlighted, the argumentes beginning-of-selected-region and end-of-selected-region will be automatically populated.
"
    (interactive "r") ;; 'r' mode will auto-populate 'beginning-of-selected-region' and 'end-of-selected-region' above with the values of region-beginning and region-end.
    (if (use-region-p) ;; If a region is actively highlighted
        (progn ;; Start a multi-line sequence of commands   
            ;; Following https://learnxinyminutes.com/docs/elisp/, go to the beginning-of-selected-region (here, of the selected region), and do a find-and-replace.
            (setq list-of-tag-strings (list)) ;; Create a blank list, which we'll fill in below.

            (goto-char beginning-of-selected-region) ;; Go to the beginning of the selected region (we'll then search forward from there.

            ;; A regex of "{{\\(.*?\\)}}" below looks for tags in {{this}} form. You can specify any other regex here instead.
            (while (re-search-forward tag-regexp-for-generating-org-mode-tag-list-from-text end-of-selected-region 't) ;; Search forward, but only up to the end-point of the selected region (otherwise, end-of-selected-region could be replaced with nil here).
                (add-to-list 'list-of-tag-strings ;; Add to the list called list-of-tag-strings
                    (replace-regexp-in-string "[[:space:]|:|-]+" "_" (match-string 1)) ;; Since org-mode tags cannot have spaces or colons (or dashes?) within them, replace any of those in the first capture group from the regular expression above ('match-string 1' returns whatever was in the parentheses in the regular expression above) with an underscore.
                    t) ;; Append (first checking for duplicate items) the first capture group from the regular expression above (i.e., what's inside the parentheses in the regular expression) to a list. The t tells the function to append (rather than prepend) to the list.
            ) ;; End of while statement

            ;; Go to the end of the first line of the selected region.
            (goto-char beginning-of-selected-region)
            (end-of-line)

            (if (> (length list-of-tag-strings) 0) ;; If the length of the list of found tags is greater than 0:
                (insert "  " ":" (mapconcat 'identity list-of-tag-strings ":") ":")) ;; Insert two spaces, a ':', the items from the list each separated by a ':', and a final ':'.

            (message "Tags gathered from the selected region (which comprises character markers %d to %d) and printed on the first line of the region." beginning-of-selected-region end-of-selected-region))

        ;; 'Else' part of the statement:
        (message "No region is selected for gathering tags. To run the function, you need to highlight a region first.") 
    ))

然后,您可以突出显示这样的文字,并使用M-x generate-tag-list-from-selected-text

运行该功能
This is a test {{with}} some {{tags}} in it.
This is another test with an {{additional           tag}} and {{one:more}}.

此文本将成为

This is a test {{with}} some {{tags}} in it.  :with:tags:additional_tag:one_more:
This is another test with an {{additional           tag}} and {{one:more}}.

由于这是我在elisp中编写的第一个函数,因此我使用two sources来理解elisp语法的基础知识,特别是关于a)仅使用选定的文本和b)对该文本运行查找和替换操作。鉴于该函数使用代码的泛型结构与其特定内容,我认为我有权使用 CC0 dedication打开该函数。 (我这样做是因为StackOverflow的ongoing discussion关于此网站上代码的许可。)