[英]How to get pandoc lua filter avoid counting words using this pattern in code blocks inside Rmarkdown file?
這是這篇文章的后續問題。 我想要實現的是避免計算標題和具有這種模式的內部代碼塊中的單詞:
```{r label-name}
all code words not to be counted.
```
而不是這種模式:
```
{r label-name}
all code words not to be counted.
```
因為當我使用后一種模式時,我在 emacs 的 Rmarkdown 緩沖區中丟失了字體化鎖,所以我總是使用第一種模式。
考慮這個 MWE:
MWE (MWE-wordcount.Rmd)
# Results {-}
## Topic 1 {-}
This is just a random text with a citation in markdown \@ref(fig:pca-scree)).
Below is a code block.
```{r pca-scree, echo = FALSE, fig.align = "left", out.width = "80%", fig.cap = "Scree plot with parallel analysis using simulated data of 100 iterations (red line) suggests retaining only the first 2 components. Observed dimensions with their eigenvalues are shown in green."}
knitr::include_graphics("./plots/PCA_scree_parallel_analysis.png")
```
## Topic 2 {-}
<!-- todo: a comment that needs to be avoided by word count hopefully-->
結果應該只有 17 個字。 不計算代碼塊、注釋或 Markdown 標記(如標題)中的單詞。
我按照這里解釋的方法使用 lua 過濾器讓 pandoc 計算單詞數。 總之我做了這些步驟:
從命令行:
mkdir -p ~/.local/share/pandoc/filters
然后在那里創建了一個名為wordcount.lua
的文件,內容如下:
-- counts words in a document words = 0 wordcount = { Str = function(el) -- we don't count a word if it's entirely punctuation: if el.text:match("%P") then words = words + 1 end end, Code = function(el) _,n = el.text:gsub("%S+","") words = words + n end, } function Pandoc(el) -- skip metadata, just count body: pandoc.walk_block(pandoc.Div(el.blocks), wordcount) print(words.. " words in body") os.exit(0) end
我將以下 elisp 代碼放在臨時緩沖區中並對其進行了評估:
(defun pandoc-count-words () (interactive) (shell-command-on-region (point-min) (point-max) "pandoc --lua-filter wordcount.lua"))
從 MWE Markdown 文件 (MWE-wordcount.Rmd) 中,我發出了Mx pandoc-count-words
並在迷你緩沖區中獲得了計數。
使用第一個模式我得到 62 個單詞。
使用第二種模式我得到 22 個單詞,更合理。 這種方法成功地避免了對評論中的單詞進行計數。
問題
如何獲得 lua 過濾器代碼避免使用第一個模式而不是第二個模式來計算單詞?
如何獲得 lua 過濾器避免計算標題中的單詞##?
如果答案解釋了 lua 代碼的工作原理,我也將不勝感激。
這是一個有趣的問題,它結合了很多技術。 這里最重要的是 R Markdown,我們需要深入了解到底發生了什么。
R Markdown 處理的第一步之一是解析文檔,找到所有 R 代碼塊(由{r...}
模式標記),執行這些塊,並用評估結果替換塊。修改后的輸入文本是然后傳遞給 pandoc,后者將其解析為抽象文檔樹 (AST)。在 pandoc 以目標格式寫入文檔之前,可以使用過濾器檢查或修改 AST。
這是相關的,因為識別表單輸入的是 R Markdown,而不是pandoc
``` {r ...}
# code
```
作為代碼塊,而 pandoc 將它們解析為與` {r...} # code `
code`相同的內聯代碼,即代碼中的所有換行符都被忽略。 原因在於 pandoc 的屬性解析和 Markdown 語法中`
chars 的重載。¹
這給了我們第一個問題的答案:我們不能! 這兩個代碼片段在到達 pandoc 的 AST 中的過濾器時看起來完全相同; 他們無法區分。 但是,如果我們運行 R Markdown 的knitr步驟來執行代碼,我們將獲得帶有換行符的正確代碼塊。
因此,一種解決方案可能是使wordcount.lua
過濾器成為 R Markdown 處理步驟的一部分,但僅在設置COUNT_WORDS
環境變量時運行過濾器。 我們可以通過將此片段添加到過濾器文件的頂部來做到這一點:
if not os.getenv 'COUNT_WORDS` then
return {}
end
有關如何 集成過濾器的信息,請參閱 R Markdown 食譜。
我省略了第二個問題,因為這個答案已經很長了,那個子問題值得單獨發帖。
¹:如果r
前面有一個點,pandoc 會將其識別為代碼塊,如
``` {.r}
# code
```
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.