1# Purpose: Create a structured HTML view of raw DXF tags - not a CAD drawing!
2# Created: 17.01.2018
3# Copyright (C) 2018, Manfred Moitzi
4# License: MIT License
5"""
6Creates a structured HTML view of raw DXF tags - not a CAD drawing!
7"""
8from typing import Iterable
9from ezdxf.tools import escape
10from ezdxf.lldxf.tags import group_tags, DXFTag
11from ezdxf.lldxf.types import GROUP_MARKERS, BINARY_FLAGS, HEX_HANDLE_CODES
12from ezdxf.tools.binarydata import bytes_to_hexstr
13from .dxfpp import tag_type_str, load_resource, with_bitmask, MAX_STR_LEN
14
15TAG_TPL = '<div class="dxf-tag" ><span class="tag-code">{code}</span> <span class="var-type">{type}</span>' \
16          ' <span class="tag-value">{value}</span></div>'
17MARKER_TPL = '<div class="tag-group-marker">{tag}</div>'
18CONTROL_TPL = '<div class="tag-control-tag">{tag}</div>'
19
20
21def rawpp(tagger: Iterable[DXFTag], filename: str, binary=False) -> str:
22    def tag2html(tag: DXFTag) -> str:
23        type_str = tag_type_str(tag.code)
24        value = tag.value
25        if tag.code in BINARY_FLAGS:
26            vstr = with_bitmask(value)
27        else:
28
29            if isinstance(value, bytes):
30                vstr = bytes_to_hexstr(value)
31            else:
32                vstr = str(tag.value)
33                if tag.code in HEX_HANDLE_CODES:
34                    vstr = '#' + vstr
35        if len(vstr) > MAX_STR_LEN:
36            vstr = vstr[:MAX_STR_LEN - 3] + '...'
37        return TAG_TPL.format(code=tag.code, value=escape(vstr), type=escape(type_str))
38
39    def marker(tag: DXFTag, tag_html: str) -> str:
40        if tag.code == 0:
41            return CONTROL_TPL.format(tag=tag_html)
42        elif tag.code in GROUP_MARKERS:
43            return MARKER_TPL.format(tag=tag_html)
44        else:
45            return tag_html
46
47    def tags2html(tags: Iterable[DXFTag]) -> str:
48        return '\n'.join(marker(tag, tag2html(tag)) for tag in tags)
49
50    def groups(tags: Iterable[DXFTag]) -> Iterable[str]:
51        for group in group_tags(tags, splitcode=0):
52            yield '<div class="dxf-tag-group">\n{content}\n</div>'.format(content=tags2html(group))
53
54    def dxf_control_structures(tags: Iterable[DXFTag]) -> str:
55        return '\n'.join(groups(tags))
56
57    template = load_resource('rawpp.html')
58    return template.format(
59        name=filename + (' (bin)' if binary else ' (asc)'),
60        css=load_resource('rawpp.css'),
61        dxf_file=dxf_control_structures(tagger),
62    )
63