123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- # Copyright 2019 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- import os
- import sys
- import collections
- import re
- import textwrap
- from style_variable_generator import path_overrides
- from style_variable_generator.color import Color
- from style_variable_generator.opacity import Opacity
- from style_variable_generator.model import Model, Modes, VariableType
- _FILE_PATH = os.path.dirname(os.path.realpath(__file__))
- _JSON5_PATH = os.path.join(_FILE_PATH, os.pardir, os.pardir, 'third_party',
- 'pyjson5', 'src')
- sys.path.insert(1, _JSON5_PATH)
- import json5
- _JINJA2_PATH = os.path.join(_FILE_PATH, os.pardir, os.pardir, 'third_party')
- sys.path.insert(1, _JINJA2_PATH)
- import jinja2
- class BaseGenerator:
- '''A generic style variable generator.
- Subclasses should provide format-specific generation templates, filters and
- globals to render their output.
- '''
- @staticmethod
- def GetName():
- return None
- def __init__(self):
- self.out_file_path = None
- self.model = Model()
- # A map of input filepaths to their context object.
- self.in_file_to_context = dict()
- # If specified, only generates the given mode.
- self.generate_single_mode = None
- # If true, resolves all blend() colors to the RGBA values at
- # compile time.
- self.resolve_blended_colors = True
- # A dictionary of options used to alter generator function. See
- # ./README.md for each generators list of options.
- self.generator_options = {}
- def GetInputFiles(self):
- return sorted(self.in_file_to_context.keys())
- def AddJSONFilesToModel(self, paths):
- '''Adds one or more JSON files to the model.
- '''
- for path in paths:
- try:
- with open(path, 'r') as f:
- self.AddJSONToModel(f.read(), path)
- except ValueError as err:
- raise ValueError(f'Could not add {path}') from err
- self.model.PostProcess(
- resolve_blended_colors=self.resolve_blended_colors)
- def AddJSONToModel(self, json_string, in_file=None):
- '''Adds a |json_string| with variable definitions to the model.
- See *test.json5 files for a defacto format reference.
- |in_file| is used to populate a file-to-context map.
- '''
- # TODO(calamity): Add allow_duplicate_keys=False once pyjson5 is
- # rolled.
- data = json5.loads(json_string,
- object_pairs_hook=collections.OrderedDict)
- context = data.get('options', {})
- context['token_namespace'] = data.get('token_namespace', '')
- self.in_file_to_context[in_file] = context
- # Add variables to the model.
- for name, value in data.get('colors', {}).items():
- self.model.Add(VariableType.COLOR, name, value, context)
- for name, value in data.get('opacities', {}).items():
- self.model.Add(VariableType.OPACITY, name, value, context)
- typography = data.get('typography')
- if typography:
- for name, value in typography['font_families'].items():
- self.model.Add(VariableType.FONT_FAMILY, name, value, context)
- for name, value_obj in typography['typefaces'].items():
- self.model.Add(VariableType.TYPEFACE, name, value_obj, context)
- for group_name, value_obj in data.get('untyped_css', {}).items():
- for var_name, value in value_obj.items():
- self.model.Add(VariableType.UNTYPED_CSS, var_name, value,
- context)
- def ApplyTemplate(self, style_generator, path_to_template, params):
- loader_root_dir = path_overrides.GetFileSystemLoaderRootDirectory()
- jinja_env = jinja2.Environment(
- loader=jinja2.FileSystemLoader(loader_root_dir),
- keep_trailing_newline=True)
- jinja_env.globals.update(style_generator.GetGlobals())
- jinja_env.filters.update(style_generator.GetFilters())
- template = jinja_env.get_template(
- path_overrides.GetPathToTemplate(path_to_template))
- return template.render(params)
|