File: __init__.py

package info (click to toggle)
mdit-py-plugins 0.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 672 kB
  • sloc: python: 3,595; sh: 8; makefile: 7
file content (58 lines) | stat: -rw-r--r-- 1,791 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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()])


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)