class FettBench: template = fett.Template('''{{ for step in steps }} .. only:: not (html or dirhtml or singlehtml) Step {{ i inc }}: {{ step.title }} {{ heading }} {{step.body}} .. only:: html or dirhtml or singlehtml .. raw:: html <div class="sequence-block"> <div class="bullet-block"> <div class="sequence-step">{{i inc}}</div></div> {{step.title}} {{heading}} {{step.body}} .. raw:: html </div> {{ end }}''') @classmethod def bench(cls): cls.template.render(DATA)
def main(args): paths = args[1:] for path in paths: with open(path, 'r') as f: data = yaml.load(f) for test in data['tests']: name = test['name'] template = test['template'] expected = test.get('expected', None) data = test['data'] print(path, name) try: compiled = fett.Template(template) rendered = compiled.render(data) except (ValueError, TypeError) as err: if not test.get('error', False): raise err # pragma: no cover continue try: assert rendered == expected except AssertionError as err: # pragma: no cover print('Got: ', repr(rendered)) print('Expected: ', repr(expected)) raise err
def create_directive(name, template, defined_in, is_yaml): template = fett.Template(template) # Quick-and-dirty fixup. In giza projects, people shouldn't be including # things underneath build/<branch> if defined_in.startswith('build/'): defined_in = '/'.join(defined_in.split('/')[2:]) class CustomDirective(Directive): has_content = True required_arguments = 0 optional_arguments = 1 final_argument_whitespace = True option_spec = {'level': int} def run(self): source_path = self.state.document.get('source') if source_path not in REGISTERED or name not in REGISTERED[ source_path]: raise self.severe(u'Unknown directive: {}. ' u'Try including {}'.format( self.name, defined_in)) contents = '\n'.join(self.content) if is_yaml: data = self.process_yaml(contents) else: title = self.arguments[0] data = {'directive': name, 'body': contents, 'title': title} rendered = template.render(data) rendered_lines = statemachine.string2lines(rendered, 4, convert_whitespace=1) self.state_machine.insert_input(rendered_lines, '') return [] def process_yaml(self, contents): level = self.options.get('level', None) source_path = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) data = yaml.safe_load(contents) options = Options(self.state, source_path, data) if level: options.level = level try: populate(data, options) except IOError as error: raise self.severe( u'Problems with "{}" directive path:\n{}.'.format( self.name, ErrorString(error))) return data return CustomDirective
def run(self): raw_template = fett.Template(self.GRAPHIQL_TEMPLATE) try: rendered_template = raw_template.render(self.options) except Exception as error: raise self.severe('Failed to render template: {}'.format(ErrorString(error))) rendered_lines = statemachine.string2lines(rendered_template, 4, convert_whitespace=1) self.state_machine.insert_input(rendered_lines, '') return []
def run(self): contents = '\n'.join(self.content) try: data = yaml.safe_load(contents) except yaml.YAMLError as error: raise self.severe(u'Error parsing YAML:\n{}.'.format( ErrorString(error))) raw_template = fett.Template(self.TABS_TEMPLATE) try: rendered_template = raw_template.render(data) except Exception as error: raise self.severe('Failed to render template: {}'.format( ErrorString(error))) rendered_lines = statemachine.string2lines(rendered_template, 4, convert_whitespace=1) self.state_machine.insert_input(rendered_lines, '') return []
from dateutil.parser import parse as parse_date from calendar import month_name import fett STITCH_RELEASE = fett.Template(''' {{header}} ------------------------------------ {{for category in categories}} .. _release-note-{{slug_date}}-{{category.name}}: {{category.name}} {{for item in category.items}} - {{item.note}} {{if item.details}} {{item.details}} {{end}} {{end}} {{end}} .. raw:: html <br> ''') def convert_to_snake_case(input): if type(input) is not str:
from docutils import statemachine from docutils.parsers.rst import Directive import fett CODEPEN_TEMPLATE = fett.Template(''' .. raw:: html <p class="codepen" data-pen-title="{{ slug escape }}" data-slug-hash="{{ slug escape }}" data-height="600" data-theme-id="32535" data-default-tab="js,result" data-user="******" data-embed-version="2" data-editable="true"> <a href="https://codepen.io/mongodb-docs/pen/{{ slug escape }}">See this example on codepen: {{ slug escape }}</a> </p> ''') class CodepenDirective(Directive): has_content = False required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True def run(self): data = {'slug': self.arguments[0]} rendered = CODEPEN_TEMPLATE.render(data) rendered_lines = statemachine.string2lines(
PARAMETER_TEMPLATE = fett.Template(""" {{ title }} ***************** .. list-table:: :header-rows: 1 :widths: 20 15 15 50 * - Name - Type - Necessity - Description {{ for parameter in parameters }} * - ``{{ parameter.name }}`` - {{ parameter.data_type }} - {{ if parameter.required }}required{{ else }}optional{{ end }} - {{ parameter.description }}{{ if parameter.enum }} Possible Values: {{ for val in parameter.enum }} - ``{{ val }}`` {{ end }} {{ end }} {{ end }} """)
GUIDES_TEMPLATE = fett.Template(''' :tocdepth: 2 ==================================================================================================== {{ title }} ==================================================================================================== .. default-domain:: mongodb Author: {{ author }} {{ result_description }} *Time required: {{ time }} minutes* What You'll Need ---------------- {{ prerequisites }} Check Your Environment ---------------------- {{ check_your_environment }} Procedure --------- {{ if considerations }} {{ considerations }} {{ end }} {{ procedure }} {{ if verify }} Verify ------ {{ verify }} {{ end }} Summary ------- {{ summary }} What's Next ----------- {{ whats_next }} ''')
from docutils import statemachine from docutils.nodes import Element, Text from docutils.parsers.rst import Directive, directives from template import populate, Options import sphinx import fett import yaml TAB_CONTENT_TEMPLATE = fett.Template(''' .. {{ tabset }}:: hidden: true tabs: - id: {{ tab_id }} content: | {{ content }} ''') class TabContent(Directive): has_content = True required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False option_spec = {'tab-id': directives.unchanged_required} def run(self): options = self.options tabset = self.arguments[0] content = "\n".join(self.content)
LEGACY_GUIDES_TEMPLATE = fett.Template(""" :guide: ==================================================================================================== {{ title }} ==================================================================================================== .. author:: {{ author }} .. category:: {{ type }} {{ if languages }} .. languages:: {{ for language in languages }} * {{ language }} {{ end }} {{ end }} .. level:: {{ level }} {{ if product_version }} .. product_version:: {{ product_version }} {{ end }} .. result_description:: {{ result_description }} .. time:: {{ time }} .. prerequisites:: {{ prerequisites }} {{ if check_your_environment }} .. check_your_environment:: {{ check_your_environment }} {{ end }} .. procedure:: {{ procedure }} .. summary:: {{ summary }} {{ if whats_next }} .. whats_next:: {{ whats_next }} {{ end }} {{ if seealso }} .. seealso:: {{ seealso }} {{ end }} """)
def render_c_header(name: str, defs) -> None: functions = {} # type: Dict[str, List[Any]] print(f'#ifndef __{name.upper()}_H__\n#define __{name.upper()}_H__') print('#include <stdint.h>') print('''#ifdef __cplusplus extern "C" { #endif''') for orig_key, value in defs.items(): key = '{}_{}'.format(name, orig_key) if isinstance(value, str): print('#define {} "{}"'.format(key, value)) elif isinstance(value, numbers.Number): print('#define {} {}'.format(key, value)) elif isinstance(value, StateStruct.Container): print('struct {} {{'.format(key)) for fieldname, fieldvalue in value.items(): typename = resolve_c_type(fieldvalue) print(' {} {};'.format(typename, fieldname)) print('};\n') elif isinstance(value, StateEnum.Container): print('enum {} {{'.format(key)) for fieldname, fieldvalue in value.items(): print(' {}_{} = {},'.format(key, fieldname, fieldvalue)) print('};\n') elif isinstance(value, StateFunction.Container): functions[orig_key] = value elif isinstance(value, StateSignal.Container): pass # print('signal', key, value) print('typedef enum {') for function_name in functions.keys(): print(f' {name.upper()}_METHOD_{function_name.upper()},') print(f'}} {name}_methodid_t;\n') for function_name, function_prototype in functions.items(): print('typedef struct {') for arg in function_prototype[0]: print(f' {resolve_c_type(arg[1])} {arg[0]};') print(f'}} {name}_{function_name}_args_t;\n') print('typedef struct {') print(f' uint64_t messageid;') print(f' {name}_methodid_t methodid;') print(f' union {{') for function_name in functions.keys(): print(f' {name}_{function_name}_args_t args_{function_name};') print(' };') print(f'}} {name}_method_t;') fett.Template.FILTERS['serializeType'] = lambda x: serialize_type(x, defs) template = fett.Template(''' int {{ name }}_read_message(int, {{ name }}_method_t*); int {{ name }}_write_message({{ name }}_method_t*, int); #ifdef {{ name upperCase }}_IMPLEMENTATION #include <cmp/cmp.h> int {{ name }}_read_message(int fd, {{ name }}_method_t* args) { cmp_ctx_t cmp; cmp_init(&cmp, fd, file_reader, file_writer); } int {{ name }}_write_message({{ name }}_method_t* args, int fd) { cmp_ctx_t cmp; cmp_init(&cmp, fd, file_reader, file_writer); if (!cmp_write_array(&cmp, 2)) { return 1; } if (!cmp_write_uinteger(&cmp, args->messageid)) { return 1; } if (!cmp_write_uinteger(&cmp, args->methodid)) { return 1; } switch (args->methodid) { {{ for method in methods }} case {{ name upperCase }}_METHOD_{{ method upperCase }}: {{ method serializeType }} break; {{ end }} } } #endif /* {{ name upperCase }}_IMPLEMENTATION */ #endif /* __{{ name upperCase }}_H__ */ ''') print(template.render({'name': name, 'methods': functions.keys()})) print('''#ifdef __cplusplus } /* extern "C" */ #endif''')
import fett import yaml CARD_GROUP_TEMPLATE_LARGE = fett.Template(''' .. raw:: html <div class="card_group"> {{ for card in cards }} <a href="{{ card.link }}" class="card card-large" id="{{ card.id }}"> <div class="card-image"> .. image:: {{ card.image }} .. raw:: html </div> <div class="card-content"> <div class="card-headline">{{ card.headline }}</div> {{if card.has_subheadline }} <div class="card-subheadline">{{ card.subheadline }}</div> {{end}} </div> </a> {{ end }} </div> ''') CARD_GROUP_TEMPLATE_SMALL = fett.Template(''' .. raw:: html
GUIDES_TEMPLATE = fett.Template(''' :tocdepth: 2 ==================================================================================================== {{ title }} ==================================================================================================== .. default-domain:: mongodb {{ if languages }} .. raw:: html <div class="guide-prefs"> <div class="guide-prefs__caption">Language: <span class="show-current-language"></span></div> .. tabs-pillstrip:: languages .. raw:: html </div> <hr> {{ end }} Author: {{ author }} {{ result_description }} *Time required: {{ time }} minutes* What You'll Need ---------------- {{ prerequisites }} {{ if check_your_environment }} Check Your Environment ---------------------- {{ check_your_environment }} {{ end }} Procedure --------- {{ if considerations }} {{ considerations }} {{ end }} {{ procedure }} {{ if verify }} Verify ------ {{ verify }} {{ end }} Summary ------- {{ summary }} {{ if whats_next }} What's Next ----------- {{ whats_next }} {{ end }} {{ if seealso }} See Also -------- {{ seealso }} {{ end }} ''')
from docutils import statemachine from docutils.nodes import Element, Text from docutils.parsers.rst import Directive, directives from template import populate, Options import sphinx import fett import yaml TAB_CONTENT_TEMPLATE = fett.Template(''' .. {{ tabset }}:: hidden: true tabs: - id: {{ tab_id }} content: | {{ content }} ''') TAB_BAR_TEMPLATE = fett.Template(''' .. {{ tabset }}:: tabs: {{ for tab in tabs }} - id: {{ tab }} content: "" {{ end }} ''') class TabBar(Directive):
PARAMETER_TEMPLATE = fett.Template(''' .. raw:: html <h3>{{ title }}</h3> .. list-table:: :header-rows: 1 :widths: 25 10 65 * - Name - Type - Description {{ for parameter in parameters }} * - ``{{ parameter.name }}`` {{ if parameter.required }}:raw-html:`<span class="apiref-resource__parameter-required-flag"></span>` {{ else }}:raw-html:`<span class="apiref-resource__parameter-optional-flag"></span>`{{ end }} - {{ parameter.type }} - {{ parameter.description }}{{ if parameter.enum }} Possible Values: {{ for val in parameter.enum }} - ``{{ val }}`` {{ end }} {{ end }} {{ end }} ''')
import collections import re import fett from docutils import nodes, statemachine from docutils.parsers.rst import roles, Directive from sphinx.util.nodes import split_explicit_title from docutils.utils.error_reporting import ErrorString PAT_STRIP = re.compile(r'-(?:o|(?:alt))$') ALL_SUFFIXES = ('-add', '-edit', '-exclamation', '-remove', '-restart') HELP_TEMPLATE = fett.Template(''' .. list-table:: {{ for name in icons }} * - ``:{{ role }}:`{{ name }}``` - :{{ role }}:`{{ name }}` {{ end }} ''') IconSet = collections.namedtuple( 'IconSet', ('node_name', 'role_names', 'css_prefix', 'icons')) # Each of the below classes describes an icon font. Each must provide: # * A name for the docutils icon node # * A name for the docutils role # * A prefix for the CSS class attached to the output <span> # * A set of known icon names # Request new icons from the PPO team #: FontAwesome 5 Solid icon font ICONS_FA5 = IconSet( node_name='IconFA5',
from docutils import statemachine from docutils.parsers.rst import Directive from docutils.parsers.rst import directives import fett CODEPEN_TEMPLATE = fett.Template(''' .. raw:: html <iframe height={{ height }} scrolling='no' title={{ title escape }} src='//codepen.io/mongodb-docs/embed/{{ slug escape }}/?height={{ height }}&theme-id=32535&default-tab=js,result&embed-version=2&editable=true' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;' > See the Pen <a href='https://codepen.io/mongodb-docs/pen/{{ slug escape }}/'> {{ title escape }} </a> by Shannon Bradshaw (<a href='https://codepen.io/mongodb-docs'>@mongodb-docs</a>) on <a href='https://codepen.io'>CodePen</a>. </iframe> ''') class CodepenDirective(Directive): has_content = False required_arguments = 1