如何在组织模式下引用代码块点?
How to reference a code block points in org mode?
我想使用 libxml-parse-html-region
来测试一些 HTML 提取函数。但它只接受区域点作为输入参数。 Org 模式是否提供了一种将另一个代码块引用为 region 的方法?
例如
#+Name: html-test
#+BEGIN_EXAMPLE
<html>
<body>test</body>
</html>
#+END_EXAMPLE
#+BEGIN_SRC elisp
(libxml-parse-html-region html-test-start-point html-test-end-point)
#+END_SRC
那么,如何设置 html-test-start-point
和 html-test-end-point
?
查阅手册后,我怀疑没有简单的方法可以实现。
您可以使用其他块作为参数,如 https://orgmode.org/worg/org-contrib/babel/intro.html#arguments-to-source-code-blocks,但是 libxml
没有接受字符串的函数。
#+name: html-test
#+begin_example
<html>
<body>test</body>
</html>
#+end_example
#+begin_src elisp :var html=html-test
(message html)
#+end_src
org-element
库(Org 模式的官方解析器)提供了将块主体作为字符串获取的功能。然后您可以将该字符串插入临时缓冲区,其中由 (point-min)
和 (point-max)
指定的区域恰好包含块的主体。您可以在 Worg.
上找到该库的开发人员文档
由于您没有准确指定接口,我在这里只能提供一些指导。基本思想是以某种方式将点设置到示例块的开头(可能通过搜索名称 html-test
然后移动到行的开头)。到达那里后,您调用 org-element-at-point
来解析元素(也许 sanity-check 您在示例块中)。从解析树中,提取 :value
属性 的值作为字符串作为块的主体。创建一个临时缓冲区,插入字符串,然后在临时缓冲区的上下文中执行 libxml
函数。
这里是一些说明性代码,评论相当自由,我希望以一种启发性的方式(对于神秘的 (goto-char 130)
,请继续阅读 - 它在下面完整的 Org 模式文件中有解释):
(save-excursion
;; this should probably be replaced by a search for the correct place
(goto-char 130)
;; parse the element at point
(setq parsed (org-element-at-point))
;; check that it is an example block
(unless (eq (org-element-type parsed) 'example-block)
(error "Not an example block"))
;; retrieve the :value property, i.e, the body of the block
(setq value (org-element-property :value parsed))
;; create a temp buffer
(with-temp-buffer
;; in the context of the temp buffer, insert the body of the block
(insert value)
;; do something with the region containing the body by using (point-min)
;; as the beginning of the region and (point-max) as the end
(message (buffer-substring (point-min) (point-max)))
(libxml-parse-html-region (point-min) (point-max))))
这是与 Org 模式文件中的代码块相同的代码,其中包含代码块可以操作的示例块。 Cut-and-paste 将整个内容放入一个 foo.org
文件中,在 emacs 中打开它并在代码块上 C-c C-c
以查看它的运行情况:
* foo
We have a named block and we want to get the beginning and the end of the region
that consists of the body of the block.
#+Name: html-test
#+BEGIN_EXAMPLE
<html>
<body>test</body>
</html>
#+END_EXAMPLE
The position of the beginning of the block is 130 - you can check by evaluating
this expression with C-x C-e after the closing paren:
(goto-char 130)
You should end up at the beginning of the `#+name:` line.
If we imagine a code block like this:
#+BEGIN_SRC elisp
(libxml-parse-html-region html-test-start-point html-test-end-point)
#+END_SRC
the question is how to calculate the html-test-{start,end}-point values.
The suggested solution is to copy the body of the block to a temporary
buffer and do the evaluation of the XML function in that buffer. The region
is then delimited by (point-min) and (point-max).
* Code :noexport:
#+begin_src elisp :results drawer
(save-excursion
;; this should probably be replaced by a search for the correct place
(goto-char 130)
;; parse the element at point
(setq parsed (org-element-at-point))
;; check that it is an example block
(unless (eq (org-element-type parsed) 'example-block)
(error "Not an example block"))
;; retrieve the :value property, i.e, the body of the block
(setq value (org-element-property :value parsed))
;; create a temp buffer
(with-temp-buffer
;; in the context of the temp buffer, insert the body of the block
(insert value)
;; do something with the region containing the body by using (point-min)
;; as the beginning of the region and (point-max) as the end
(message (buffer-substring (point-min) (point-max)))
(libxml-parse-html-region (point-min) (point-max))))
#+end_src
正如OP在评论中指出的和@TianshuWang在他的回答中所描述的,您可以在源代码块中添加一个变量并直接获取示例块的主体:
#+begin_src elisp :results drawer :var value=html-test
;; create a temp buffer
(with-temp-buffer
;; in the context of the temp buffer, insert the body of the block
(insert value)
;; do something with the region containing the body by using (point-min)
;; as the beginning of the region and (point-max) as the end
(message (buffer-substring (point-min) (point-max)))
(libxml-parse-html-region (point-min) (point-max))))
#+end_src
但这绕过了 org-element
库:那有什么好玩的? :-)
我想使用 libxml-parse-html-region
来测试一些 HTML 提取函数。但它只接受区域点作为输入参数。 Org 模式是否提供了一种将另一个代码块引用为 region 的方法?
例如
#+Name: html-test
#+BEGIN_EXAMPLE
<html>
<body>test</body>
</html>
#+END_EXAMPLE
#+BEGIN_SRC elisp
(libxml-parse-html-region html-test-start-point html-test-end-point)
#+END_SRC
那么,如何设置 html-test-start-point
和 html-test-end-point
?
查阅手册后,我怀疑没有简单的方法可以实现。
您可以使用其他块作为参数,如 https://orgmode.org/worg/org-contrib/babel/intro.html#arguments-to-source-code-blocks,但是 libxml
没有接受字符串的函数。
#+name: html-test
#+begin_example
<html>
<body>test</body>
</html>
#+end_example
#+begin_src elisp :var html=html-test
(message html)
#+end_src
org-element
库(Org 模式的官方解析器)提供了将块主体作为字符串获取的功能。然后您可以将该字符串插入临时缓冲区,其中由 (point-min)
和 (point-max)
指定的区域恰好包含块的主体。您可以在 Worg.
由于您没有准确指定接口,我在这里只能提供一些指导。基本思想是以某种方式将点设置到示例块的开头(可能通过搜索名称 html-test
然后移动到行的开头)。到达那里后,您调用 org-element-at-point
来解析元素(也许 sanity-check 您在示例块中)。从解析树中,提取 :value
属性 的值作为字符串作为块的主体。创建一个临时缓冲区,插入字符串,然后在临时缓冲区的上下文中执行 libxml
函数。
这里是一些说明性代码,评论相当自由,我希望以一种启发性的方式(对于神秘的 (goto-char 130)
,请继续阅读 - 它在下面完整的 Org 模式文件中有解释):
(save-excursion
;; this should probably be replaced by a search for the correct place
(goto-char 130)
;; parse the element at point
(setq parsed (org-element-at-point))
;; check that it is an example block
(unless (eq (org-element-type parsed) 'example-block)
(error "Not an example block"))
;; retrieve the :value property, i.e, the body of the block
(setq value (org-element-property :value parsed))
;; create a temp buffer
(with-temp-buffer
;; in the context of the temp buffer, insert the body of the block
(insert value)
;; do something with the region containing the body by using (point-min)
;; as the beginning of the region and (point-max) as the end
(message (buffer-substring (point-min) (point-max)))
(libxml-parse-html-region (point-min) (point-max))))
这是与 Org 模式文件中的代码块相同的代码,其中包含代码块可以操作的示例块。 Cut-and-paste 将整个内容放入一个 foo.org
文件中,在 emacs 中打开它并在代码块上 C-c C-c
以查看它的运行情况:
* foo
We have a named block and we want to get the beginning and the end of the region
that consists of the body of the block.
#+Name: html-test
#+BEGIN_EXAMPLE
<html>
<body>test</body>
</html>
#+END_EXAMPLE
The position of the beginning of the block is 130 - you can check by evaluating
this expression with C-x C-e after the closing paren:
(goto-char 130)
You should end up at the beginning of the `#+name:` line.
If we imagine a code block like this:
#+BEGIN_SRC elisp
(libxml-parse-html-region html-test-start-point html-test-end-point)
#+END_SRC
the question is how to calculate the html-test-{start,end}-point values.
The suggested solution is to copy the body of the block to a temporary
buffer and do the evaluation of the XML function in that buffer. The region
is then delimited by (point-min) and (point-max).
* Code :noexport:
#+begin_src elisp :results drawer
(save-excursion
;; this should probably be replaced by a search for the correct place
(goto-char 130)
;; parse the element at point
(setq parsed (org-element-at-point))
;; check that it is an example block
(unless (eq (org-element-type parsed) 'example-block)
(error "Not an example block"))
;; retrieve the :value property, i.e, the body of the block
(setq value (org-element-property :value parsed))
;; create a temp buffer
(with-temp-buffer
;; in the context of the temp buffer, insert the body of the block
(insert value)
;; do something with the region containing the body by using (point-min)
;; as the beginning of the region and (point-max) as the end
(message (buffer-substring (point-min) (point-max)))
(libxml-parse-html-region (point-min) (point-max))))
#+end_src
正如OP在评论中指出的和@TianshuWang在他的回答中所描述的,您可以在源代码块中添加一个变量并直接获取示例块的主体:
#+begin_src elisp :results drawer :var value=html-test
;; create a temp buffer
(with-temp-buffer
;; in the context of the temp buffer, insert the body of the block
(insert value)
;; do something with the region containing the body by using (point-min)
;; as the beginning of the region and (point-max) as the end
(message (buffer-substring (point-min) (point-max)))
(libxml-parse-html-region (point-min) (point-max))))
#+end_src
但这绕过了 org-element
库:那有什么好玩的? :-)