ajout fichiers manquant

This commit is contained in:
Ambulance Clerc
2022-03-04 18:47:24 +01:00
parent 2e92cb8cf4
commit aa5b7f9254
170 changed files with 554027 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,301 @@
"""
weasyprint.css.counters
-----------------------
Implement counter styles.
These are defined in CSS Counter Styles Level 3:
https://www.w3.org/TR/css-counter-styles-3/#counter-style-system
"""
from copy import deepcopy
from .utils import remove_whitespace
def symbol(string_or_url):
"""Create a string from a symbol."""
# TODO: this function should handle images too, and return something else
# than strings.
type_, value = string_or_url
if type_ == 'string':
return value
return ''
def parse_counter_style_name(tokens, counter_style):
tokens = remove_whitespace(tokens)
if len(tokens) == 1:
token, = tokens
if token.type == 'ident':
if token.lower_value in ('decimal', 'disc'):
if token.lower_value not in counter_style:
return token.value
elif token.lower_value != 'none':
return token.value
class CounterStyle(dict):
"""Counter styles dictionary.
.. versionadded:: 0.52
Keep a list of counter styles defined by ``@counter-style`` rules, indexed
by their names.
See https://www.w3.org/TR/css-counter-styles-3/.
"""
def resolve_counter(self, counter_name, previous_types=None):
if counter_name[0] in ('symbols()', 'string'):
counter_type, arguments = counter_name
if counter_type == 'string':
system = (None, 'cyclic', None)
symbols = (('string', arguments),)
suffix = ('string', '')
elif counter_type == 'symbols()':
system = (
None, arguments[0], 1 if arguments[0] == 'fixed' else None)
symbols = tuple(
('string', argument) for argument in arguments[1:])
suffix = ('string', ' ')
return {
'system': system,
'negative': (('string', '-'), ('string', '')),
'prefix': ('string', ''),
'suffix': suffix,
'range': 'auto',
'pad': (0, ''),
'fallback': 'decimal',
'symbols': symbols,
'additive_symbols': (),
}
elif counter_name in self:
# Avoid circular fallbacks
if previous_types is None:
previous_types = []
elif counter_name in previous_types:
return
previous_types.append(counter_name)
counter = self[counter_name].copy()
if counter['system']:
extends, system, _ = counter['system']
else:
extends, system = None, 'symbolic'
# Handle extends
while extends:
if system in self:
extended_counter = self[system]
counter['system'] = extended_counter['system']
previous_types.append(system)
if counter['system']:
extends, system, _ = counter['system']
else:
extends, system = None, 'symbolic'
if extends and system in previous_types:
extends, system = 'extends', 'decimal'
continue
for name, value in extended_counter.items():
if counter[name] is None and value is not None:
counter[name] = value
else:
return counter
return counter
def render_value(self, counter_value, counter_name=None, counter=None,
previous_types=None):
"""Generate the counter representation.
See https://www.w3.org/TR/css-counter-styles-3/#generate-a-counter
"""
assert counter or counter_name
counter = counter or self.resolve_counter(counter_name, previous_types)
if counter is None:
if 'decimal' in self:
return self.render_value(counter_value, 'decimal')
else:
# Could happen if the UA stylesheet is not used
return ''
if counter['system']:
extends, system, fixed_number = counter['system']
else:
extends, system, fixed_number = None, 'symbolic', None
# Avoid circular fallbacks
if previous_types is None:
previous_types = []
elif system in previous_types:
return self.render_value(counter_value, 'decimal')
previous_types.append(counter_name)
# Handle extends
while extends:
if system in self:
extended_counter = self[system]
counter['system'] = extended_counter['system']
if counter['system']:
extends, system, fixed_number = counter['system']
else:
extends, system, fixed_number = None, 'symbolic', None
if system in previous_types:
return self.render_value(counter_value, 'decimal')
previous_types.append(system)
for name, value in extended_counter.items():
if counter[name] is None and value is not None:
counter[name] = value
else:
return self.render_value(counter_value, 'decimal')
# Step 2
if counter['range'] in ('auto', None):
min_range, max_range = -float('inf'), float('inf')
if system in ('alphabetic', 'symbolic'):
min_range = 1
elif system == 'additive':
min_range = 0
counter_ranges = ((min_range, max_range),)
else:
counter_ranges = counter['range']
for min_range, max_range in counter_ranges:
if min_range <= counter_value <= max_range:
break
else:
return self.render_value(
counter_value, counter['fallback'] or 'decimal',
previous_types=previous_types)
# Step 3
initial = None
is_negative = counter_value < 0
if is_negative:
negative_prefix, negative_suffix = (
symbol(character) for character
in counter['negative'] or (('string', '-'), ('string', '')))
use_negative = (
system in
('symbolic', 'alphabetic', 'numeric', 'additive'))
if use_negative:
counter_value = abs(counter_value)
# TODO: instead of using the decimal fallback when we have the wrong
# number of symbols, we should discard the whole counter. The problem
# only happens when extending from another style, it is easily refused
# during validation otherwise.
if system == 'cyclic':
length = len(counter['symbols'])
if length < 1:
return self.render_value(counter_value, 'decimal')
index = (counter_value - 1) % length
initial = symbol(counter['symbols'][index])
elif system == 'fixed':
length = len(counter['symbols'])
if length < 1:
return self.render_value(counter_value, 'decimal')
index = counter_value - fixed_number
if 0 <= index < length:
initial = symbol(counter['symbols'][index])
else:
return self.render_value(
counter_value, counter['fallback'] or 'decimal',
previous_types=previous_types)
elif system == 'symbolic':
length = len(counter['symbols'])
if length < 1:
return self.render_value(counter_value, 'decimal')
index = (counter_value - 1) % length
repeat = (counter_value - 1) // length + 1
initial = symbol(counter['symbols'][index]) * repeat
elif system == 'alphabetic':
length = len(counter['symbols'])
if length < 2:
return self.render_value(counter_value, 'decimal')
reversed_parts = []
while counter_value != 0:
counter_value -= 1
reversed_parts.append(symbol(
counter['symbols'][counter_value % length]))
counter_value //= length
initial = ''.join(reversed(reversed_parts))
elif system == 'numeric':
if counter_value == 0:
initial = symbol(counter['symbols'][0])
else:
reversed_parts = []
length = len(counter['symbols'])
if length < 2:
return self.render_value(counter_value, 'decimal')
counter_value = abs(counter_value)
while counter_value != 0:
reversed_parts.append(symbol(
counter['symbols'][counter_value % length]))
counter_value //= length
initial = ''.join(reversed(reversed_parts))
elif system == 'additive':
if counter_value == 0:
for weight, symbol_string in counter['additive_symbols']:
if weight == 0:
initial = symbol(symbol_string)
else:
parts = []
if len(counter['additive_symbols']) < 1:
return self.render_value(counter_value, 'decimal')
for weight, symbol_string in counter['additive_symbols']:
repetitions = counter_value // weight
parts.extend([symbol(symbol_string)] * repetitions)
counter_value -= weight * repetitions
if counter_value == 0:
initial = ''.join(parts)
break
if initial is None:
return self.render_value(
counter_value, counter['fallback'] or 'decimal',
previous_types=previous_types)
assert initial is not None
# Step 4
pad = counter['pad'] or (0, '')
pad_difference = pad[0] - len(initial)
if is_negative and use_negative:
pad_difference -= len(negative_prefix) + len(negative_suffix)
if pad_difference > 0:
initial = pad_difference * symbol(pad[1]) + initial
# Step 5
if is_negative and use_negative:
initial = negative_prefix + initial + negative_suffix
# Step 6
return initial
def render_marker(self, counter_name, counter_value):
"""Generate the content of a ::marker pseudo-element."""
counter = self.resolve_counter(counter_name)
if counter is None:
if 'decimal' in self:
return self.render_marker('decimal', counter_value)
else:
# Could happen if the UA stylesheet is not used
return ''
prefix = symbol(counter['prefix'] or ('string', ''))
suffix = symbol(counter['suffix'] or ('string', '. '))
value = self.render_value(counter_value, counter_name=counter_name)
assert value is not None
return prefix + value + suffix
def copy(self):
return CounterStyle(deepcopy(self))

