Exemplo n.º 1
0
    def sub_block(match) -> str:
        if chapter:
            meta = chapter.get_section_by_offset(match.start())
            meta_config = meta.data.get('confluence', {}).get('codeblocks', {})
            options = CombinedOptions(
                {
                    'backend': config,
                    'meta': meta_config
                },
                priority='meta'
            )
        else:
            options = config

        language = None
        if 'syntax' in match.groupdict():
            language = match.group('syntax')

        source = match.group('content')
        if source.endswith('\n'):
            source = source[:-1]
        logger.debug(f'Found code block ({language}):\n{source[:150]}\n...')
        return gen_code_macro(source,
                              language=language,
                              theme=options.get('theme'),
                              title=options.get('title'),
                              linenumbers=options.get('linenumbers'),
                              collapse=options.get('collapse'))
    def process_template_tag(self, block) -> str:
        """
        Function for processing tag. Send the contents to the corresponging
        template engine along with parameters from tag and config, and
        <content_file> path. Replace the tag with output from the engine.
        """
        tag_options = Options(
            self.get_options(block.group('options')),
            validators={'engine': validate_in(self.engines.keys())})
        options = CombinedOptions({
            'config': self.options,
            'tag': tag_options
        },
                                  priority='tag')

        tag = block.group('tag')
        if tag == 'template':  # if "template" tag is used — engine must be specified
            if 'engine' not in options:
                self._warning(
                    'Engine must be specified in the <template> tag. Skipping.',
                    self.get_tag_context(block))
                return block.group(0)
            engine = self.engines[options['engine']]
        else:
            engine = self.engines[tag]

        current_pos = block.start()
        chapter = get_meta_for_chapter(self.current_filepath)
        section = chapter.get_section_by_offset(current_pos)
        _foliant_vars = {
            'meta': section.data,
            'meta_object': self.meta,
            'config': self.config,
            'target': self.context['target'],
            'backend': self.context['backend'],
            'project_path': self.context['project_path']
        }

        context = {}

        # external context is loaded first, it has lowest priority
        if 'ext_context' in options:
            context.update(
                self.load_external_context(options['ext_context'], options))

        # all unrecognized params are redirected to template engine params
        context.update(
            {p: options[p]
             for p in options if p not in self.tag_params})

        # add options from "context" param
        context.update(options.get('context', {}))

        template = engine(block.group('body'), context,
                          options.get('engine_params', {}),
                          self.current_filepath, _foliant_vars)
        return template.build()
Exemplo n.º 3
0
def get_diagram_format(options: CombinedOptions) -> str:
    '''
    Parse options and get the final diagram format. Format stated in params
    (e.g. tsvg) has higher priority.

    :param options: the options object to be parsed

    :returns: the diagram format string
    '''
    result = None
    for key in options.get('params', {}):
        if key.lower().startswith('t'):
            result = key[1:]
    return result or options['format']
 def _process_jinja(self, spec: PosixPath, options: CombinedOptions) -> str:
     """Process swagger.json with jinja and return the resulting string"""
     self.logger.debug('Using jinja mode')
     data = yaml.safe_load(open(spec, encoding="utf8"))
     additional = options.get('additional_json_path')
     if additional:
         if not additional.exists():
             self._warning(
                 f'Additional swagger spec file {additional} is missing. Skipping'
             )
         else:
             add = yaml.safe_load(open(additional, encoding="utf8"))
             data = {**add, **data}
     if options.is_default('template') and not Path(
             options['template']).exists():
         copyfile(
             resource_filename(__name__,
                               'template/' + self.defaults['template']),
             options['template'])
     return self._to_md(data, options['template'])
    def _process_widdershins(self, spec: PosixPath,
                             options: CombinedOptions) -> str:
        """
        Process swagger.json with widdershins and return the resulting string
        """

        self.logger.debug('Using widdershins mode')
        environment = options.get('environment')
        if environment:
            if isinstance(environment, str) or isinstance(
                    environment, PosixPath):
                env_str = f'--environment {environment}'
            else:  # inline config in foliant.yaml
                env_yaml = str(self._swagger_tmp / 'env.yaml')
                with open(env_yaml, 'w') as f:
                    yaml.dump(environment, f)
                env_str = f'--environment {env_yaml}'
        else:  # not environment
            env_str = ''
        log_path = self._swagger_tmp / 'widdershins.log'
        in_str = str(spec)
        out_str = str(self._swagger_tmp / f'swagger{self._counter}.md')
        cmd = f'widdershins {env_str} {in_str} -o {out_str}'
        self.logger.info(f'Constructed command: \n {cmd}')
        result = run(cmd, shell=True, check=True, stdout=PIPE, stderr=PIPE)
        with open(log_path, 'w') as f:
            f.write(result.stdout.decode())
            f.write('\n\n')
            f.write(result.stderr.decode())
        self.logger.info(f'Build log saved at {log_path}')
        if result.stderr:
            error_fragment = '\n'.join(result.stderr.decode().split("\n")[:3])
            self._warning('Widdershins builder returned error or warning:\n'
                          f'{error_fragment}\n...\n'
                          f'Full build log at {log_path.absolute()}')
        with open(out_str) as f:
            return f.read()
Exemplo n.º 6
0
class DBRendererBase:
    defaults = {}
    module_name = __name__

    def __init__(self, config):
        self.config = config

    def process(self, tag_options) -> str:
        self.options = CombinedOptions(
            {
                'config': self.config,
                'tag': tag_options
            },
            priority='tag',
            defaults=self.defaults)

        self.connect()
        return self.gen_docs()

    def connect(self):
        """
        Connect to database using parameters from options.
        """
        raise NotImplementedError

    def get_template(self, key: str, default_name: str):
        template_path = self.options.get(key)
        if template_path:
            return template_path
        else:
            return resource_filename(self.module_name,
                                     f"templates/{default_name}")

    def get_doc_template(self):
        KEY = 'doc_template'
        DEFAULT_NAME = 'doc.j2'
        return self.get_template(KEY, DEFAULT_NAME)

    def get_scheme_template(self):
        KEY = 'scheme_template'
        DEFAULT_NAME = 'scheme.j2'
        return self.get_template(KEY, DEFAULT_NAME)

    def gen_docs(self) -> str:
        data = self.collect_datasets()

        docs = ''

        if self.options['doc']:
            docs += self.to_md(data, self.get_doc_template())
        if self.options['scheme']:
            docs += '\n\n' + self.to_diag(data, self.get_scheme_template())
        return docs

    def collect_datasets(self) -> dict:
        raise NotImplementedError

    def to_md(self, data: dict, template: str) -> str:
        template_root, template_name = os.path.split(template)
        with open(template, encoding='utf8') as f:
            # template = Template(f.read())
            template = Environment(
                loader=FileSystemLoader(template_root)).from_string(f.read())

        return template.render(**data)

    def to_diag(self, data: dict, template: str) -> str:
        template_root, template_name = os.path.split(template)
        with open(template, encoding='utf8') as f:
            # template = Template(f.read())
            template = Environment(
                loader=FileSystemLoader(template_root)).from_string(f.read())

        return template.render(tables=data['tables'])