660 lines
17 KiB
Python
660 lines
17 KiB
Python
|
# Copyright 2004-2022 Tom Rothamel <pytom@bishoujo.us>
|
||
|
#
|
||
|
# Permission is hereby granted, free of charge, to any person
|
||
|
# obtaining a copy of this software and associated documentation files
|
||
|
# (the "Software"), to deal in the Software without restriction,
|
||
|
# including without limitation the rights to use, copy, modify, merge,
|
||
|
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||
|
# and to permit persons to whom the Software is furnished to do so,
|
||
|
# subject to the following conditions:
|
||
|
#
|
||
|
# The above copyright notice and this permission notice shall be
|
||
|
# included in all copies or substantial portions of the Software.
|
||
|
#
|
||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
from __future__ import print_function, unicode_literals, division, absolute_import
|
||
|
|
||
|
from future import standard_library
|
||
|
standard_library.install_aliases()
|
||
|
|
||
|
from builtins import str
|
||
|
|
||
|
import collections
|
||
|
import os
|
||
|
|
||
|
from io import StringIO # @UnusedImport
|
||
|
|
||
|
# Paths
|
||
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
||
|
ROOT = os.path.dirname(BASE)
|
||
|
|
||
|
import setuplib
|
||
|
module_gen = "module/" + setuplib.gen
|
||
|
|
||
|
|
||
|
def sorted_dict(**kwargs):
|
||
|
"""
|
||
|
Constructs an ordered_dict from the keyword arguments in sorted order.
|
||
|
"""
|
||
|
|
||
|
items = list(kwargs.items())
|
||
|
return collections.OrderedDict(items)
|
||
|
|
||
|
################################################################################
|
||
|
# Prefixes
|
||
|
################################################################################
|
||
|
|
||
|
|
||
|
# A map from prefix name to Prefix object.
|
||
|
prefixes = collections.OrderedDict()
|
||
|
|
||
|
|
||
|
class Prefix(object):
|
||
|
|
||
|
def __init__(self, index, name, priority, alts):
|
||
|
|
||
|
# The index of where this prefix is stored in memory, or -1 if this
|
||
|
# prefix isn't stored in memory.
|
||
|
self.index = index
|
||
|
|
||
|
# The name of this prefix.
|
||
|
self.name = name
|
||
|
|
||
|
# The priority of this prefix. When added at the same time, higher
|
||
|
# priority prefixes take precendence over lower priority prefixes.
|
||
|
#
|
||
|
# We double the priority here so we have room for the special priority
|
||
|
# stuff below.
|
||
|
self.priority = priority * 2
|
||
|
|
||
|
# A list of prefix indexes that should be updated when this prefix is
|
||
|
# updated, including this prefix.
|
||
|
if index >= 0:
|
||
|
self.alts = [ self.index ]
|
||
|
self.alt_names = [ self.name ]
|
||
|
else:
|
||
|
self.alts = [ ]
|
||
|
self.alt_names = [ ]
|
||
|
|
||
|
for i in alts:
|
||
|
self.alts.append(prefixes[i].index)
|
||
|
self.alt_names.append(i)
|
||
|
|
||
|
prefixes[name] = self
|
||
|
|
||
|
|
||
|
# The number of priority levels we have. Double the number given below, due to the doubling above.
|
||
|
PRIORITY_LEVELS = 8
|
||
|
|
||
|
# The number of prefixes we have.
|
||
|
PREFIX_COUNT = 6
|
||
|
|
||
|
Prefix(5, 'selected_hover_', 3, [ ])
|
||
|
Prefix(4, 'selected_idle_', 3, [ ])
|
||
|
Prefix(3, 'selected_insensitive_', 3, [ ])
|
||
|
Prefix(-3, 'selected_', 2, [ "selected_hover_", "selected_idle_", "selected_insensitive_" ])
|
||
|
Prefix(2, 'hover_', 1, [ "selected_hover_" ])
|
||
|
Prefix(1, 'idle_', 1, [ "selected_idle_" ])
|
||
|
Prefix(0, 'insensitive_', 1, [ "selected_insensitive_" ])
|
||
|
Prefix(-4, '', 0, [ "selected_hover_", "selected_idle_", "selected_insensitive_", "idle_", "hover_", "insensitive_" ])
|
||
|
|
||
|
Prefix(-2, 'activate_', 0, [ ])
|
||
|
Prefix(-1, 'selected_activate_', 0, [ ])
|
||
|
|
||
|
# The images that are searched by a prefix.
|
||
|
PREFIX_SEARCH = {
|
||
|
"idle_" : [ "idle_", "" ],
|
||
|
"hover_" : [ "hover_", "" ],
|
||
|
"insensitive_" : [ "insensitive_", "", "idle_" ],
|
||
|
"selected_idle_" : [ "selected_idle_", "selected_", "", "idle_" ],
|
||
|
"selected_hover_" : [ "selected_hover_", "hover_", "selected_", "" ],
|
||
|
"selected_insensitive_" : [ "selected_insensitive_", "insensitive_", "selected_", "", "selected_idle_", "idle_" ],
|
||
|
"" : [ "" ],
|
||
|
}
|
||
|
|
||
|
################################################################################
|
||
|
# Style Properties
|
||
|
################################################################################
|
||
|
|
||
|
# All the style properties we know about. This is a dict, that maps each style
|
||
|
# to a function that is called when it is set, or None if no such function
|
||
|
# is needed.
|
||
|
style_properties = sorted_dict(
|
||
|
activate_sound=None,
|
||
|
adjust_spacing=None,
|
||
|
aft_bar='none_is_null',
|
||
|
aft_gutter=None,
|
||
|
alt=None,
|
||
|
altruby_style=None,
|
||
|
antialias=None,
|
||
|
vertical=None,
|
||
|
background='renpy.easy.displayable_or_none',
|
||
|
bar_invert=None,
|
||
|
bar_resizing=None,
|
||
|
unscrollable=None,
|
||
|
bar_vertical=None,
|
||
|
black_color='renpy.easy.color',
|
||
|
bold=None,
|
||
|
bottom_margin=None,
|
||
|
bottom_padding=None,
|
||
|
box_layout=None,
|
||
|
box_reverse=None,
|
||
|
box_wrap=None,
|
||
|
box_wrap_spacing=None,
|
||
|
caret='renpy.easy.displayable_or_none',
|
||
|
child='renpy.easy.displayable_or_none',
|
||
|
clipping=None,
|
||
|
color='renpy.easy.color',
|
||
|
debug=None,
|
||
|
drop_shadow=None,
|
||
|
drop_shadow_color='renpy.easy.color',
|
||
|
first_indent=None,
|
||
|
first_spacing=None,
|
||
|
fit_first=None,
|
||
|
focus_mask='expand_focus_mask',
|
||
|
focus_rect=None,
|
||
|
font=None,
|
||
|
fore_bar='none_is_null',
|
||
|
fore_gutter=None,
|
||
|
foreground='renpy.easy.displayable_or_none',
|
||
|
hinting=None,
|
||
|
hover_sound=None,
|
||
|
hyperlink_functions=None,
|
||
|
italic=None,
|
||
|
justify=None,
|
||
|
kerning=None,
|
||
|
key_events=None,
|
||
|
keyboard_focus=None,
|
||
|
language=None,
|
||
|
layout=None,
|
||
|
line_leading=None,
|
||
|
left_margin=None,
|
||
|
line_overlap_split=None,
|
||
|
left_padding=None,
|
||
|
line_spacing=None,
|
||
|
mouse=None,
|
||
|
modal=None,
|
||
|
min_width=None,
|
||
|
mipmap=None,
|
||
|
newline_indent=None,
|
||
|
order_reverse=None,
|
||
|
outlines='expand_outlines',
|
||
|
outline_scaling=None,
|
||
|
rest_indent=None,
|
||
|
right_margin=None,
|
||
|
right_padding=None,
|
||
|
ruby_style=None,
|
||
|
size=None,
|
||
|
size_group=None,
|
||
|
slow_abortable=None,
|
||
|
slow_cps=None,
|
||
|
slow_cps_multiplier=None,
|
||
|
spacing=None,
|
||
|
strikethrough=None,
|
||
|
subtitle_width=None,
|
||
|
subpixel=None,
|
||
|
text_y_fudge=None,
|
||
|
text_align=None,
|
||
|
thumb='none_is_null',
|
||
|
thumb_offset=None,
|
||
|
thumb_shadow='none_is_null',
|
||
|
time_policy=None,
|
||
|
top_margin=None,
|
||
|
top_padding=None,
|
||
|
underline=None,
|
||
|
xanchor='expand_anchor',
|
||
|
xfill=None,
|
||
|
xfit=None,
|
||
|
xmaximum=None,
|
||
|
xminimum='none_is_0',
|
||
|
xoffset=None,
|
||
|
xpos=None,
|
||
|
xspacing=None,
|
||
|
yanchor='expand_anchor',
|
||
|
yfill=None,
|
||
|
yfit=None,
|
||
|
ymaximum=None,
|
||
|
yminimum='none_is_0',
|
||
|
yoffset=None,
|
||
|
ypos=None,
|
||
|
yspacing=None,
|
||
|
)
|
||
|
|
||
|
# Properties that take displayables that should be given the right set
|
||
|
# of prefixes.
|
||
|
displayable_properties = {
|
||
|
"background",
|
||
|
"foreground",
|
||
|
"child",
|
||
|
"fore_bar",
|
||
|
"aft_bar",
|
||
|
"thumb",
|
||
|
"thumb_shadow",
|
||
|
}
|
||
|
|
||
|
# A map from a style property to its index in the order of style_properties.
|
||
|
style_property_index = collections.OrderedDict()
|
||
|
for i, name in enumerate(style_properties):
|
||
|
style_property_index[name] = i
|
||
|
|
||
|
style_property_count = len(style_properties)
|
||
|
|
||
|
# print("{} properties * {} prefixes = {} cache entries".format(
|
||
|
# style_property_count, PREFIX_COUNT, style_property_count * PREFIX_COUNT))
|
||
|
|
||
|
# Special priority properties - these take a +1 compared to others. Generally,
|
||
|
# these would be listed in the tuples in synthetic_properies, below.
|
||
|
property_priority = sorted_dict(
|
||
|
left_margin=1,
|
||
|
top_margin=1,
|
||
|
right_margin=1,
|
||
|
bottom_margin=1,
|
||
|
xpos=1,
|
||
|
xanchor=1,
|
||
|
ypos=1,
|
||
|
yanchor=1,
|
||
|
left_padding=1,
|
||
|
top_padding=1,
|
||
|
right_padding=1,
|
||
|
bottom_padding=1,
|
||
|
xoffset=1,
|
||
|
yoffset=1,
|
||
|
xminimum=1,
|
||
|
yminimum=1,
|
||
|
xmaximum=1,
|
||
|
ymaximum=1,
|
||
|
xfill=1,
|
||
|
yfill=1,
|
||
|
)
|
||
|
|
||
|
# A list of synthetic style properties, where each property is expanded into
|
||
|
# multiple style properties. Each property are mapped into a list of tuples,
|
||
|
# with each consisting of:
|
||
|
#
|
||
|
# * The name of the style to assign.
|
||
|
# * A string giving the name of a functon to call to get the value to assign, a constant
|
||
|
# numeric value, or None to not change the argument.
|
||
|
synthetic_properties = sorted_dict(
|
||
|
|
||
|
margin=[
|
||
|
('left_margin', 'index_0'),
|
||
|
('top_margin', 'index_1'),
|
||
|
('right_margin', 'index_2_or_0'),
|
||
|
('bottom_margin', 'index_3_or_1'),
|
||
|
],
|
||
|
|
||
|
xmargin=[
|
||
|
('left_margin', None),
|
||
|
('right_margin', None)
|
||
|
],
|
||
|
|
||
|
ymargin=[
|
||
|
('top_margin', None),
|
||
|
('bottom_margin', None),
|
||
|
],
|
||
|
|
||
|
xalign=[
|
||
|
('xpos', None),
|
||
|
('xanchor', None),
|
||
|
],
|
||
|
|
||
|
yalign=[
|
||
|
('ypos', None),
|
||
|
('yanchor', None),
|
||
|
],
|
||
|
|
||
|
padding=[
|
||
|
('left_padding', 'index_0'),
|
||
|
('top_padding', 'index_1'),
|
||
|
('right_padding', 'index_2_or_0'),
|
||
|
('bottom_padding', 'index_3_or_1'),
|
||
|
],
|
||
|
|
||
|
xpadding=[
|
||
|
('left_padding', None),
|
||
|
('right_padding', None),
|
||
|
],
|
||
|
|
||
|
ypadding=[
|
||
|
('top_padding', None),
|
||
|
('bottom_padding', None),
|
||
|
],
|
||
|
|
||
|
minwidth=[ ('min_width', None) ],
|
||
|
textalign=[ ('text_align', None) ],
|
||
|
slow_speed=[ ('slow_cps', None) ],
|
||
|
enable_hover=[ ],
|
||
|
|
||
|
left_gutter=[ ('fore_gutter', None) ],
|
||
|
right_gutter=[ ('aft_gutter', None) ],
|
||
|
top_gutter=[ ('fore_gutter', None) ],
|
||
|
bottom_gutter=[ ('aft_gutter', None) ],
|
||
|
|
||
|
left_bar=[ ('fore_bar', None) ],
|
||
|
right_bar=[ ('aft_bar', None) ],
|
||
|
top_bar=[ ('fore_bar', None) ],
|
||
|
bottom_bar=[ ('aft_bar', None) ],
|
||
|
|
||
|
base_bar=[
|
||
|
('fore_bar', None),
|
||
|
('aft_bar', None),
|
||
|
],
|
||
|
|
||
|
box_spacing=[ ('spacing', None) ],
|
||
|
box_first_spacing=[ ('first_spacing', None) ],
|
||
|
|
||
|
pos=[
|
||
|
('xpos', 'index_0'),
|
||
|
('ypos', 'index_1'),
|
||
|
],
|
||
|
|
||
|
anchor=[
|
||
|
('xanchor', 'index_0'),
|
||
|
('yanchor', 'index_1'),
|
||
|
],
|
||
|
|
||
|
offset=[
|
||
|
('xoffset', 'index_0'),
|
||
|
('yoffset', 'index_1'),
|
||
|
],
|
||
|
|
||
|
align=[
|
||
|
('xpos', 'index_0'),
|
||
|
('ypos', 'index_1'),
|
||
|
('xanchor', 'index_0'),
|
||
|
('yanchor', 'index_1'),
|
||
|
],
|
||
|
|
||
|
maximum=[
|
||
|
('xmaximum', 'index_0'),
|
||
|
('ymaximum', 'index_1'),
|
||
|
],
|
||
|
|
||
|
minimum=[
|
||
|
('xminimum', 'index_0'),
|
||
|
('yminimum', 'index_1'),
|
||
|
],
|
||
|
|
||
|
xsize=[
|
||
|
('xminimum', None),
|
||
|
('xmaximum', None),
|
||
|
],
|
||
|
|
||
|
ysize=[
|
||
|
('yminimum', None),
|
||
|
('ymaximum', None),
|
||
|
],
|
||
|
|
||
|
xysize=[
|
||
|
('xminimum', 'index_0'),
|
||
|
('xmaximum', 'index_0'),
|
||
|
('yminimum', 'index_1'),
|
||
|
('ymaximum', 'index_1'),
|
||
|
],
|
||
|
|
||
|
area=[
|
||
|
('xpos', 'index_0'),
|
||
|
('ypos', 'index_1'),
|
||
|
('xanchor', 0),
|
||
|
('yanchor', 0),
|
||
|
('xfill', True),
|
||
|
('yfill', True),
|
||
|
('xmaximum', 'index_2'),
|
||
|
('ymaximum', 'index_3'),
|
||
|
('xminimum', 'index_2'),
|
||
|
('yminimum', 'index_3'),
|
||
|
],
|
||
|
|
||
|
xcenter=[
|
||
|
('xpos', None),
|
||
|
('xanchor', 0.5),
|
||
|
],
|
||
|
|
||
|
ycenter=[
|
||
|
('ypos', None),
|
||
|
('yanchor', 0.5),
|
||
|
],
|
||
|
)
|
||
|
|
||
|
all_properties = collections.OrderedDict()
|
||
|
|
||
|
for k, v in style_properties.items():
|
||
|
all_properties[k] = [ (k, None) ]
|
||
|
|
||
|
all_properties.update(synthetic_properties)
|
||
|
|
||
|
################################################################################
|
||
|
# Code Generation
|
||
|
################################################################################
|
||
|
|
||
|
|
||
|
class CodeGen(object):
|
||
|
"""
|
||
|
Utility class for code generation.
|
||
|
|
||
|
`filename`
|
||
|
The name of the file we code-generate into.
|
||
|
`spew`
|
||
|
If true, spew the generated code to stdout.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, filename, spew=False):
|
||
|
self.filename = os.path.join(ROOT, filename)
|
||
|
self.f = StringIO()
|
||
|
self.depth = 0
|
||
|
self.spew = spew
|
||
|
|
||
|
def close(self):
|
||
|
|
||
|
text = self.f.getvalue()
|
||
|
|
||
|
if os.path.exists(self.filename):
|
||
|
with open(self.filename, "r") as f:
|
||
|
old = f.read()
|
||
|
|
||
|
if old == text:
|
||
|
return
|
||
|
|
||
|
with open(self.filename, "w") as f:
|
||
|
f.write(text)
|
||
|
|
||
|
def write(self, s, *args, **kwargs):
|
||
|
out = " " * self.depth
|
||
|
out += s.format(*args, **kwargs)
|
||
|
out = out.rstrip()
|
||
|
|
||
|
if self.spew:
|
||
|
print(out)
|
||
|
|
||
|
out += "\n"
|
||
|
self.f.write(out)
|
||
|
|
||
|
def indent(self):
|
||
|
self.depth += 1
|
||
|
|
||
|
def dedent(self):
|
||
|
self.depth -= 1
|
||
|
|
||
|
|
||
|
def generate_constants():
|
||
|
"""
|
||
|
This generates code that defines the property functions.
|
||
|
"""
|
||
|
|
||
|
g = CodeGen(module_gen + "/styleconstants.pxi")
|
||
|
|
||
|
g.write("DEF PRIORITY_LEVELS = {}", PRIORITY_LEVELS)
|
||
|
g.write("DEF PREFIX_COUNT = {}", PREFIX_COUNT)
|
||
|
g.write("DEF STYLE_PROPERTY_COUNT = {}", style_property_count)
|
||
|
|
||
|
for p in prefixes.values():
|
||
|
if p.index < 0:
|
||
|
continue
|
||
|
|
||
|
g.write("DEF {}PREFIX = {}", p.name.upper(), p.index * style_property_count)
|
||
|
|
||
|
for k in style_properties:
|
||
|
g.write("DEF {}_INDEX = {}", k.upper(), style_property_index[k])
|
||
|
|
||
|
g.close()
|
||
|
|
||
|
|
||
|
def generate_property_function(g, prefix, propname, properties):
|
||
|
|
||
|
name = prefix.name + propname
|
||
|
|
||
|
g.write("cdef int {name}_property(PyObject **cache, int *cache_priorities, int priority, object value) except -1:", name=name)
|
||
|
g.indent()
|
||
|
|
||
|
g.write("priority += {}", prefix.priority + property_priority.get(propname, 0))
|
||
|
|
||
|
for stylepropname, func in properties:
|
||
|
value = "value"
|
||
|
|
||
|
g.write("")
|
||
|
|
||
|
if isinstance(func, str):
|
||
|
g.write("v = {func}({value})", func=func, value=value)
|
||
|
value = "v"
|
||
|
elif func is not None:
|
||
|
g.write("v = {}", func)
|
||
|
value = "v"
|
||
|
|
||
|
propfunc = style_properties[stylepropname]
|
||
|
|
||
|
if propfunc is not None:
|
||
|
g.write("v = {propfunc}({value})", propfunc=propfunc, value=value)
|
||
|
value = "v"
|
||
|
|
||
|
for alt, alt_name in zip(prefix.alts, prefix.alt_names):
|
||
|
|
||
|
if stylepropname in displayable_properties:
|
||
|
g.write("assign_prefixed({}, cache, cache_priorities, priority, {}, '{}') # {}{}",
|
||
|
alt * len(style_properties) + style_property_index[stylepropname],
|
||
|
value, alt_name, alt_name, stylepropname)
|
||
|
else:
|
||
|
g.write("assign({}, cache, cache_priorities, priority, <PyObject *> {}) # {}{}",
|
||
|
alt * len(style_properties) + style_property_index[stylepropname],
|
||
|
value, alt_name, stylepropname)
|
||
|
|
||
|
g.write("return 0")
|
||
|
g.dedent()
|
||
|
|
||
|
g.write("")
|
||
|
g.write('register_property_function("{}", {}_property)', name, name)
|
||
|
g.write("")
|
||
|
|
||
|
pass
|
||
|
|
||
|
|
||
|
def generate_property_functions():
|
||
|
"""
|
||
|
This generates code that defines the property functions.
|
||
|
"""
|
||
|
|
||
|
for prefix in sorted(prefixes.values(), key=lambda p : p.index):
|
||
|
g = CodeGen(module_gen + "/style_{}functions.pyx".format(prefix.name))
|
||
|
|
||
|
g.write('include "style_common.pxi"')
|
||
|
g.write('')
|
||
|
|
||
|
for propname, proplist in all_properties.items():
|
||
|
generate_property_function(g, prefix, propname, proplist)
|
||
|
|
||
|
g.close()
|
||
|
|
||
|
|
||
|
def generate_property(g, propname):
|
||
|
"""
|
||
|
This generates the code for a single property on the style object.
|
||
|
"""
|
||
|
|
||
|
g.write("property {}:", propname)
|
||
|
g.indent()
|
||
|
|
||
|
# __get__
|
||
|
g.write("def __get__(self):")
|
||
|
g.indent()
|
||
|
g.write("return self._get({})", style_property_index[propname])
|
||
|
g.dedent()
|
||
|
|
||
|
# __set__
|
||
|
g.write("def __set__(self, value):")
|
||
|
g.indent()
|
||
|
g.write("self.properties.append({{ '{}' : value }})", propname)
|
||
|
g.dedent()
|
||
|
|
||
|
# __del__
|
||
|
g.write("def __del__(self):")
|
||
|
g.indent()
|
||
|
g.write("self.delattr('{}')", propname)
|
||
|
g.dedent()
|
||
|
|
||
|
g.dedent()
|
||
|
g.write("")
|
||
|
|
||
|
|
||
|
def generate_properties():
|
||
|
|
||
|
g = CodeGen(module_gen + "/styleclass.pxi")
|
||
|
|
||
|
g.write("cdef class Style(StyleCore):")
|
||
|
g.write("")
|
||
|
|
||
|
g.indent()
|
||
|
|
||
|
for propname in style_properties:
|
||
|
generate_property(g, propname)
|
||
|
|
||
|
g.dedent()
|
||
|
g.close()
|
||
|
|
||
|
|
||
|
def generate_sets():
|
||
|
"""
|
||
|
Generates code for sets of properties.
|
||
|
"""
|
||
|
|
||
|
ap = collections.OrderedDict()
|
||
|
|
||
|
for k, v in all_properties.items():
|
||
|
ap[k] = [ i[0] for i in v ]
|
||
|
|
||
|
prefix_priority = collections.OrderedDict()
|
||
|
prefix_alts = collections.OrderedDict()
|
||
|
|
||
|
for p in prefixes.values():
|
||
|
prefix_priority[p.name] = p.priority
|
||
|
prefix_alts[p.name] = p.alt_names
|
||
|
|
||
|
g = CodeGen(module_gen + "/stylesets.pxi")
|
||
|
|
||
|
g.write("# This file is generated by generate_styles.py.")
|
||
|
g.write("")
|
||
|
g.write('exec("""\\')
|
||
|
g.write("all_properties = {}", ap)
|
||
|
g.write("prefix_priority = {}", prefix_priority)
|
||
|
g.write("prefix_alts = {}", prefix_alts)
|
||
|
g.write("prefix_search = {}", PREFIX_SEARCH)
|
||
|
g.write("property_priority = {}", property_priority)
|
||
|
g.write('""")')
|
||
|
g.close()
|
||
|
|
||
|
|
||
|
def generate():
|
||
|
generate_constants()
|
||
|
generate_property_functions()
|
||
|
generate_properties()
|
||
|
generate_sets()
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
generate()
|