diff --git a/example.html b/example.html
deleted file mode 100644
index 3c62f4b..0000000
--- a/example.html
+++ /dev/null
@@ -1,890 +0,0 @@
-
-
-
-
-
- diff: example_old.py / example.py
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1 #!/usr/bin/env python3
-
1 #!/usr/bin/env python3
-
2
-
2
-
3 import math
-
3 import math
-
4 import itertools
-
4 import itertools
-
5 import textwrap
-
5 import textwrap
-
Collapse 24 unchanged lines
-
6
-
6
-
7 import click
-
7 import click
-
8 from reedmuller import reedmuller
-
8 from reedmuller import reedmuller
-
9
-
9
-
10
-
10
-
11 class Tag :
-
11 class Tag :
-
12 """ Helper class to ease creation of SVG. All API functions that create SVG allow you to substitute this with your
-
12 """ Helper class to ease creation of SVG. All API functions that create SVG allow you to substitute this with your
-
13 own implementation by passing a ``tag`` parameter. """
-
13 own implementation by passing a ``tag`` parameter. """
-
14
-
14
-
15 def __init__ ( self , name , children = None , root = False , * * attrs ) :
-
15 def __init__ ( self , name , children = None , root = False , * * attrs ) :
-
16 if ( fill := attrs . get ( ' fill ' ) ) and isinstance ( fill , tuple ) :
-
16 if ( fill := attrs . get ( ' fill ' ) ) and isinstance ( fill , tuple ) :
-
17 attrs [ ' fill ' ] , attrs [ ' fill-opacity ' ] = fill
-
17 attrs [ ' fill ' ] , attrs [ ' fill-opacity ' ] = fill
-
18 if ( stroke := attrs . get ( ' stroke ' ) ) and isinstance ( stroke , tuple ) :
-
18 if ( stroke := attrs . get ( ' stroke ' ) ) and isinstance ( stroke , tuple ) :
-
19 attrs [ ' stroke ' ] , attrs [ ' stroke-opacity ' ] = stroke
-
19 attrs [ ' stroke ' ] , attrs [ ' stroke-opacity ' ] = stroke
-
20 self . name , self . attrs = name , attrs
-
20 self . name , self . attrs = name , attrs
-
21 self . children = children or [ ]
-
21 self . children = children or [ ]
-
22 self . root = root
-
22 self . root = root
-
23
-
23
-
24 def __str__ ( self ) :
-
24 def __str__ ( self ) :
-
25 prefix = ' <?xml version= " 1.0 " encoding= " utf-8 " ?> \n ' if self . root else ' '
-
25 prefix = ' <?xml version= " 1.0 " encoding= " utf-8 " ?> \n ' if self . root else ' '
-
26 opening = ' ' . join ( [ self . name ] + [ f ' { key . replace ( " __ " , " : " ) . replace ( " _ " , " - " ) } = " { value } " ' for key , value in self . attrs . items ( ) ] )
-
26 opening = ' ' . join ( [ self . name ] + [ f ' { key . replace ( " __ " , " : " ) . replace ( " _ " , " - " ) } = " { value } " ' for key , value in self . attrs . items ( ) ] )
-
27 if self . children :
-
27 if self . children :
-
28 children = ' \n ' . join ( textwrap . indent ( str ( c ) , ' ' ) for c in self . children )
-
28 children = ' \n ' . join ( textwrap . indent ( str ( c ) , ' ' ) for c in self . children )
-
29 return f ' { prefix } < { opening } > \n { children } \n </ { self . name } > '
-
29 return f ' { prefix } < { opening } > \n { children } \n </ { self . name } > '
-
-
30 else :
-
30 else :
-
31 return f ' { prefix } < { opening } /> '
-
31 return f ' { prefix } < { opening } /> '
-
32
-
32
-
33
-
33
-
34 @classmethod
-
34 @classmethod
-
35 def setup_svg ( kls , tags , bounds , margin = 0 , unit = ' mm ' , pagecolor = ' white ' ) :
-
35 def setup_svg ( kls , tags , bounds , unit = ' mm ' , pagecolor = ' white ' , inkscape = False ) :
-
36 ( min_x , min_y ) , ( max_x , max_y ) = bounds
-
36 ( min_x , min_y ) , ( max_x , max_y ) = bounds
-
37
-
-
38 if margin :
-
-
39 min_x - = margin
-
-
40 min_y - = margin
-
-
41 max_x + = margin
-
-
42 max_y + = margin
-
-
43
-
37
-
44 w , h = max_x - min_x , max_y - min_y
-
38 w , h = max_x - min_x , max_y - min_y
-
45 w = 1.0 if math . isclose ( w , 0.0 ) else w
-
39 w = 1.0 if math . isclose ( w , 0.0 ) else w
-
46 h = 1.0 if math . isclose ( h , 0.0 ) else h
-
40 h = 1.0 if math . isclose ( h , 0.0 ) else h
-
47
-
41
-
-
42 if inkscape :
-
-
43 tags . insert ( 0 , kls ( ' sodipodi:namedview ' , [ ] , id = ' namedview1 ' , pagecolor = pagecolor ,
-
-
44 inkscape__document_units = unit ) )
-
48 namespaces = dict (
-
45 namespaces = dict (
-
49 xmlns = " http://www.w3.org/2000/svg " ,
-
46 xmlns = " http://www.w3.org/2000/svg " ,
-
-
47 xmlns__xlink = " http://www.w3.org/1999/xlink " ,
-
-
48 xmlns__sodipodi = ' http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd ' ,
-
-
49 xmlns__inkscape = ' http://www.inkscape.org/namespaces/inkscape ' )
-
-
50
-
-
51 else :
-
-
52 namespaces = dict (
-
-
53 xmlns = " http://www.w3.org/2000/svg " ,
-
50 xmlns__xlink = " http://www.w3.org/1999/xlink " )
-
54 xmlns__xlink = " http://www.w3.org/1999/xlink " )
-
51
-
55
-
52 return kls ( ' svg ' , tags ,
-
56 return kls ( ' svg ' , tags ,
-
53 width = f ' { w } { unit } ' , height = f ' { h } { unit } ' ,
-
57 width = f ' { w } { unit } ' , height = f ' { h } { unit } ' ,
-
54 viewBox = f ' { min_x } { min_y } { w } { h } ' ,
-
58 viewBox = f ' { min_x } { min_y } { w } { h } ' ,
-
55 style = f ' background-color: { pagecolor } ' ,
-
59 style = f ' background-color: { pagecolor } ' ,
-
Collapse 49 unchanged lines
-
56 * * namespaces ,
-
60 * * namespaces ,
-
57 root = True )
-
61 root = True )
-
58
-
62
-
59
-
63
-
60 @click . command ( )
-
64 @click . command ( )
-
61 @click . option ( ' -h ' , ' --height ' , type = float , default = 20 , help = ' Bar height in mm ' )
-
65 @click . option ( ' -h ' , ' --height ' , type = float , default = 20 , help = ' Bar height in mm ' )
-
62 @click . option ( ' -t/-n ' , ' --text/--no-text ' , default = True , help = ' Whether to add text containing the data under the bar code ' )
-
66 @click . option ( ' -t/-n ' , ' --text/--no-text ' , default = True , help = ' Whether to add text containing the data under the bar code ' )
-
63 @click . option ( ' -f ' , ' --font ' , default = ' sans-serif ' , help = ' Font for the text underneath the bar code ' )
-
67 @click . option ( ' -f ' , ' --font ' , default = ' sans-serif ' , help = ' Font for the text underneath the bar code ' )
-
64 @click . option ( ' -s ' , ' --font-size ' , type = float , default = 12 , help = ' Font size for the text underneath the bar code in points (pt) ' )
-
68 @click . option ( ' -s ' , ' --font-size ' , type = float , default = 12 , help = ' Font size for the text underneath the bar code in points (pt) ' )
-
65 @click . option ( ' -b ' , ' --bar-width ' , type = float , default = 1.0 , help = ' Bar width in mm ' )
-
69 @click . option ( ' -b ' , ' --bar-width ' , type = float , default = 1.0 , help = ' Bar width in mm ' )
-
66 @click . option ( ' -m ' , ' --margin ' , type = float , default = 3.0 , help = ' Margin around bar code in mm ' )
-
70 @click . option ( ' -m ' , ' --margin ' , type = float , default = 3.0 , help = ' Margin around bar code in mm ' )
-
67 @click . option ( ' -c ' , ' --color ' , default = ' black ' , help = ' SVG color for the bar code ' )
-
71 @click . option ( ' -c ' , ' --color ' , default = ' black ' , help = ' SVG color for the bar code ' )
-
68 @click . option ( ' --text-color ' , default = None , help = ' SVG color for the text (defaults to the bar code \' s color) ' )
-
72 @click . option ( ' --text-color ' , default = None , help = ' SVG color for the text (defaults to the bar code \' s color) ' )
-
69 @click . option ( ' --dpi ' , type = float , default = 96 , help = ' DPI value to assume for internal SVG unit conversions ' )
-
73 @click . option ( ' --dpi ' , type = float , default = 96 , help = ' DPI value to assume for internal SVG unit conversions ' )
-
70 @click . argument ( ' data ' )
-
74 @click . argument ( ' data ' )
-
71 @click . argument ( ' outfile ' , type = click . File ( ' w ' ) , default = ' - ' )
-
75 @click . argument ( ' outfile ' , type = click . File ( ' w ' ) , default = ' - ' )
-
72 def cli ( data , outfile , height , text , font , font_size , bar_width , margin , color , text_color , dpi ) :
-
76 def cli ( data , outfile , height , text , font , font_size , bar_width , margin , color , text_color , dpi ) :
-
73 data = int ( data , 16 )
-
77 data = int ( data , 16 )
-
74 text_color = text_color or color
-
78 text_color = text_color or color
-
75
-
79
-
76 NUM_BITS = 26
-
80 NUM_BITS = 26
-
77
-
81
-
78 data_bits = [ bool ( data & ( 1 << i ) ) for i in range ( NUM_BITS ) ]
-
82 data_bits = [ bool ( data & ( 1 << i ) ) for i in range ( NUM_BITS ) ]
-
79 data_encoded = itertools . chain ( * [
-
83 data_encoded = itertools . chain ( * [
-
80 ( a , not a ) for a in data_bits
-
84 ( a , not a ) for a in data_bits
-
81 ] )
-
85 ] )
-
82 data_encoded = [ True , False , True , False , * data_encoded , False , True , True , False , True ]
-
86 data_encoded = [ True , False , True , False , * data_encoded , False , True , True , False , True ]
-
83
-
87
-
84 width = len ( data_encoded ) * bar_width
-
88 width = len ( data_encoded ) * bar_width
-
85 # 1 px = 0.75 pt
-
89 # 1 px = 0.75 pt
-
86 pt_to_mm = lambda pt : pt / 0.75 / dpi * 25.4
-
90 pt_to_mm = lambda pt : pt / 0.75 / dpi * 25.4
-
87 font_size = pt_to_mm ( font_size )
-
91 font_size = pt_to_mm ( font_size )
-
88 total_height = height + font_size * 2
-
92 total_height = height + font_size * 2
-
89
-
93
-
90 tags = [ ]
-
94 tags = [ ]
-
91 for key , group in itertools . groupby ( enumerate ( data_encoded ) , key = lambda x : x [ 1 ] ) :
-
95 for key , group in itertools . groupby ( enumerate ( data_encoded ) , key = lambda x : x [ 1 ] ) :
-
92 if key :
-
96 if key :
-
93 group = list ( group )
-
97 group = list ( group )
-
94 x0 , _key = group [ 0 ]
-
98 x0 , _key = group [ 0 ]
-
95 w = len ( group )
-
99 w = len ( group )
-
96 tags . append ( Tag ( ' path ' , stroke = color , stroke_width = w , d = f ' M { ( x0 + w / 2 ) * bar_width } 0 l 0 { height } ' ) )
-
100 tags . append ( Tag ( ' path ' , stroke = color , stroke_width = w , d = f ' M { ( x0 + w / 2 ) * bar_width } 0 l 0 { height } ' ) )
-
97
-
101
-
98 if text :
-
102 if text :
-
99 tags . append ( Tag ( ' text ' , children = [ f ' { data : 07x } ' ] ,
-
103 tags . append ( Tag ( ' text ' , children = [ f ' { data : 07x } ' ] ,
-
100 x = width / 2 , y = height + 0.5 * font_size ,
-
104 x = width / 2 , y = height + 0.5 * font_size ,
-
101 font_family = font , font_size = f ' { font_size : .3f } px ' ,
-
105 font_family = font , font_size = f ' { font_size : .3f } px ' ,
-
102 text_anchor = ' middle ' , dominant_baseline = ' hanging ' ,
-
106 text_anchor = ' middle ' , dominant_baseline = ' hanging ' ,
-
103 fill = text_color ) )
-
107 fill = text_color ) )
-
104
-
108
-
-
105 outfile . write ( str ( Tag . setup_svg ( tags , bounds = ( ( 0 , 0 ) , ( width , total_height ) ) , margin = margin ) ) )
-
109 outfile . write ( str ( Tag . setup_svg ( tags , bounds = ( ( 0 , 0 ) , ( width , total_height ) ) , margin = margin ) ) )
-
106
-
110
-
107
-
111
-
108 if __name__ == ' __main__ ' :
-
112 if __name__ == ' __main__ ' :
-
109 cli ( )
-
113 cli ( )
-
-
-
-
-
-
diff --git a/example.py b/example.py
deleted file mode 100644
index 2e22e20..0000000
--- a/example.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env python3
-
-import math
-import itertools
-import textwrap
-
-import click
-from reedmuller import reedmuller
-
-
-class Tag:
- """ Helper class to ease creation of SVG. All API functions that create SVG allow you to substitute this with your
- own implementation by passing a ``tag`` parameter. """
-
- def __init__(self, name, children=None, root=False, **attrs):
- if (fill := attrs.get('fill')) and isinstance(fill, tuple):
- attrs['fill'], attrs['fill-opacity'] = fill
- if (stroke := attrs.get('stroke')) and isinstance(stroke, tuple):
- attrs['stroke'], attrs['stroke-opacity'] = stroke
- self.name, self.attrs = name, attrs
- self.children = children or []
- self.root = root
-
- def __str__(self):
- prefix = '\n' if self.root else ''
- opening = ' '.join([self.name] + [f'{key.replace("__", ":").replace("_", "-")}="{value}"' for key, value in self.attrs.items()])
- if self.children:
- children = '\n'.join(textwrap.indent(str(c), ' ') for c in self.children)
- return f'{prefix}<{opening}>\n{children}\n{self.name}>'
- else:
- return f'{prefix}<{opening}/>'
-
-
- @classmethod
- def setup_svg(kls, tags, bounds, unit='mm', pagecolor='white', inkscape=False):
- (min_x, min_y), (max_x, max_y) = bounds
-
- w, h = max_x - min_x, max_y - min_y
- w = 1.0 if math.isclose(w, 0.0) else w
- h = 1.0 if math.isclose(h, 0.0) else h
-
- if inkscape:
- tags.insert(0, kls('sodipodi:namedview', [], id='namedview1', pagecolor=pagecolor,
- inkscape__document_units=unit))
- namespaces = dict(
- xmlns="http://www.w3.org/2000/svg",
- xmlns__xlink="http://www.w3.org/1999/xlink",
- xmlns__sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
- xmlns__inkscape='http://www.inkscape.org/namespaces/inkscape')
-
- else:
- namespaces = dict(
- xmlns="http://www.w3.org/2000/svg",
- xmlns__xlink="http://www.w3.org/1999/xlink")
-
- return kls('svg', tags,
- width=f'{w}{unit}', height=f'{h}{unit}',
- viewBox=f'{min_x} {min_y} {w} {h}',
- style=f'background-color:{pagecolor}',
- **namespaces,
- root=True)
-
-
-@click.command()
-@click.option('-h', '--height', type=float, default=20, help='Bar height in mm')
-@click.option('-t/-n', '--text/--no-text', default=True, help='Whether to add text containing the data under the bar code')
-@click.option('-f', '--font', default='sans-serif', help='Font for the text underneath the bar code')
-@click.option('-s', '--font-size', type=float, default=12, help='Font size for the text underneath the bar code in points (pt)')
-@click.option('-b', '--bar-width', type=float, default=1.0, help='Bar width in mm')
-@click.option('-m', '--margin', type=float, default=3.0, help='Margin around bar code in mm')
-@click.option('-c', '--color', default='black', help='SVG color for the bar code')
-@click.option('--text-color', default=None, help='SVG color for the text (defaults to the bar code\'s color)')
-@click.option('--dpi', type=float, default=96, help='DPI value to assume for internal SVG unit conversions')
-@click.argument('data')
-@click.argument('outfile', type=click.File('w'), default='-')
-def cli(data, outfile, height, text, font, font_size, bar_width, margin, color, text_color, dpi):
- data = int(data, 16)
- text_color = text_color or color
-
- NUM_BITS = 26
-
- data_bits = [bool(data & (1<\n{children}\n{self.name}>'
- else:
- return f'{prefix}<{opening}/>'
-
-
- @classmethod
- def setup_svg(kls, tags, bounds, margin=0, unit='mm', pagecolor='white'):
- (min_x, min_y), (max_x, max_y) = bounds
-
- if margin:
- min_x -= margin
- min_y -= margin
- max_x += margin
- max_y += margin
-
- w, h = max_x - min_x, max_y - min_y
- w = 1.0 if math.isclose(w, 0.0) else w
- h = 1.0 if math.isclose(h, 0.0) else h
-
- namespaces = dict(
- xmlns="http://www.w3.org/2000/svg",
- xmlns__xlink="http://www.w3.org/1999/xlink")
-
- return kls('svg', tags,
- width=f'{w}{unit}', height=f'{h}{unit}',
- viewBox=f'{min_x} {min_y} {w} {h}',
- style=f'background-color:{pagecolor}',
- **namespaces,
- root=True)
-
-
-@click.command()
-@click.option('-h', '--height', type=float, default=20, help='Bar height in mm')
-@click.option('-t/-n', '--text/--no-text', default=True, help='Whether to add text containing the data under the bar code')
-@click.option('-f', '--font', default='sans-serif', help='Font for the text underneath the bar code')
-@click.option('-s', '--font-size', type=float, default=12, help='Font size for the text underneath the bar code in points (pt)')
-@click.option('-b', '--bar-width', type=float, default=1.0, help='Bar width in mm')
-@click.option('-m', '--margin', type=float, default=3.0, help='Margin around bar code in mm')
-@click.option('-c', '--color', default='black', help='SVG color for the bar code')
-@click.option('--text-color', default=None, help='SVG color for the text (defaults to the bar code\'s color)')
-@click.option('--dpi', type=float, default=96, help='DPI value to assume for internal SVG unit conversions')
-@click.argument('data')
-@click.argument('outfile', type=click.File('w'), default='-')
-def cli(data, outfile, height, text, font, font_size, bar_width, margin, color, text_color, dpi):
- data = int(data, 16)
- text_color = text_color or color
-
- NUM_BITS = 26
-
- data_bits = [bool(data & (1<
@@ -59,92 +55,14 @@ DIFF_STYLE_TOGGLE = r'''
'''
MAIN_CSS = r'''
-
-@media (prefers-color-scheme: light) {
- html {
- --c-bg-primary: #ffffff;
- --c-fg-primary: #000000;
- --c-bg-auxiliary: #f8f8f8;
- --c-fg-auxiliary: #a0a0a0;
- --c-border-line: #e0e0e0;
- --c-bg-insert: #ecfdf0;
- --c-bg-delete: #fbe9eb;
- --c-bg-delete-lineno: #f9d7dc;
- --c-fg-delete-lineno: #ae969a;
- --c-bg-delete-word: #fac5cd;
- --c-fg-delete-word: #400000;
- --c-fg-insert-word: #004000;
- --c-bg-insert-word: #c7f0d2;
- --c-fg-insert-lineno: #9bb0a1;
- --c-bg-insert-lineno: #ddfbe6;
- --c-bg-empty: #f0f0f0;
- --c-fg-foldline: #bbbbbb;
- --c-border-delete: #e0c8c8; /* pick a darker border color inside the light red gutter */
- }
-}
-
-@media (prefers-color-scheme: dark) {
- html {
- --c-bg-primary: #010409;
- --c-fg-primary: #a0a0a0;
- --c-bg-auxiliary: #0d1117;
- --c-fg-auxiliary: #f0f6fc;
- --c-fg-foldline: #bbbbbb;
- --c-border-line: #3d444d;
- --c-bg-insert: #223738;
- --c-bg-delete: #280d1f;
- --c-bg-delete-lineno: #421632;
- --c-fg-delete-lineno: #ae969a;
- --c-bg-delete-word: #421632;
- --c-fg-delete-word: #fac5cd;
- --c-fg-insert-word: #c7f0d2;
- --c-bg-insert-word: #325148;
- --c-fg-insert-lineno: #9bb0a1;
- --c-bg-insert-lineno: #325148;
- --c-bg-empty: #080b0f;
- --c-border-delete: #e0c8c8;
- }
-}
-
-@media print {
- html {
- /* Copy of the light theme, but we clip all light gray backgrounds to white. */
- --c-bg-primary: #ffffff;
- --c-fg-primary: #000000;
- --c-bg-auxiliary: #ffffff;
- --c-fg-auxiliary: #a0a0a0;
- --c-border-line: #e0e0e0;
- --c-bg-insert: #ecfdf0;
- --c-bg-delete: #fbe9eb;
- --c-bg-delete-lineno: #f9d7dc;
- --c-fg-delete-lineno: #ae969a;
- --c-bg-delete-word: #fac5cd;
- --c-fg-delete-word: #400000;
- --c-fg-insert-word: #004000;
- --c-bg-insert-word: #c7f0d2;
- --c-fg-insert-lineno: #9bb0a1;
- --c-bg-insert-lineno: #ddfbe6;
- --c-bg-empty: #ffffff;
- --c-fg-foldline: #bbbbbb;
- --c-border-delete: #e0c8c8;
- }
-}
-
@layer wsd-base-style {
- html {
- background-color: var(--c-bg-primary);
- height: 100%;
- width: 100%;
- }
-
#wsd-js-controls {
display: none;
- color: var(--c-fg-primary);
- background-color: var(--c-bg-auxiliary);
+ background-color: #f8f8f8;
padding: 5px 20px;
font-size: 10pt;
font-weight: bold;
- border: 1px solid var(--c-border-line);
+ border: 1px solid #e0e0e0;
position: sticky;
top: 0;
z-index: 1;
@@ -161,8 +79,8 @@ MAIN_CSS = r'''
}
.wsd-file-title {
- background-color: var(--c-bg-auxiliary);
- border-bottom: solid 1px var(--c-border-line);
+ background-color: #f8f8f8;
+ border-bottom: solid 1px #e0e0e0;
}
}
@@ -199,8 +117,8 @@ MAIN_CSS = r'''
.wsd-file-container {
font-family: monospace;
font-size: 9pt;
- background-color: var(--c-bg-auxiliary);
- border: solid 1px var(--c-border-line);
+ background-color: #f8f8f8;
+ border: solid 1px #e0e0e0;
margin: 15px;
}
@@ -222,16 +140,11 @@ MAIN_CSS = r'''
direction: rtl;
}
- .wsd-diff-files {
- color: var(--c-fg-primary);
- }
-
.wsd-diff {
- background-color: var(--c-bg-primary);
overflow-x: auto;
display: grid;
align-items: start;
- border-top: 1px solid var(--c-border-line);
+ border-top: 1px solid #e0e0e0;
}
.wsd-line {
@@ -252,31 +165,31 @@ MAIN_CSS = r'''
}
.wsd-line.wsd-left.wsd-change, .wsd-line.wsd-left.wsd-insert {
- background-color: var(--c-bg-delete);
+ background-color: #fbe9eb;
}
.wsd-line.wsd-right.wsd-change, .wsd-line.wsd-right.wsd-insert {
- background-color: var(--c-bg-insert);
+ background-color: #ecfdf0;
}
.wsd-lineno.wsd-left.wsd-change, .wsd-lineno.wsd-left.wsd-insert {
- background-color: var(--c-bg-delete-lineno);
- color: var(--c-fg-delete-lineno);
+ background-color: #f9d7dc;
+ color: #ae969a;
}
.wsd-lineno.wsd-right.wsd-change, .wsd-lineno.wsd-right.wsd-insert {
- background-color: var(--c-bg-insert-lineno);
- color: var(--c-fg-insert-lineno);
+ background-color: #ddfbe6;
+ color: #9bb0a1;
}
.wsd-right > .wsd-word-change {
- background-color: var(--c-bg-insert-word);
- color: var(--c-fg-insert-word);
+ background-color: #c7f0d2;
+ color: #004000;
}
.wsd-left > .wsd-word-change {
- background-color: var(--c-bg-delete-word);
- color: var(--c-fg-delete-word);
+ background-color: #fac5cd;
+ color: #400000;
}
.wsd-lineno {
@@ -287,18 +200,22 @@ MAIN_CSS = r'''
overflow: clip;
position: relative;
text-align: right;
- color: var(--c-fg-auxiliary);
- background-color: var(--c-bg-auxiliary);
- border-right: 1px solid var(--c-border-line);
+ color: #a0a0a0;
+ background-color: #f8f8f8;
+ border-right: 1px solid #e0e0e0;
align-self: stretch;
}
+ .wsd-lineno.wsd-change, .wsd-lineno.wsd-insert {
+ color: #000000;
+ }
+
.wsd-lineno::after {
position: absolute;
right: 0;
content: "\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳";
white-space: pre;
- color: var(--c-fg-auxiliary);
+ color: #a0a0a0;
}
/* Default rules for split diff for wide screens (laptops) */
@@ -307,7 +224,7 @@ MAIN_CSS = r'''
}
.wsd-empty {
- background-color: var(--c-bg-empty);
+ background-color: #f0f0f0;
align-self: stretch;
}
@@ -331,17 +248,16 @@ MAIN_CSS = r'''
grid-column: 1 / span 4;
display: flex;
justify-content: center;
- color: var(--c-fg-auxiliary);
+ color: #a0a0a0;
- background-image: radial-gradient(var(--c-fg-foldline) 1px, transparent 0);
+ background-image: radial-gradient(#BBBBBB 1px, transparent 0);
background-size: 10px 10px;
background-position: center;
background-repeat: repeat-x;
- background-color: var(--c-bg-auxiliary)
}
.wsd-collapse-controls > label {
- background-color: var(--c-bg-auxiliary);
+ background-color: #f8f8f8;
}
.wsd-collapse:has(input[type="checkbox"]:checked) > span {
@@ -384,7 +300,7 @@ MAIN_CSS = r'''
content: "";
align-self: stretch;
grid-column: 1;
- border-right: 1px solid var(--c-border-line);
+ border-right: 1px solid #e0e0e0;
margin-right: -6px; /* move border into column gap, and 1px over to align with other borders */
}
@@ -392,12 +308,12 @@ MAIN_CSS = r'''
content: "";
align-self: stretch;
grid-column: 2;
- border-left: 1px solid var(--c-border-delete);
+ border-left: 1px solid #e0c8c8; /* pick a darker border color inside the light red gutter */
margin-left: -5px;
}
.wsd-lineno.wsd-left.wsd-insert {
- border-right: 1px solid var(--c-border-delete);
+ border-right: 1px solid #e0c8c8;
}
.wsd-lineno.wsd-right.wsd-change::after {
@@ -443,7 +359,7 @@ MAIN_CSS = r'''
}
.wsd-lineno.wsd-left.wsd-empty {
- background-color: var(--c-bg-insert-lineno);
+ background-color: #ddfbe6;
}
/* line continuation arrows only in right line number column */
@@ -453,7 +369,7 @@ MAIN_CSS = r'''
.wsd-lineno.wsd-left.wsd-insert::before {
content: "";
grid-column: 2;
- border-left: 1px solid var(--c-border-delete); /* pick a darker border color inside the light red gutter */
+ border-left: 1px solid #e0c8c8; /* pick a darker border color inside the light red gutter */
margin-left: -5px;
}
}
@@ -515,7 +431,8 @@ DIFF_STYLE_SCRIPT = r'''
document.getElementById('wsd-js-controls').style = 'display: flex';
'''
-HTML_TEMPLATE = r'''
+HTML_TEMPLATE = r'''
+
@@ -548,6 +465,70 @@ HTML_TEMPLATE = r'''
'''
+PYGMENTS_CSS = '''
+body .wsd-hll { background-color: #ffffcc }
+body .wsd-c { color: #177500 } /* Comment */
+body .wsd-err { color: #000000 } /* Error */
+body .wsd-k { color: #A90D91 } /* Keyword */
+body .wsd-l { color: #1C01CE } /* Literal */
+body .wsd-n { color: #000000 } /* Name */
+body .wsd-o { color: #000000 } /* Operator */
+body .wsd-cm { color: #177500 } /* Comment.Multiline */
+body .wsd-cp { color: #633820 } /* Comment.Preproc */
+body .wsd-c1 { color: #177500 } /* Comment.Single */
+body .wsd-cs { color: #177500 } /* Comment.Special */
+body .wsd-kc { color: #A90D91 } /* Keyword.Constant */
+body .wsd-kd { color: #A90D91 } /* Keyword.Declaration */
+body .wsd-kn { color: #A90D91 } /* Keyword.Namespace */
+body .wsd-kp { color: #A90D91 } /* Keyword.Pseudo */
+body .wsd-kr { color: #A90D91 } /* Keyword.Reserved */
+body .wsd-kt { color: #A90D91 } /* Keyword.Type */
+body .wsd-ld { color: #1C01CE } /* Literal.Date */
+body .wsd-m { color: #1C01CE } /* Literal.Number */
+body .wsd-s { color: #C41A16 } /* Literal.String */
+body .wsd-na { color: #836C28 } /* Name.Attribute */
+body .wsd-nb { color: #A90D91 } /* Name.Builtin */
+body .wsd-nc { color: #3F6E75 } /* Name.Class */
+body .wsd-no { color: #000000 } /* Name.Constant */
+body .wsd-nd { color: #000000 } /* Name.Decorator */
+body .wsd-ni { color: #000000 } /* Name.Entity */
+body .wsd-ne { color: #000000 } /* Name.Exception */
+body .wsd-nf { color: #000000 } /* Name.Function */
+body .wsd-nl { color: #000000 } /* Name.Label */
+body .wsd-nn { color: #000000 } /* Name.Namespace */
+body .wsd-nx { color: #000000 } /* Name.Other */
+body .wsd-py { color: #000000 } /* Name.Property */
+body .wsd-nt { color: #000000 } /* Name.Tag */
+body .wsd-nv { color: #000000 } /* Name.Variable */
+body .wsd-ow { color: #000000 } /* Operator.Word */
+body .wsd-mb { color: #1C01CE } /* Literal.Number.Bin */
+body .wsd-mf { color: #1C01CE } /* Literal.Number.Float */
+body .wsd-mh { color: #1C01CE } /* Literal.Number.Hex */
+body .wsd-mi { color: #1C01CE } /* Literal.Number.Integer */
+body .wsd-mo { color: #1C01CE } /* Literal.Number.Oct */
+body .wsd-sb { color: #C41A16 } /* Literal.String.Backtick */
+body .wsd-sc { color: #2300CE } /* Literal.String.Char */
+body .wsd-sd { color: #C41A16 } /* Literal.String.Doc */
+body .wsd-s2 { color: #C41A16 } /* Literal.String.Double */
+body .wsd-se { color: #C41A16 } /* Literal.String.Escape */
+body .wsd-sh { color: #C41A16 } /* Literal.String.Heredoc */
+body .wsd-si { color: #C41A16 } /* Literal.String.Interpol */
+body .wsd-sx { color: #C41A16 } /* Literal.String.Other */
+body .wsd-sr { color: #C41A16 } /* Literal.String.Regex */
+body .wsd-s1 { color: #C41A16 } /* Literal.String.Single */
+body .wsd-ss { color: #C41A16 } /* Literal.String.Symbol */
+body .wsd-bp { color: #5B269A } /* Name.Builtin.Pseudo */
+body .wsd-vc { color: #000000 } /* Name.Variable.Class */
+body .wsd-vg { color: #000000 } /* Name.Variable.Global */
+body .wsd-vi { color: #000000 } /* Name.Variable.Instance */
+body .wsd-il { color: #1C01CE } /* Literal.Number.Integer.Long */
+'''
+
+from pygments.formatter import Formatter
+from pygments.token import STANDARD_TYPES
+
+from functools import lru_cache
+
@lru_cache(maxsize=256)
def get_token_class(ttype):
while not (name := STANDARD_TYPES.get(ttype)):
@@ -696,16 +677,7 @@ def cli():
if args.syntax_css:
syntax_css = Path(args.syntax_css).read_text()
else:
- light_css = HtmlFormatter(classprefix='wsd-', style='xcode').get_style_defs()
- dark_css = HtmlFormatter(classprefix='wsd-', style=witchhazel.WitchHazelStyle).get_style_defs()
-
- syntax_css = textwrap.dedent(f'''@media print, (prefers-color-scheme: light) {{
- {light_css}
- }}
-
- @media (prefers-color-scheme: dark) {{
- {dark_css}
- }}''')
+ syntax_css = PYGMENTS_CSS
if args.header:
print(string.Template(HTML_TEMPLATE).substitute(