使用 org-element 解析与特定标签(或属性)匹配的标题

问题描述 投票:0回答:1

我正在尝试根据

org-mode
缓冲区的某些部分编写自定义 Elisp 函数来进行字数统计,我想知道
org-element
是否有一个好方法来解析与某个标签(或属性)匹配的所有标题。更具体地说,我有一个像这样的缓冲区:

#+TITLE: My manuscript

Authors, affiliations, etc.

* Abstract       :abstract:

Text in the abstract.

* Introduction   :body:

Some sample text goes here.

* Methods        :body:

Some sample text goes here.

* Results        :body:

Some sample text goes here.

* Discussion     :body:

Some sample text goes here.

* References     :refs:

References go here.

我想获取与

:body:
标签匹配的所有标题的字数(即 20)。到目前为止,我一直在使用这个答案中的函数,它在返回标题的字数方面做得很好:

(require 'cl-lib)
(require 'org-element)

(defun org-element-parse-headline (&optional granularity visible-only)
  "Parse current headline.
GRANULARITY and VISIBLE-ONLY are like the args of `org-element-parse-buffer'."
  (let ((level (org-current-level)))
    (org-element-map
    (org-element-parse-buffer granularity visible-only)
    'headline
      (lambda (el)
    (and
     (eq (org-element-property :level el) level)
     (<= (org-element-property :begin el) (point))
     (<= (point) (org-element-property :end el))
     el))
      nil 'first-match 'no-recursion)))

(cl-defun org+-count-words-of-heading (&key (worthy '(paragraph bold italic underline code footnote-reference link strike-through subscript superscript table table-row table-cell))
                        (no-recursion nil))
  "Count words in the section of the current heading.
WORTHY is a list of things worthy to be counted.
This list should at least include the symbols:
paragraph, bold, italic, underline and strike-through.

If NO-RECURSION is non-nil don't count the words in subsections."
  (interactive (and current-prefix-arg
            (list :no-recursion t)))
  (let ((word-count 0))
    (org-element-map
    (org-element-contents (org-element-parse-headline))
    '(paragraph table)
      (lambda (par)
    (org-element-map
        par
        worthy
        (lambda (el)
          (cl-incf
           word-count
           (cl-loop
        for txt in (org-element-contents el)
        when (eq (org-element-type txt) 'plain-text)
        sum
        (with-temp-buffer
          (insert txt)
          (count-words (point-min) (point-max))))
           ))))
      nil nil (and no-recursion 'headline)
      )
      (when (called-interactively-p 'any)
      (message "Word count in section: %d" word-count))
    word-count))

我想我必须调整

org-element-parse-headline
函数来匹配标签,而不是抓住标题,但有人知道如何做到这一点吗?谢谢!

emacs org-mode word-count
1个回答
0
投票

要从整个缓冲区中获取结果,而不仅仅是当前点的标题,请设置

level
的值,例如。到
0
检查整个缓冲区。然后,要将匹配限制为具有特定标签的标题,请向
org-element-map
中的函数添加条件。

(defun my-org-element-parse-headline (&optional granularity visible-only)
  (let ((level 0)                       ; or restrict level
        (granularity (or granularity 'headline)))
    (org-element-map
        (org-element-parse-buffer granularity visible-only)
        granularity
      (lambda (el)
        ;; eg. restrict elements to levels greater than `level`
        (when (< level (org-element-property :level el))
          (and
           (member "body" (org-element-property :tags el))
           ;; ...
           el)))
      ;; dont set 'first-match if you want all the matches
      nil nil 'no-recursion)))

;; eg. results from your example org file
(mapcar (lambda (el) (org-element-property :raw-value el)) (my-org-element-parse-headline))
;; ("Introduction" "Methods" "Results" "Discussion")
© www.soinside.com 2019 - 2024. All rights reserved.