View File

@@ -0,0 +1,192 @@
/*
Presentational hints stylsheet for HTML.
This stylesheet contains all the presentational hints rules that can be
expressed as CSS.
See https://www.w3.org/TR/html5/rendering.html#rendering
TODO: Attribute values are not case-insensitive, but they should be. We can add
a "i" flag when CSS Selectors Level 4 is supported.
*/
pre[wrap] { white-space: pre-wrap; }
br[clear=left] { clear: left; }
br[clear=right] { clear: right; }
br[clear=all], br[clear=both] { clear: both; }
ol[type="1"], li[type="1"] { list-style-type: decimal; }
ol[type=a], li[type=a] { list-style-type: lower-alpha; }
ol[type=A], li[type=A] { list-style-type: upper-alpha; }
ol[type=i], li[type=i] { list-style-type: lower-roman; }
ol[type=I], li[type=I] { list-style-type: upper-roman; }
ul[type=disc], li[type=disc] { list-style-type: disc; }
ul[type=circle], li[type=circle] { list-style-type: circle; }
ul[type=square], li[type=square] { list-style-type: square; }
table[align=left] { float: left; }
table[align=right] { float: right; }
table[align=center] { margin-left: auto; margin-right: auto; }
thead[align=absmiddle], tbody[align=absmiddle], tfoot[align=absmiddle],
tr[align=absmiddle], td[align=absmiddle], th[align=absmiddle] {
text-align: center;
}
caption[align=bottom] { caption-side: bottom; }
p[align=left], h1[align=left], h2[align=left], h3[align=left],
h4[align=left], h5[align=left], h6[align=left] {
text-align: left;
}
p[align=right], h1[align=right], h2[align=right], h3[align=right],
h4[align=right], h5[align=right], h6[align=right] {
text-align: right;
}
p[align=center], h1[align=center], h2[align=center], h3[align=center],
h4[align=center], h5[align=center], h6[align=center] {
text-align: center;
}
p[align=justify], h1[align=justify], h2[align=justify], h3[align=justify],
h4[align=justify], h5[align=justify], h6[align=justify] {
text-align: justify;
}
thead[valign=top], tbody[valign=top], tfoot[valign=top],
tr[valign=top], td[valign=top], th[valign=top] {
vertical-align: top;
}
thead[valign=middle], tbody[valign=middle], tfoot[valign=middle],
tr[valign=middle], td[valign=middle], th[valign=middle] {
vertical-align: middle;
}
thead[valign=bottom], tbody[valign=bottom], tfoot[valign=bottom],
tr[valign=bottom], td[valign=bottom], th[valign=bottom] {
vertical-align: bottom;
}
thead[valign=baseline], tbody[valign=baseline], tfoot[valign=baseline],
tr[valign=baseline], td[valign=baseline], th[valign=baseline] {
vertical-align: baseline;
}
td[nowrap], th[nowrap] { white-space: nowrap; }
table[rules=none], table[rules=groups], table[rules=rows],
table[rules=cols], table[rules=all] {
border-style: hidden;
border-collapse: collapse;
}
table[border]:not([border="0"]) { border-style: outset; }
table[frame=void] { border-style: hidden; }
table[frame=above] { border-style: outset hidden hidden hidden; }
table[frame=below] { border-style: hidden hidden outset hidden; }
table[frame=hsides] { border-style: outset hidden outset hidden; }
table[frame=lhs] { border-style: hidden hidden hidden outset; }
table[frame=rhs] { border-style: hidden outset hidden hidden; }
table[frame=vsides] { border-style: hidden outset; }
table[frame=box], table[frame=border] { border-style: outset; }
table[border]:not([border="0"]) > tr > td, table[border]:not([border="0"]) > tr > th,
table[border]:not([border="0"]) > thead > tr > td, table[border]:not([border="0"]) > thead > tr > th,
table[border]:not([border="0"]) > tbody > tr > td, table[border]:not([border="0"]) > tbody > tr > th,
table[border]:not([border="0"]) > tfoot > tr > td, table[border]:not([border="0"]) > tfoot > tr > th {
border-width: 1px;
border-style: inset;
}
table[rules=none] > tr > td, table[rules=none] > tr > th,
table[rules=none] > thead > tr > td, table[rules=none] > thead > tr > th,
table[rules=none] > tbody > tr > td, table[rules=none] > tbody > tr > th,
table[rules=none] > tfoot > tr > td, table[rules=none] > tfoot > tr > th,
table[rules=groups] > tr > td, table[rules=groups] > tr > th,
table[rules=groups] > thead > tr > td, table[rules=groups] > thead > tr > th,
table[rules=groups] > tbody > tr > td, table[rules=groups] > tbody > tr > th,
table[rules=groups] > tfoot > tr > td, table[rules=groups] > tfoot > tr > th,
table[rules=rows] > tr > td, table[rules=rows] > tr > th,
table[rules=rows] > thead > tr > td, table[rules=rows] > thead > tr > th,
table[rules=rows] > tbody > tr > td, table[rules=rows] > tbody > tr > th,
table[rules=rows] > tfoot > tr > td, table[rules=rows] > tfoot > tr > th {
border-width: 1px;
border-style: none;
}
table[rules=cols] > tr > td, table[rules=cols] > tr > th,
table[rules=cols] > thead > tr > td, table[rules=cols] > thead > tr > th,
table[rules=cols] > tbody > tr > td, table[rules=cols] > tbody > tr > th,
table[rules=cols] > tfoot > tr > td, table[rules=cols] > tfoot > tr > th {
border-width: 1px;
border-style: none solid;
}
table[rules=all] > tr > td, table[rules=all] > tr > th,
table[rules=all] > thead > tr > td, table[rules=all] > thead > tr > th,
table[rules=all] > tbody > tr > td, table[rules=all] > tbody > tr > th,
table[rules=all] > tfoot > tr > td, table[rules=all] > tfoot > tr > th {
border-width: 1px;
border-style: solid;
}
table[rules=groups] > colgroup {
border-left-width: 1px;
border-left-style: solid;
border-right-width: 1px;
border-right-style: solid;
}
table[rules=groups] > thead,
table[rules=groups] > tbody,
table[rules=groups] > tfoot {
border-top-width: 1px;
border-top-style: solid;
border-bottom-width: 1px;
border-bottom-style: solid;
}
table[rules=rows] > tr, table[rules=rows] > thead > tr,
table[rules=rows] > tbody > tr, table[rules=rows] > tfoot > tr {
border-top-width: 1px;
border-top-style: solid;
border-bottom-width: 1px;
border-bottom-style: solid;
}
hr[align=left] { margin-left: 0; margin-right: auto; }
hr[align=right] { margin-left: auto; margin-right: 0; }
hr[align=center] { margin-left: auto; margin-right: auto; }
hr[color], hr[noshade] { border-style: solid; }
iframe[frameborder="0"], iframe[frameborder=no] { border: none; }
applet[align=left], embed[align=left], iframe[align=left],
img[align=left], input[type=image][align=left], object[align=left] {
float: left;
}
applet[align=right], embed[align=right], iframe[align=right],
img[align=right], input[type=image][align=right], object[align=right] {
float: right;
}
applet[align=top], embed[align=top], iframe[align=top],
img[align=top], input[type=image][align=top], object[align=top] {
vertical-align: top;
}
applet[align=baseline], embed[align=baseline], iframe[align=baseline],
img[align=baseline], input[type=image][align=baseline], object[align=baseline] {
vertical-align: baseline;
}
applet[align=texttop], embed[align=texttop], iframe[align=texttop],
img[align=texttop], input[type=image][align=texttop], object[align=texttop] {
vertical-align: text-top;
}
applet[align=absmiddle], embed[align=absmiddle], iframe[align=absmiddle],
img[align=absmiddle], input[type=image][align=absmiddle], object[align=absmiddle],
applet[align=abscenter], embed[align=abscenter], iframe[align=abscenter],
img[align=abscenter], input[type=image][align=abscenter], object[align=abscenter] {
vertical-align: middle;
}
applet[align=bottom], embed[align=bottom], iframe[align=bottom],
img[align=bottom], input[type=image][align=bottom],
object[align=bottom] {
vertical-align: bottom;
}

