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
« 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# --------------------------------------------------------------------------------------------------
10# Standard libraries
11import re
14class HtmlTranslator:
16 r"""
17 Translate a raw text with markdown/rst annotations into HTML code.
19 Supports:
21 * Strong: **double asterisks**
22 * Emphasis: *single asterisks*
24 Literal asterisks should be escaped: \*
25 """
27 _not_escaped = r"(?<!\\)"
28 _double_asterisks = r"\*\*"
29 _single_asterisk = r"\*"
30 _match_text = r"(.*?)"
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 )
40 # This pattern matches escaped asterisks
41 _re_escaped_literal_pattern = re.compile(r"\\(\*)")
43 # Consecutive newlines is a paragraph separator
44 _re_paragraph_separator = re.compile(r"\n{2,}")
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
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
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
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("<", "<")
84 result = result.replace(">", ">")
85 return result