Source code for mdit_py_plugins.wordcount
import string
from typing import Callable, List
from markdown_it import MarkdownIt
from markdown_it.rules_core import StateCore
def basic_count(text: str) -> int:
"""Split the string and ignore punctuation only elements."""
return sum([el.strip(string.punctuation).isalpha() for el in text.split()])
[docs]def wordcount_plugin(
md: MarkdownIt,
*,
per_minute: int = 200,
count_func: Callable[[str], int] = basic_count,
store_text: bool = False,
) -> None:
"""Plugin for computing and storing the word count.
Stores in the ``env`` e.g.::
env["wordcount"] = {
"words": 200
"minutes": 1,
}
If "wordcount" is already in the env, it will update it.
:param per_minute: Words per minute reading speed
:param store_text: store all text under a "text" key, as a list of strings
"""
def _word_count_rule(state: StateCore) -> None:
text: List[str] = []
words = 0
for token in state.tokens:
if token.type == "text":
words += count_func(token.content)
if store_text:
text.append(token.content)
elif token.type == "inline":
for child in token.children or ():
if child.type == "text":
words += count_func(child.content)
if store_text:
text.append(child.content)
data = state.env.setdefault("wordcount", {})
if store_text:
data.setdefault("text", [])
data["text"] += text
data.setdefault("words", 0)
data["words"] += words
data["minutes"] = int(round(data["words"] / per_minute))
md.core.ruler.push("wordcount", _word_count_rule)