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()
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()
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'])