View File

@@ -0,0 +1,826 @@
/*
User agent stylsheet for HTML.
Contributed by Peter Moulder.
Based on suggested styles in the HTML5 specification, CSS 2.1, and
what various web browsers use.
*/
/* http://www.w3.org/TR/html5/Overview#scroll-to-the-fragment-identifier */
*[id] { -weasy-anchor: attr(id); }
a[name] { -weasy-anchor: attr(name); }
*[dir] { /* unicode-bidi: embed; */ }
*[hidden] { display: none; }
*[dir=ltr] { direction: ltr; }
*[dir=rtl] { direction: rtl; }
/* :dir(ltr) { direction: ltr; } */
/* :dir(rtl) { direction: rtl; } */
:root { quotes: '\201c' '\201d' '\2018' '\2019'; }
*[lang] { -weasy-lang: attr(lang); }
[lang|=af] { quotes: '\201c' '\201d' '\2018' '\201d'; }
[lang|=agq] { quotes: '\0027' '\0027' '\201e' '\201d'; }
[lang|=ak] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=am] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=ar] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=asa] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=az] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=bas] { quotes: '\00ab' '\00bb' '\201c' '\201e'; }
[lang|=be] { quotes: '\201e' '\201d' '\00ab' '\00bb'; }
[lang|=bem] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=bez] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=bg] { quotes: '\201e' '\201c' '\2018' '\2019'; }
[lang|=bm] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=bn] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=brx] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=bs] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=ca] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=cgg] { quotes: '\0027' '\0027' '\201c' '\201e'; }
[lang|=chr] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=cs] { quotes: '\201e' '\201c' '\201a' '\2018'; }
[lang|=cy] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=da] { quotes: '\201d' '\201d' '\201d' '\201d'; }
[lang|=dav] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=de] { quotes: '\201e' '\201c' '\201a' '\2018'; }
[lang|=de-CH] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=dje] { quotes: '\201c' '\201d' '\00ab' '\00bb'; }
[lang|=dua] { quotes: '\00ab' '\00bb' '\0027' '\0027'; }
[lang|=dyo] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=dz] { quotes: '\0022' '\0022' '\0027' '\0027'; }
[lang|=ebu] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=ee] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=el] { quotes: '\00ab' '\00bb' '\2018' '\2019'; }
[lang|=el-POLYTON] { quotes: '\00ab' '\00bb' '\201b' '\2019'; }
[lang|=en] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=en-GB] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=es] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=et] { quotes: '\201e' '\201c' '\201e' '\201c'; }
[lang|=eu] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=ewo] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=fa] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=ff] { quotes: '\201e' '\201d' '\0027' '\0027'; }
[lang|=fi] { quotes: '\201d' '\201d' '\2019' '\2019'; }
[lang|=fil] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=fo] { quotes: '\201d' '\201d' '\2019' '\2019'; }
[lang|=fr] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=fr-CH] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=fur] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=gaa] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=gd] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=gl] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=gsw] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=gu] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=guz] { quotes: '\0027' '\2018' '\201c' '\201c'; }
[lang|=ha] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=he] { quotes: '\201c' '\201d' '\0022' '\0022'; }
[lang|=hi] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=hr] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=hu] { quotes: '\201e' '\201d' '\201e' '\201d'; }
[lang|=ia] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=id] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=ig] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=is] { quotes: '\201e' '\201c' '\201a' '\2018'; }
[lang|=it] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=it-CH] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=ja] { quotes: '\300c' '\300d' '\300e' '\300f'; }
[lang|=jmc] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=ka] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=kab] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=kam] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=kde] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=kea] { quotes: '\201c' '\201d' '\00ab' '\00bb'; }
[lang|=khq] { quotes: '\201c' '\201d' '\00ab' '\00bb'; }
[lang|=ki] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=kl] { quotes: '\00bb' '\00ab' '\203a' '\2039'; }
[lang|=kln] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=km] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=kn] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=ko] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=ksb] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=ksf] { quotes: '\0027' '\0027' '\00ab' '\00bb'; }
[lang|=ksh] { quotes: '\201e' '\201c' '\201a' '\2018'; }
[lang|=lag] { quotes: '\201d' '\201d' '\0027' '\0027'; }
[lang|=lg] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=ln] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=lo] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=lt] { quotes: '\201e' '\201c' '\201e' '\201c'; }
[lang|=lu] { quotes: '\2018' '\2018' '\201c' '\201c'; }
[lang|=luo] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=luy] { quotes: '\0027' '\0027' '\201e' '\201c'; }
[lang|=lv] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=mas] { quotes: '\0027' '\0027' '\201d' '\201c'; }
[lang|=mer] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=mfe] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=mg] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=ml] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=mn] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=mr] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=ms] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=mt] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=mua] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=my] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=naq] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=nb] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=nd] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=nds] { quotes: '\201e' '\201c' '\201a' '\2018'; }
[lang|=ne] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=nl] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=nmg] { quotes: '\201c' '\201e' '\00ab' '\00bb'; }
[lang|=nn] { quotes: '\00ab' '\00bb' '\201c' '\201d'; }
[lang|=nr] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=nso] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=nus] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=nyn] { quotes: '\0027' '\0027' '\201c' '\201e'; }
[lang|=pa] { quotes: '\0027' '\0027' '\0022' '\0022'; }
[lang|=pl] { quotes: '\2018' '\2019' '\201e' '\201d'; }
[lang|=pt] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=rm] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=rn] { quotes: '\0027' '\0027' '\201d' '\201d'; }
[lang|=ro] { quotes: '\201e' '\201d' '\00ab' '\00bb'; }
[lang|=rof] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=ru] { quotes: '\00ab' '\00bb' '\201e' '\201c'; }
[lang|=rw] { quotes: '\2018' '\2019' '\00ab' '\00bb'; }
[lang|=rwk] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=saq] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=sbp] { quotes: '\0027' '\0027' '\201c' '\201d'; }
[lang|=se] { quotes: '\201d' '\201d' '\2019' '\2019'; }
[lang|=seh] { quotes: '\0027' '\0027' '\0027' '\0027'; }
[lang|=ses] { quotes: '\201c' '\201d' '\00ab' '\00bb'; }
[lang|=sg] { quotes: '\00ab' '\00bb' '\201c' '\2019'; }
[lang|=shi] { quotes: '\00ab' '\00bb' '\201e' '\201d'; }
[lang|=shi-Tfng] { quotes: '\00ab' '\00bb' '\201e' '\201d'; }
[lang|=sk] { quotes: '\201a' '\2018' '\201e' '\201c'; }
[lang|=sl] { quotes: '\00bb' '\00ab' '\201e' '\201c'; }
[lang|=sn] { quotes: '\0027' '\0027' '\201d' '\201d'; }
[lang|=so] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=sr] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=ss] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=st] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=sv] { quotes: '\201d' '\201d' '\2019' '\2019'; }
[lang|=sw] { quotes: '\0027' '\0027' '\0027' '\0027'; }
[lang|=swc] { quotes: '\0027' '\0027' '\201d' '\201c'; }
[lang|=ta] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=te] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=teo] { quotes: '\0027' '\2019' '\201c' '\201d'; }
[lang|=tg] { quotes: '\00ab' '\00bb' '\00ab' '\201e'; }
[lang|=th] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=ti-ER] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=tn] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=to] { quotes: '\201c' '\201d' '\00ab' '\00bb'; }
[lang|=tr] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=trv] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=ts] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=twq] { quotes: '\201c' '\201d' '\00ab' '\00bb'; }
[lang|=tzm] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=uk] { quotes: '\00ab' '\00bb' '\201e' '\201c'; }
[lang|=ur] { quotes: '\0022' '\0022' '\0027' '\0027'; }
[lang|=vai] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=vai-Latn] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=ve] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=vi] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=vun] { quotes: '\0027' '\0027' '\201c' '\201c'; }
[lang|=wae] { quotes: '\00ab' '\00bb' '\2039' '\203a'; }
[lang|=xh] { quotes: '\2018' '\2019' '\201c' '\201d'; }
[lang|=xog] { quotes: '\0027' '\0027' '\201c' '\201e'; }
[lang|=yav] { quotes: '\00ab' '\00bb' '\00ab' '\00bb'; }
[lang|=yo] { quotes: '\0027' '\0027' '\0027' '\0027'; }
[lang|=zh] { quotes: '\201c' '\201d' '\2018' '\2019'; }
[lang|=zh-Hant] { quotes: '\300c' '\300d' '\300e' '\300f'; }
[lang|=zu] { quotes: '\2018' '\2019' '\201c' '\201d'; }
:link { color: #0000EE; text-decoration: underline; }
a[href] { -weasy-link: attr(href); }
:visited { color: #551A8B; text-decoration: underline; }
a:link[rel~=help] { cursor: help; }
a:visited[rel~=help] { cursor: help; }
abbr[title] { text-decoration: dotted underline; }
acronym[title] { text-decoration: dotted underline; }
address { display: block; font-style: italic; /* unicode-bidi: isolate; */ }
area { display: none; }
area:link[rel~=help] { cursor: help; }
area:visited[rel~=help] { cursor: help; }
article { display: block; /* unicode-bidi: isolate; */ }
aside { display: block; /* unicode-bidi: isolate; */ }
b { font-weight: bold; }
base { display: none; }
basefont { display: none; }
bdi { /* unicode-bidi: isolate; */ }
bdi[dir] { /* unicode-bidi: isolate; */ }
bdo { /* unicode-bidi: bidi-override; */ }
bdo[dir] { /* unicode-bidi: bidi-override; */ }
big { font-size: larger; }
blink { text-decoration: blink; }
blockquote { display: block; margin: 1em 40px; /* unicode-bidi: isolate; */ }
body { display: block; margin: 8px; }
br::before { content: '\A'; white-space: pre-line; }
button { display: inline-block; text-align: center; text-indent: 0; }
caption { display: table-caption; /* unicode-bidi: isolate; */ }
center { display: block; text-align: center; /* unicode-bidi: isolate; */ }
cite { font-style: italic; }
code { font-family: monospace; }
col { display: table-column; /* unicode-bidi: isolate; */ }
col[hidden] { display: table-column; /* unicode-bidi: isolate; */ visibility: collapse; }
colgroup { display: table-column-group; /* unicode-bidi: isolate; */ }
colgroup[hidden] { display: table-column-group; /* unicode-bidi: isolate; */ visibility: collapse; }
command { display: none; }
datalist { display: none; }
dd { display: block; margin-left: 40px; /* unicode-bidi: isolate; */ }
*[dir=ltr] dd { margin-left: 0; margin-right: 40px; }
*[dir=rtl] dd { margin-left: 40px; margin-right: 0; }
*[dir] *[dir=ltr] dd { margin-left: 0; margin-right: 40px; }
*[dir] *[dir=rtl] dd { margin-left: 40px; margin-right: 0; }
*[dir] *[dir] *[dir=ltr] dd { margin-left: 0; margin-right: 40px; }
*[dir] *[dir] *[dir=rtl] dd { margin-left: 40px; margin-right: 0; }
dd[dir=ltr][dir][dir] { margin-left: 0; margin-right: 40px; }
dd[dir=rtl][dir][dir] { margin-left: 40px; margin-right: 0; }
details { display: block; /* unicode-bidi: isolate; */ }
del { text-decoration: line-through; }
dfn { font-style: italic; }
dir { display: block; list-style-type: disc; margin-bottom: 1em; margin-top: 1em; padding-left: 40px; /* unicode-bidi: isolate; */ }
*[dir=rtl] dir { padding-left: 0; padding-right: 40px; }
*[dir=ltr] dir { padding-left: 40px; padding-right: 0; }
*[dir] *[dir=rtl] dir { padding-left: 0; padding-right: 40px; }
*[dir] *[dir=ltr] dir { padding-left: 40px; padding-right: 0; }
*[dir] *[dir] *[dir=rtl] dir { padding-left: 0; padding-right: 40px; }
*[dir] *[dir] *[dir=ltr] dir { padding-left: 40px; padding-right: 0; }
dir[dir=rtl][dir][dir] { padding-left: 0; padding-right: 40px; }
dir[dir=ltr][dir][dir] { padding-left: 40px; padding-right: 0; }
dir dir { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dl dir { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
menu dir { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ol dir { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ul dir { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
div { display: block; /* unicode-bidi: isolate; */ }
dl { display: block; margin-bottom: 1em; margin-top: 1em; /* unicode-bidi: isolate; */ }
dir dl { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dl dl { margin-bottom: 0; margin-top: 0; }
ol dl { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ul dl { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dir dir dl { list-style-type: square; }
dir menu dl { list-style-type: square; }
dir ol dl { list-style-type: square; }
dir ul dl { list-style-type: square; }
menu dir dl { list-style-type: square; }
menu dl { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
menu menu dl { list-style-type: square; }
menu ol dl { list-style-type: square; }
menu ul dl { list-style-type: square; }
ol dir dl { list-style-type: square; }
ol menu dl { list-style-type: square; }
ol ol dl { list-style-type: square; }
ol ul dl { list-style-type: square; }
ul dir dl { list-style-type: square; }
ul menu dl { list-style-type: square; }
ul ol dl { list-style-type: square; }
ul ul dl { list-style-type: square; }
ol, ul { counter-reset: list-item }
dt { display: block; /* unicode-bidi: isolate; */ }
em { font-style: italic; }
fieldset { display: block; border-style: groove; border-width: 2px; margin-left: 2px; margin-right: 2px; padding: .35em .625em .75em .625em; }
figcaption { display: block; /* unicode-bidi: isolate; */ }
figure { display: block; margin: 1em 40px; /* unicode-bidi: isolate; */ }
footer { display: block; /* unicode-bidi: isolate; */ }
form { display: block; /* unicode-bidi: isolate; */ }
frame { display: block; }
frameset { display: block; }
h1 { display: block; font-size: 2em; font-weight: bold; hyphens: manual; margin-bottom: .67em; margin-top: .67em; page-break-after: avoid; page-break-inside: avoid; /* unicode-bidi: isolate; */ bookmark-level: 1; bookmark-label: content(text); }
section h1 { font-size: 1.50em; margin-bottom: .83em; margin-top: .83em; }
section section h1 { font-size: 1.17em; margin-bottom: 1.00em; margin-top: 1.00em; }
section section section h1 { font-size: 1.00em; margin-bottom: 1.33em; margin-top: 1.33em; }
section section section section h1 { font-size: .83em; margin-bottom: 1.67em; margin-top: 1.67em; }
section section section section section h1 { font-size: .67em; margin-bottom: 2.33em; margin-top: 2.33em; }
h2 { display: block; font-size: 1.50em; font-weight: bold; hyphens: manual; margin-bottom: .83em; margin-top: .83em; page-break-after: avoid; page-break-inside: avoid; /* unicode-bidi: isolate; */ bookmark-level: 2; bookmark-label: content(text); }
h3 { display: block; font-size: 1.17em; font-weight: bold; hyphens: manual; margin-bottom: 1.00em; margin-top: 1.00em; page-break-after: avoid; page-break-inside: avoid; /* unicode-bidi: isolate; */ bookmark-level: 3; bookmark-label: content(text); }
h4 { display: block; font-size: 1.00em; font-weight: bold; hyphens: manual; margin-bottom: 1.33em; margin-top: 1.33em; page-break-after: avoid; page-break-inside: avoid; /* unicode-bidi: isolate; */ bookmark-level: 4; bookmark-label: content(text); }
h5 { display: block; font-size: .83em; font-weight: bold; hyphens: manual; margin-bottom: 1.67em; margin-top: 1.67em; page-break-after: avoid; /* unicode-bidi: isolate; */ bookmark-level: 5; bookmark-label: content(text); }
h6 { display: block; font-size: .67em; font-weight: bold; hyphens: manual; margin-bottom: 2.33em; margin-top: 2.33em; page-break-after: avoid; /* unicode-bidi: isolate; */ bookmark-level: 6; bookmark-label: content(text); }
head { display: none; }
header { display: block; /* unicode-bidi: isolate; */ }
hgroup { display: block; /* unicode-bidi: isolate; */ }
hr { border-style: inset; border-width: 1px; color: gray; display: block; margin-bottom: .5em; margin-left: auto; margin-right: auto; margin-top: .5em; /* unicode-bidi: isolate; */ }
html { display: block; }
i { font-style: italic; }
*[dir=auto] { /* unicode-bidi: isolate; */ }
bdo[dir=auto] { /* unicode-bidi: bidi-override isolate; */ }
input[type=hidden] { display: none; }
menu[type=context] { display: none; }
pre[dir=auto] { /* unicode-bidi: plaintext; */ }
table[frame=above] { border-color: black; }
table[frame=below] { border-color: black; }
table[frame=border] { border-color: black; }
table[frame=box] { border-color: black; }
table[frame=hsides] { border-color: black; }
table[frame=lhs] { border-color: black; }
table[frame=rhs] { border-color: black; }
table[frame=void] { border-color: black; }
table[frame=vsides] { border-color: black; }
table[rules=all] { border-color: black; }
table[rules=cols] { border-color: black; }
table[rules=groups] { border-color: black; }
table[rules=none] { border-color: black; }
table[rules=rows] { border-color: black; }
textarea[dir=auto] { /* unicode-bidi: plaintext; */ }
iframe { border: 2px inset; }
iframe[seamless] { border: none; }
input { display: inline-block; text-indent: 0; }
ins { text-decoration: underline; }
kbd { font-family: monospace; }
keygen { display: inline-block; text-indent: 0; }
legend { display: block; /* unicode-bidi: isolate; */ }
li { display: list-item; /* unicode-bidi: isolate; */ }
link { display: none; }
listing { display: block; font-family: monospace; margin-bottom: 1em; margin-top: 1em; /* unicode-bidi: isolate; */ white-space: pre; }
mark { background: yellow; color: black; }
main { display: block; /* unicode-bidi: isolate; */ }
menu { display: block; list-style-type: disc; margin-bottom: 1em; margin-top: 1em; padding-left: 40px; /* unicode-bidi: isolate; */ }
*[dir=rtl] menu { padding-left: 0; padding-right: 40px; }
*[dir=ltr] menu { padding-left: 40px; padding-right: 0; }
*[dir] *[dir=rtl] menu { padding-left: 0; padding-right: 40px; }
*[dir] *[dir=ltr] menu { padding-left: 40px; padding-right: 0; }
*[dir] *[dir] *[dir=rtl] menu { padding-left: 0; padding-right: 40px; }
*[dir] *[dir] *[dir=ltr] menu { padding-left: 40px; padding-right: 0; }
menu[dir=rtl][dir][dir] { padding-left: 0; padding-right: 40px; }
menu[dir=ltr][dir][dir] { padding-left: 40px; padding-right: 0; }
dir menu { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dl menu { margin-bottom: 0; margin-top: 0; }
menu menu { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dir dir menu { list-style-type: square; }
dir menu menu { list-style-type: square; }
dir ol menu { list-style-type: square; }
dir ul menu { list-style-type: square; }
menu dir menu { list-style-type: square; }
menu menu menu { list-style-type: square; }
menu ol menu { list-style-type: square; }
menu ul menu { list-style-type: square; }
ol menu { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ol dir menu { list-style-type: square; }
ol menu menu { list-style-type: square; }
ol ol menu { list-style-type: square; }
ol ul menu { list-style-type: square; }
ul dir menu { list-style-type: square; }
ul menu menu { list-style-type: square; }
ul menu { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ul ol menu { list-style-type: square; }
ul ul menu { list-style-type: square; }
meta { display: none; }
nav { display: block; /* unicode-bidi: isolate; */ }
nobr { white-space: nowrap; }
noembed { display: none; }
/* The HTML5 spec suggests display:none for the old (now forbidden) noframes element,
* but Morp doesn't currently handle frames, so we might as well render it.
*/
/*noframes { display: none; }*/
noframes { display: block; }
ol { page-break-before: avoid; }
ol { display: block; list-style-type: decimal; margin-bottom: 1em; margin-top: 1em; padding-left: 40px; /* unicode-bidi: isolate; */ }
*[dir=ltr] ol { padding-left: 0; padding-right: 40px; }
*[dir=rtl] ol { padding-left: 40px; padding-right: 0; }
*[dir] *[dir=ltr] ol { padding-left: 0; padding-right: 40px; }
*[dir] *[dir=rtl] ol { padding-left: 40px; padding-right: 0; }
*[dir] *[dir] *[dir=ltr] ol { padding-left: 0; padding-right: 40px; }
*[dir] *[dir] *[dir=rtl] ol { padding-left: 40px; padding-right: 0; }
ol[dir=ltr][dir][dir] { padding-left: 0; padding-right: 40px; }
ol[dir=rtl][dir][dir] { padding-left: 40px; padding-right: 0; }
dir ol { margin-bottom: 0; margin-top: 0; }
dl ol { margin-bottom: 0; margin-top: 0; }
menu ol { margin-bottom: 0; margin-top: 0; }
ol ol { margin-bottom: 0; margin-top: 0; }
ul ol { margin-bottom: 0; margin-top: 0; }
optgroup { text-indent: 0; }
option { text-indent: 0; display: none; } /* Don't display the tag, it's replaced content in dynamic browsers */
output { /* unicode-bidi: isolate; */ }
output[dir] { /* unicode-bidi: isolate; */ }
p { display: block; margin-bottom: 1em; margin-top: 1em; /* unicode-bidi: isolate; */ }
param { display: none; }
plaintext { display: block; font-family: monospace; margin-bottom: 1em; margin-top: 1em; /* unicode-bidi: isolate; */ white-space: pre; }
pre { display: block; font-family: monospace; margin-bottom: 1em; margin-top: 1em; /* unicode-bidi: isolate; */ white-space: pre; }
q::after { content: close-quote; }
q::before { content: open-quote; }
rp { display: none; }
/* rt { display: ruby-text; } */
/* ruby { display: ruby; } */
s { text-decoration: line-through; }
samp { font-family: monospace; }
script { display: none; }
section { display: block; /* unicode-bidi: isolate; */ }
select { text-indent: 0; }
small { font-size: smaller; }
source { display: none; }
strike { text-decoration: line-through; }
strong { font-weight: bolder; }
style { display: none; }
sub { font-size: smaller; line-height: normal; vertical-align: sub; }
summary { display: block; /* unicode-bidi: isolate; */ }
sup { font-size: smaller; line-height: normal; vertical-align: super; }
table { border-collapse: separate; border-color: gray; border-spacing: 2px; display: table; text-indent: 0; /* unicode-bidi: isolate; */ }
/* The html5 spec doesn't mention the following, though the CSS 2.1 spec does
* hint at its use, and a couple of UAs do have this. I haven't looked into
* why the HTML5 spec doesn't include this rule.
*/
table { box-sizing: border-box; }
tbody { border-color: inherit; display: table-row-group; /* unicode-bidi: isolate; */ vertical-align: middle; }
tbody[hidden] { display: table-row-group; /* unicode-bidi: isolate; */ visibility: collapse; }
td { border-color: gray; display: table-cell; padding: 1px; /* unicode-bidi: isolate; */ vertical-align: inherit; }
td[hidden] { display: table-cell; /* unicode-bidi: isolate; */ visibility: collapse; }
textarea { display: inline-block; text-indent: 0; white-space: pre-wrap; }
tfoot { border-color: inherit; display: table-footer-group; /* unicode-bidi: isolate; */ vertical-align: middle; }
tfoot[hidden] { display: table-footer-group; /* unicode-bidi: isolate; */ visibility: collapse; }
table[rules=none] > tr > td, table[rules=none] > tr > th, table[rules=groups] > tr > td, table[rules=groups] > tr > th, table[rules=rows] > tr > td, table[rules=rows] > tr > th, table[rules=cols] > tr > td, table[rules=cols] > tr > th, table[rules=all] > tr > td, table[rules=all] > tr > th, table[rules=none] > thead > tr > td, table[rules=none] > thead > tr > th, table[rules=groups] > thead > tr > td, table[rules=groups] > thead > tr > th, table[rules=rows] > thead > tr > td, table[rules=rows] > thead > tr > th, table[rules=cols] > thead > tr > td, table[rules=cols] > thead > tr > th, table[rules=all] > thead > tr > td, table[rules=all] > thead > tr > th, table[rules=none] > tbody > tr > td, table[rules=none] > tbody > tr > th, table[rules=groups] > tbody > tr > td, table[rules=groups] > tbody > tr > th, table[rules=rows] > tbody > tr > td, table[rules=rows] > tbody > tr > th, table[rules=cols] > tbody > tr > td, table[rules=cols] > tbody > tr > th, table[rules=all] > tbody > tr > td, table[rules=all] > tbody > tr > th, table[rules=none] > tfoot > tr > td, table[rules=none] > tfoot > tr > th, table[rules=groups] > tfoot > tr > td, table[rules=groups] > tfoot > tr > th, table[rules=rows] > tfoot > tr > td, table[rules=rows] > tfoot > tr > th, table[rules=cols] > tfoot > tr > td, table[rules=cols] > tfoot > tr > th, table[rules=all] > tfoot > tr > td, table[rules=all] > tfoot > tr > th { border-color: black; }
th { border-color: gray; display: table-cell; font-weight: bold; padding: 1px; /* unicode-bidi: isolate; */ vertical-align: inherit; }
th[hidden] { display: table-cell; /* unicode-bidi: isolate; */ visibility: collapse; }
thead { border-color: inherit; display: table-header-group; /* unicode-bidi: isolate; */ vertical-align: middle; }
thead[hidden] { display: table-header-group; /* unicode-bidi: isolate; */ visibility: collapse; }
table > tr { vertical-align: middle; }
tr { border-color: inherit; display: table-row; /* unicode-bidi: isolate; */ vertical-align: inherit; }
tr[hidden] { display: table-row; /* unicode-bidi: isolate; */ visibility: collapse; }
template { display: none; }
title { display: none; }
track { display: none; }
tt { font-family: monospace; }
u { text-decoration: underline; }
::marker { /* unicode-bidi: isolate; */ font-variant-numeric: tabular-nums; }
ul { display: block; list-style-type: disc; margin-bottom: 1em; margin-top: 1em; padding-left: 40px; /* unicode-bidi: isolate; */ }
*[dir=ltr] ul { padding-left: 40px; padding-right: 0; }
*[dir=rtl] ul { padding-left: 0; padding-right: 40px; }
*[dir] *[dir=ltr] ul { padding-left: 40px; padding-right: 0; }
*[dir] *[dir=rtl] ul { padding-left: 0; padding-right: 40px; }
*[dir] *[dir] *[dir=ltr] ul { padding-left: 40px; padding-right: 0; }
*[dir] *[dir] *[dir=rtl] ul { padding-left: 0; padding-right: 40px; }
ul[dir=ltr][dir][dir] { padding-left: 40px; padding-right: 0; }
ul[dir=rtl][dir][dir] { padding-left: 0; padding-right: 40px; }
/* This isn't in the HTML5 spec's suggested styling, and should probably be a
* mere hint rather than a demand. It usually is the right thing, though.
*/
ul { display: block; page-break-before: avoid; }
dir ul { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dl ul { margin-bottom: 0; margin-top: 0; }
menu ul { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ol ul { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
ul ul { list-style-type: circle; margin-bottom: 0; margin-top: 0; }
dir dir ul { list-style-type: square; }
dir menu ul { list-style-type: square; }
dir ol ul { list-style-type: square; }
dir ul ul { list-style-type: square; }
menu dir ul { list-style-type: square; }
menu menu ul { list-style-type: square; }
menu ol ul { list-style-type: square; }
menu ul ul { list-style-type: square; }
ol dir ul { list-style-type: square; }
ol menu ul { list-style-type: square; }
ol ol ul { list-style-type: square; }
ol ul ul { list-style-type: square; }
ul dir ul { list-style-type: square; }
ul menu ul { list-style-type: square; }
ul ol ul { list-style-type: square; }
ul ul ul { list-style-type: square; }
var { font-style: italic; }
video { object-fit: contain; }
xmp { display: block; font-family: monospace; margin-bottom: 1em; margin-top: 1em; /* unicode-bidi: isolate; */ white-space: pre; }
::footnote-call { content: counter(footnote); vertical-align: baseline; font-size: 100%; line-height: inherit; font-variant-position: super; }
::footnote-marker { content: counter(footnote) '. '; }
@page {
/* `size: auto` (the initial) is A4 portrait */
margin: 75px;
@footnote { margin-top: 1em }
@top-left-corner { text-align: right; vertical-align: middle }
@top-left { text-align: left; vertical-align: middle }
@top-center { text-align: center; vertical-align: middle }
@top-right { text-align: right; vertical-align: middle }
@top-right-corner { text-align: left; vertical-align: middle }
@left-top { text-align: center; vertical-align: top }
@left-middle { text-align: center; vertical-align: middle }
@left-bottom { text-align: center; vertical-align: bottom }
@right-top { text-align: center; vertical-align: top }
@right-middle { text-align: center; vertical-align: middle }
@right-bottom { text-align: center; vertical-align: bottom }
@bottom-left-corner { text-align: right; vertical-align: middle }
@bottom-left { text-align: left; vertical-align: middle }
@bottom-center { text-align: center; vertical-align: middle }
@bottom-right { text-align: right; vertical-align: middle }
@bottom-right-corner { text-align: left; vertical-align: middle }
}
/* Counters: https://www.w3.org/TR/css-counter-styles-3/#predefined-counters */
@counter-style disc {
system: cyclic;
symbols: ;
suffix: " ";
}
@counter-style circle {
system: cyclic;
symbols: ;
suffix: " ";
}
@counter-style square {
system: cyclic;
symbols: ;
suffix: " ";
}
@counter-style disclosure-open {
system: cyclic;
symbols: ;
suffix: " ";
}
@counter-style disclosure-closed {
system: cyclic;
/* TODO: handle rtl */
symbols: ;
suffix: " ";
}
@counter-style decimal {
system: numeric;
symbols: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9';
}
@counter-style decimal-leading-zero {
system: extends decimal;
pad: 2 '0';
}
@counter-style arabic-indic {
system: numeric;
symbols: ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩;
}
@counter-style armenian {
system: additive;
range: 1 9999;
additive-symbols: 9000 Ք, 8000 Փ, 7000 Ւ, 6000 Ց, 5000 Ր, 4000 Տ, 3000 Վ, 2000 Ս, 1000 Ռ, 900 Ջ, 800 Պ, 700 Չ, 600 Ո, 500 Շ, 400 Ն, 300 Յ, 200 Մ, 100 Ճ, 90 Ղ, 80 Ձ, 70 Հ, 60 Կ, 50 Ծ, 40 Խ, 30 Լ, 20 Ի, 10 Ժ, 9 Թ, 8 Ը, 7 Է, 6 Զ, 5 Ե, 4 Դ, 3 Գ, 2 Բ, 1 Ա;
}
@counter-style upper-armenian {
system: extends armenian;
}
@counter-style lower-armenian {
system: additive;
range: 1 9999;
additive-symbols: 9000 ք, 8000 փ, 7000 ւ, 6000 ց, 5000 ր, 4000 տ, 3000 վ, 2000 ս, 1000 ռ, 900 ջ, 800 պ, 700 չ, 600 ո, 500 շ, 400 ն, 300 յ, 200 մ, 100 ճ, 90 ղ, 80 ձ, 70 հ, 60 կ, 50 ծ, 40 խ, 30 լ, 20 ի, 10 ժ, 9 թ, 8 ը, 7 է, 6 զ, 5 ե, 4 դ, 3 գ, 2 բ, 1 ա;
}
@counter-style bengali {
system: numeric;
symbols: ;
}
@counter-style cambodian {
system: numeric;
symbols: ;
}
@counter-style khmer {
system: extends cambodian;
}
@counter-style cjk-decimal {
system: numeric;
range: 0 infinite;
symbols: ;
suffix: "、";
}
@counter-style devanagari {
system: numeric;
symbols: ;
}
@counter-style georgian {
system: additive;
range: 1 19999;
additive-symbols: 10000 , 9000 , 8000 , 7000 , 6000 , 5000 , 4000 , 3000 , 2000 , 1000 , 900 , 800 , 700 , 600 , 500 , 400 , 300 , 200 , 100 , 90 , 80 , 70 , 60 , 50 , 40 , 30 , 20 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ;
}
@counter-style gujarati {
system: numeric;
symbols: ;
}
@counter-style gurmukhi {
system: numeric;
symbols: ;
}
@counter-style hebrew {
system: additive;
range: 1 10999;
additive-symbols: 10000 י׳, 9000 ט׳, 8000 ח׳, 7000 ז׳, 6000 ו׳, 5000 ה׳, 4000 ד׳, 3000 ג׳, 2000 ב׳, 1000 א׳, 400 ת, 300 ש, 200 ר, 100 ק, 90 צ, 80 פ, 70 ע, 60 ס, 50 נ, 40 מ, 30 ל, 20 כ, 19 יט, 18 יח, 17 יז, 16 טז, 15 טו, 10 י, 9 ט, 8 ח, 7 ז, 6 ו, 5 ה, 4 ד, 3 ג, 2 ב, 1 א;
}
@counter-style kannada {
system: numeric;
symbols: ;
}
@counter-style lao {
system: numeric;
symbols: ;
}
@counter-style malayalam {
system: numeric;
symbols: ;
}
@counter-style mongolian {
system: numeric;
symbols: ;
}
@counter-style myanmar {
system: numeric;
symbols: ;
}
@counter-style oriya {
system: numeric;
symbols: ;
}
@counter-style persian {
system: numeric;
symbols: ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹;
}
@counter-style lower-roman {
system: additive;
range: 1 3999;
additive-symbols: 1000 m, 900 cm, 500 d, 400 cd, 100 c, 90 xc, 50 l, 40 xl, 10 x, 9 ix, 5 v, 4 iv, 1 i;
}
@counter-style upper-roman {
system: additive;
range: 1 3999;
additive-symbols: 1000 M, 900 CM, 500 D, 400 CD, 100 C, 90 XC, 50 L, 40 XL, 10 X, 9 IX, 5 V, 4 IV, 1 I;
}
@counter-style tamil {
system: numeric;
symbols: ;
}
@counter-style telugu {
system: numeric;
symbols: ;
}
@counter-style thai {
system: numeric;
symbols: ;
}
@counter-style tibetan {
system: numeric;
symbols: ;
}
@counter-style lower-alpha {
system: alphabetic;
symbols: a b c d e f g h i j k l m n o p q r s t u v w x y z;
}
@counter-style lower-latin {
system: extends lower-alpha;
}
@counter-style upper-alpha {
system: alphabetic;
symbols: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z;
}
@counter-style upper-latin {
system: extends upper-alpha;
}
@counter-style cjk-earthly-branch {
system: alphabetic;
symbols: ;
suffix: "、";
}
@counter-style cjk-heavenly-stem {
system: alphabetic;
symbols: ;
suffix: "、";
}
@counter-style lower-greek {
system: alphabetic;
symbols: α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω;
}
@counter-style hiragana {
system: alphabetic;
symbols: ;
suffix: "、";
}
@counter-style hiragana-iroha {
system: alphabetic;
symbols: ;
suffix: "、";
}
@counter-style katakana {
system: alphabetic;
symbols: ;
suffix: "、";
}
@counter-style katakana-iroha {
system: alphabetic;
symbols: ;
suffix: "、";
}
@counter-style japanese-informal {
system: additive;
range: -9999 9999;
additive-symbols: 9000 九千, 8000 八千, 7000 七千, 6000 六千, 5000 五千, 4000 四千, 3000 三千, 2000 二千, 1000 , 900 九百, 800 八百, 700 七百, 600 六百, 500 五百, 400 四百, 300 三百, 200 二百, 100 , 90 九十, 80 八十, 70 七十, 60 六十, 50 五十, 40 四十, 30 三十, 20 二十, 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ;
suffix: ;
negative: マイナス;
fallback: cjk-decimal;
}
@counter-style japanese-formal {
system: additive;
range: -9999 9999;
additive-symbols: 9000 九阡, 8000 八阡, 7000 七阡, 6000 六阡, 5000 伍阡, 4000 四阡, 3000 参阡, 2000 弐阡, 1000 壱阡, 900 九百, 800 八百, 700 七百, 600 六百, 500 伍百, 400 四百, 300 参百, 200 弐百, 100 壱百, 90 九拾, 80 八拾, 70 七拾, 60 六拾, 50 伍拾, 40 四拾, 30 参拾, 20 弐拾, 10 壱拾, 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ;
suffix: ;
negative: マイナス;
fallback: cjk-decimal;
}
@counter-style korean-hangul-formal {
system: additive;
range: -9999 9999;
additive-symbols: 9000 구천, 8000 팔천, 7000 칠천, 6000 육천, 5000 오천, 4000 사천, 3000 삼천, 2000 이천, 1000 일천, 900 구백, 800 팔백, 700 칠백, 600 육백, 500 오백, 400 사백, 300 삼백, 200 이백, 100 일백, 90 구십, 80 팔십, 70 칠십, 60 육십, 50 오십, 40 사십, 30 삼십, 20 이십, 10 일십, 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ;
suffix: ', ';
negative: "마이너스 ";
}
@counter-style korean-hanja-informal {
system: additive;
range: -9999 9999;
additive-symbols: 9000 九千, 8000 八千, 7000 七千, 6000 六千, 5000 五千, 4000 四千, 3000 三千, 2000 二千, 1000 , 900 九百, 800 八百, 700 七百, 600 六百, 500 五百, 400 四百, 300 三百, 200 二百, 100 , 90 九十, 80 八十, 70 七十, 60 六十, 50 五十, 40 四十, 30 三十, 20 二十, 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ;
suffix: ', ';
negative: "마이너스 ";
}
@counter-style korean-hanja-formal {
system: additive;
range: -9999 9999;
additive-symbols: 9000 九仟, 8000 八仟, 7000 七仟, 6000 六仟, 5000 五仟, 4000 四仟, 3000 參仟, 2000 貳仟, 1000 壹仟, 900 九百, 800 八百, 700 七百, 600 六百, 500 五百, 400 四百, 300 參百, 200 貳百, 100 壹百, 90 九拾, 80 八拾, 70 七拾, 60 六拾, 50 五拾, 40 四拾, 30 參拾, 20 貳拾, 10 壹拾, 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ;
suffix: ', ';
negative: "마이너스 ";
}

View File

@@ -0,0 +1,229 @@
"""
weasyprint.formatting_structure.targets
---------------------------------------
Handle target-counter, target-counters and target-text.
The TargetCollector is a structure providing required targets'
counter_values and stuff needed to build pending targets later,
when the layout of all targeted anchors has been done.
"""
import copy
from ..logger import LOGGER
class TargetLookupItem:
"""Item controlling pending targets and page based target counters.
Collected in the TargetCollector's ``target_lookup_items``.
"""
def __init__(self, state='pending'):
self.state = state
# Required by target-counter and target-counters to access the
# target's .cached_counter_values.
# Needed for target-text via TEXT_CONTENT_EXTRACTORS.
self.target_box = None
# Functions that have to been called to check pending targets.
# Keys are (source_box, css_token).
self.parse_again_functions = {}
# Anchor position during pagination (page_number - 1)
self.page_maker_index = None
# target_box's page_counters during pagination
self.cached_page_counter_values = {}
class CounterLookupItem:
"""Item controlling page based counters.
Collected in the TargetCollector's ``counter_lookup_items``.
"""
def __init__(self, parse_again, missing_counters, missing_target_counters):
# Function that have to been called to check pending counter.
self.parse_again = parse_again
# Missing counters and target counters
self.missing_counters = missing_counters
self.missing_target_counters = missing_target_counters
# Box position during pagination (page_number - 1)
self.page_maker_index = None
# Marker for remake_page
self.pending = False
# Targeting box's page_counters during pagination
self.cached_page_counter_values = {}
class TargetCollector:
"""Collector of HTML targets used by CSS content with ``target-*``."""
def __init__(self):
# Lookup items for targets and page counters
self.target_lookup_items = {}
self.counter_lookup_items = {}
# When collecting is True, compute_content_list() collects missing
# page counters in CounterLookupItems. Otherwise, it mixes in the
# TargetLookupItem's cached_page_counter_values.
# Is switched to False in check_pending_targets().
self.collecting = True
# had_pending_targets is set to True when a target is needed but has
# not been seen yet. check_pending_targets then uses this information
# to call the needed parse_again functions.
self.had_pending_targets = False
def anchor_name_from_token(self, anchor_token):
"""Get anchor name from string or uri token."""
if anchor_token[0] == 'string' and anchor_token[1].startswith('#'):
return anchor_token[1][1:]
elif anchor_token[0] == 'url' and anchor_token[1][0] == 'internal':
return anchor_token[1][1]
def collect_anchor(self, anchor_name):
"""Create a TargetLookupItem for the given `anchor_name``."""
if anchor_name and isinstance(anchor_name, str):
if self.target_lookup_items.get(anchor_name) is not None:
LOGGER.warning('Anchor defined twice: %r', anchor_name)
else:
self.target_lookup_items.setdefault(
anchor_name, TargetLookupItem())
def lookup_target(self, anchor_token, source_box, css_token, parse_again):
"""Get a TargetLookupItem corresponding to ``anchor_token``.
If it is already filled by a previous anchor-element, the status is
'up-to-date'. Otherwise, it is 'pending', we must parse the whole
tree again.
"""
anchor_name = self.anchor_name_from_token(anchor_token)
item = self.target_lookup_items.get(
anchor_name, TargetLookupItem('undefined'))
if item.state == 'pending':
self.had_pending_targets = True
item.parse_again_functions.setdefault(
(source_box, css_token), parse_again)
if item.state == 'undefined':
LOGGER.error(
'Content discarded: target points to undefined anchor %r',
anchor_token)
return item
def store_target(self, anchor_name, target_counter_values, target_box):
"""Store a target called ``anchor_name``.
If there is a pending TargetLookupItem, it is updated. Only previously
collected anchors are stored.
"""
item = self.target_lookup_items.get(anchor_name)
if item and item.state == 'pending':
item.state = 'up-to-date'
item.target_box = target_box
# Store the counter_values in the target_box like
# compute_content_list does.
# TODO: remove attribute or set a default value in Box class
if not hasattr(target_box, 'cached_counter_values'):
target_box.cached_counter_values = copy.deepcopy(
target_counter_values)
def collect_missing_counters(self, parent_box, css_token,
parse_again_function, missing_counters,
missing_target_counters):
"""Collect missing (probably page-based) counters during formatting.
The ``missing_counters`` are re-used during pagination.
The ``missing_link`` attribute added to the parent_box is required to
connect the paginated boxes to their originating ``parent_box``.
"""
# No counter collection during pagination
if not self.collecting:
return
# No need to add empty miss-lists
if missing_counters or missing_target_counters:
# TODO: remove attribute or set a default value in Box class
if not hasattr(parent_box, 'missing_link'):
parent_box.missing_link = parent_box
counter_lookup_item = CounterLookupItem(
parse_again_function, missing_counters,
missing_target_counters)
self.counter_lookup_items.setdefault(
(parent_box, css_token), counter_lookup_item)
def check_pending_targets(self):
"""Check pending targets if needed."""
if self.had_pending_targets:
for item in self.target_lookup_items.values():
for function in item.parse_again_functions.values():
function()
self.had_pending_targets = False
# Ready for pagination
self.collecting = False
def cache_target_page_counters(self, anchor_name, page_counter_values,
page_maker_index, page_maker):
"""Store target's current ``page_maker_index`` and page counter values.
Eventually update associated targeting boxes.
"""
# Only store page counters when paginating
if self.collecting:
return
item = self.target_lookup_items.get(anchor_name)
if item and item.state == 'up-to-date':
item.page_maker_index = page_maker_index
if item.cached_page_counter_values != page_counter_values:
item.cached_page_counter_values = copy.deepcopy(
page_counter_values)
# Spread the news: update boxes affected by a change in the
# anchor's page counter values.
for (_, css_token), item in self.counter_lookup_items.items():
# Only update items that need counters in their content
if css_token != 'content':
continue
# Don't update if item has no missing target counter
missing_counters = item.missing_target_counters.get(
anchor_name)
if missing_counters is None:
continue
# Pending marker for remake_page
if (item.page_maker_index is None or
item.page_maker_index >= len(page_maker)):
item.pending = True
continue
# TODO: Is the item at all interested in the new
# page_counter_values? It probably is and this check is a
# brake.
for counter_name in missing_counters:
counter_value = page_counter_values.get(counter_name)
if counter_value is not None:
remake_state = (
page_maker[item.page_maker_index][-1])
remake_state['content_changed'] = True
item.parse_again(item.cached_page_counter_values)
break
# Hint: the box's own cached page counters trigger a
# separate 'content_changed'.

View File

@@ -0,0 +1,39 @@
/*
Simplified user-agent stylesheet for HTML5 in tests.
*/
@page { bleed: 0; @footnote { margin: 0 } }
html, body, div, h1, h2, h3, h4, ol, p, ul, hr, pre, section, article
{ display: block; }
li { display: list-item }
head { display: none }
pre { white-space: pre }
br:before { content: '\A'; white-space: pre-line }
ol { list-style-type: decimal }
ol, ul { counter-reset: list-item }
table, x-table { display: table;
box-sizing: border-box }
tr, x-tr { display: table-row }
thead, x-thead { display: table-header-group }
tbody, x-tbody { display: table-row-group }
tfoot, x-tfoot { display: table-footer-group }
col, x-col { display: table-column }
colgroup, x-colgroup { display: table-column-group }
td, th, x-td, x-th { display: table-cell }
caption, x-caption { display: table-caption }
*[lang] { -weasy-lang: attr(lang); }
a[href] { -weasy-link: attr(href); }
a[name] { -weasy-anchor: attr(name); }
*[id] { -weasy-anchor: attr(id); }
h1 { bookmark-level: 1; bookmark-label: content(text); }
h2 { bookmark-level: 2; bookmark-label: content(text); }
h3 { bookmark-level: 3; bookmark-label: content(text); }
h4 { bookmark-level: 4; bookmark-label: content(text); }
h5 { bookmark-level: 5; bookmark-label: content(text); }
h6 { bookmark-level: 6; bookmark-label: content(text); }
::marker { unicode-bidi: isolate; font-variant-numeric: tabular-nums; }
::footnote-call { content: counter(footnote); }
::footnote-marker { content: counter(footnote) '.'; }