Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/mdit_py_plugins/wordcount/__init__.py: 79%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

29 statements  

1import string 

2from typing import Callable, List 

3 

4from markdown_it import MarkdownIt 

5from markdown_it.rules_core import StateCore 

6 

7 

8def basic_count(text: str) -> int: 

9 """Split the string and ignore punctuation only elements.""" 

10 return sum([el.strip(string.punctuation).isalpha() for el in text.split()]) 

11 

12 

13def wordcount_plugin( 

14 md: MarkdownIt, 

15 *, 

16 per_minute: int = 200, 

17 count_func: Callable[[str], int] = basic_count, 

18 store_text: bool = False, 

19) -> None: 

20 """Plugin for computing and storing the word count. 

21 

22 Stores in the ``env`` e.g.:: 

23 

24 env["wordcount"] = { 

25 "words": 200 

26 "minutes": 1, 

27 } 

28 

29 If "wordcount" is already in the env, it will update it. 

30 

31 :param per_minute: Words per minute reading speed 

32 :param store_text: store all text under a "text" key, as a list of strings 

33 """ 

34 

35 def _word_count_rule(state: StateCore) -> None: 

36 text: List[str] = [] 

37 words = 0 

38 for token in state.tokens: 

39 if token.type == "text": 

40 words += count_func(token.content) 

41 if store_text: 

42 text.append(token.content) 

43 elif token.type == "inline": 

44 for child in token.children or (): 

45 if child.type == "text": 

46 words += count_func(child.content) 

47 if store_text: 

48 text.append(child.content) 

49 

50 data = state.env.setdefault("wordcount", {}) 

51 if store_text: 

52 data.setdefault("text", []) 

53 data["text"] += text 

54 data.setdefault("words", 0) 

55 data["words"] += words 

56 data["minutes"] = int(round(data["words"] / per_minute)) 

57 

58 md.core.ruler.push("wordcount", _word_count_rule)