Skip to content

Commit

Permalink
MNT: clean and test html output
Browse files Browse the repository at this point in the history
  • Loading branch information
klauer committed Oct 24, 2023
1 parent a5890f3 commit 4cd1d06
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 56 deletions.
97 changes: 41 additions & 56 deletions blark/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import collections
import dataclasses
import pathlib
from typing import Any, DefaultDict, Dict, List, Optional
from typing import Any, DefaultDict, Dict, Generator, List, Optional

import lark

Expand All @@ -13,6 +13,8 @@

@dataclasses.dataclass(frozen=True)
class HighlighterAnnotation:
"""A single HTML tag annotation which applies to a position range of source code."""

name: str
terminal: bool
is_open_tag: bool
Expand All @@ -34,13 +36,29 @@ def as_string(self, tag: str = "span") -> str:
return f'<{tag} class="{classes}">'


def add_annotation_pair(
def _add_annotation_pair(
annotations: DefaultDict[int, List[HighlighterAnnotation]],
name: str,
start_pos: int,
end_pos: int,
terminal: bool,
) -> None:
"""
Add a pair of HTML tag annotations to the position-indexed list.
Parameters
----------
annotations : DefaultDict[int, List[HighlighterAnnotation]]
Annotations keyed by 0-indexed string position.
name : str
Name of the annotation.
start_pos : int
String index position which the annotation applies to.
end_pos : int
String index position which the annotation ends at.
terminal : bool
Whether this is a TERMINAL (True) or a rule (false).
"""
annotations[start_pos].append(
HighlighterAnnotation(
name=name,
Expand All @@ -67,7 +85,7 @@ def get_annotations(tree: lark.Tree) -> DefaultDict[int, List[HighlighterAnnotat

for subtree in tree.iter_subtrees():
if hasattr(subtree.meta, "start_pos"):
add_annotation_pair(
_add_annotation_pair(
annotations,
name=subtree.data,
terminal=False,
Expand All @@ -77,7 +95,7 @@ def get_annotations(tree: lark.Tree) -> DefaultDict[int, List[HighlighterAnnotat
for child in subtree.children:
if isinstance(child, lark.Token):
if child.start_pos is not None and child.end_pos is not None:
add_annotation_pair(
_add_annotation_pair(
annotations,
name=child.type,
terminal=True,
Expand All @@ -91,57 +109,20 @@ def apply_annotations_to_code(
code: str,
annotations: Dict[int, List[HighlighterAnnotation]]
) -> str:
result = []
pos = 0
for pos, ch in enumerate(code):
for ann in reversed(annotations.get(pos, [])):
result.append(str(ann))
if ch == " ":
result.append("&nbsp;")
else:
result.append(ch)

for ann in annotations.get(pos + 1, []):
result.append(str(ann))

html = "".join(result)
html = f'<div class="blark-code">{html}</div>'
html = html.replace("\n", "<br/>\n")
# TODO remove
html = """
<style>
.blark-code {
font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;
}
.blark-code > .IDENTIFIER, .variable_name, .multi_element_variable {
font-weight: bold;
color: #208050;
}
.blark-code > .INTEGER, .SIGNED_INTEGER {
color: red;
}
.blark-code > .set_statement, .assignment_statement {
font-weight: bold;
}
.blark-code > .LOGICAL_OR, .LOGICAL_XOR, .LOGICAL_AND, .LOGICAL_NOT,
.LOGICAL_AND_THEN, .LOGICAL_OR_ELSE, .MODULO, .EQUALS, .EQUALS_NOT,
.LESS_OR_EQUAL, .GREATER_OR_EQUAL, .LESS_THAN, .GREATER_THAN, .ADDING,
.SUBTRACTING, .MULTIPLY_WITH, .DIVIDE_BY, .MINUS, .PLUS, .ASSIGNMENT {
font-weight: bold;
color: red;
}
.blark-code > .TYPE_TOD, .TYPE_DATETIME, .TYPE_LTOD, .TYPE_LDATETIME,
.elementary_type_name, .NUMERIC_TYPE_NAME, .INTEGER_TYPE_NAME,
.SIGNED_INTEGER_TYPE_NAME, .UNSIGNED_INTEGER_TYPE_NAME,
.REAL_TYPE_NAME, .DATE_TYPE_NAME, .BIT_STRING_TYPE_NAME,
.GENERIC_TYPE_NAME {
font-weight: bold;
color: blue;
}
</style>
""" + html # noqa: E501
return html
def annotate() -> Generator[str, None, None]:
pos = 0
for pos, ch in enumerate(code):
for ann in reversed(annotations.get(pos, [])):
yield str(ann)
if ch == " ":
yield "&nbsp;"
else:
yield ch

for ann in annotations.get(pos + 1, []):
yield str(ann)

return "".join(annotate())


@dataclasses.dataclass
Expand All @@ -152,17 +133,19 @@ class HtmlWriter:

@property
def source_code(self) -> str:
"""The source code associated with the block."""
assert self.block.origin is not None
return self.block.origin.source_code

def to_html(self) -> str:
"""HTML tag-annotated source code."""
assert self.block.origin is not None
assert self.block.origin.tree is not None
annotations = get_annotations(self.block.origin.tree)

for comment in self.block.origin.comments:
if comment.start_pos is not None and comment.end_pos is not None:
add_annotation_pair(
_add_annotation_pair(
annotations,
name=comment.type,
start_pos=comment.start_pos,
Expand All @@ -178,6 +161,7 @@ def save(
source_filename: Optional[pathlib.Path],
parts: List[OutputBlock],
) -> str:
"""Convert the source code block to HTML and return it."""
result = []
for part in parts:
writer = HtmlWriter(user, source_filename, part)
Expand All @@ -189,4 +173,5 @@ def save(
def _register():
"""Register the HTML output file handlers."""
register_output_handler("html", HtmlWriter.save)
register_output_handler(".htm", HtmlWriter.save)
register_output_handler(".html", HtmlWriter.save)
4 changes: 4 additions & 0 deletions blark/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ def test_blark_main_help(monkeypatch, args: List[str]):
["format", "--debug", "filename"],
id="format-debug",
),
param(
["format", "-o", "html", "filename"],
id="format-html",
),
]
)
def test_blark_main(monkeypatch, input_filename: str, args: List[str], skip_summary: bool):
Expand Down

0 comments on commit 4cd1d06

Please sign in to comment.