Coverage for hdl_registers/html_translator.py: 100%

30 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-01-29 22:03 +0000

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the hdl_registers project, a HDL register generator fast enough to be run 

5# in real time. 

6# https://hdl-registers.com 

7# https://gitlab.com/hdl_registers/hdl_registers 

8# -------------------------------------------------------------------------------------------------- 

9 

10# Standard libraries 

11import re 

12 

13 

14class HtmlTranslator: 

15 

16 r""" 

17 Translate a raw text with markdown/rst annotations into HTML code. 

18 

19 Supports: 

20 

21 * Strong: **double asterisks** 

22 * Emphasis: *single asterisks* 

23 

24 Literal asterisks should be escaped: \* 

25 """ 

26 

27 _not_escaped = r"(?<!\\)" 

28 _double_asterisks = r"\*\*" 

29 _single_asterisk = r"\*" 

30 _match_text = r"(.*?)" 

31 

32 # These patterns match asterisks only if they are not preceded by \escape 

33 _re_strong_pattern = re.compile( 

34 _not_escaped + _double_asterisks + _match_text + _not_escaped + _double_asterisks 

35 ) 

36 _re_emphasis_pattern = re.compile( 

37 _not_escaped + _single_asterisk + _match_text + _not_escaped + _single_asterisk 

38 ) 

39 

40 # This pattern matches escaped asterisks 

41 _re_escaped_literal_pattern = re.compile(r"\\(\*)") 

42 

43 # Consecutive newlines is a paragraph separator 

44 _re_paragraph_separator = re.compile(r"\n{2,}") 

45 

46 def translate(self, text): 

47 """ 

48 Translate the text to have HTML tags where appropriate. 

49 """ 

50 result = self._translate_angle_brackets(text) 

51 result = self._annotate(result) 

52 result = self._insert_line_breaks(result) 

53 return result 

54 

55 def _annotate(self, text): 

56 """ 

57 Replace markdown/rst syntax with HTML tags. 

58 """ 

59 result = re.sub(self._re_strong_pattern, r"<strong>\g<1></strong>", text) 

60 result = re.sub(self._re_emphasis_pattern, r"<em>\g<1></em>", result) 

61 # Remove the escape sign 

62 result = re.sub(self._re_escaped_literal_pattern, r"\g<1>", result) 

63 return result 

64 

65 def _insert_line_breaks(self, text): 

66 """ 

67 Insert HTML line break tag instead of consecutive newlines. 

68 """ 

69 # Two line breaks to get new paragraph. 

70 result = re.sub(self._re_paragraph_separator, "<br /><br />", text) 

71 # A single newline in Markdown should be a space 

72 result = result.replace("\n", " ") 

73 # Split to get nicer HTML file formatting 

74 result = result.replace("<br />", "<br />\n") 

75 return result 

76 

77 @staticmethod 

78 def _translate_angle_brackets(text): 

79 """ 

80 The HTML may not contain raw angle brackets ("<", ">") since they will be interpreted as 

81 HTML tags by the web browse. 

82 """ 

83 result = text.replace("<", "&lt;") 

84 result = result.replace(">", "&gt;") 

85 return result