def __init__(self, option): if not isinstance(option, Option): raise TypeError else: self.option = option self.rst = RstCloth()
def build_contents(self): self.contents = RstCloth() self.contents.directive('class', 'hidden') self.contents.newline() self.contents.directive('toctree', fields=[('titlesonly', '')], indent=3) self.contents.newline()
def __init__(self, steps): if not isinstance(steps, Steps): raise TypeError else: self.steps = steps self.current_step = 1 self.rst = RstCloth() self.hook()
def __init__(self, imported_table, widths=None, indent=0): self.table = imported_table self.indent = indent if widths is not None: self.widths = [str(i) for i in widths] else: self.widths = None self.r = RstCloth() self._render_table() self.output = self.r.data
def generate_release_copy(builder, release): r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') r.content('mkdir -p mongodb', 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-{1}/ mongodb'.format(builder, release), 3, wrap=False, block='cmd') return r
def generate_release_untar(builder, release): r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') r.content('tar -zxvf mongodb-{0}-{1}.tgz'.format(builder, release), 3, wrap=False, block='cmd') return r
def __init__(self, imported_table, widths=None, indent=0): self.table = imported_table self.indent = indent if widths is not None: self.widths = [ str(i) for i in widths ] else: self.widths = None self.r = RstCloth() self._render_table() self.output = self.r.data
def generate_hash_file(fn): r = RstCloth() if os.path.exists(fn): with open(fn, 'r') as f: existing = f.read() else: existing = [] commit = get_commit() r.directive('|commit| replace', '``{0}``'.format(commit)) try: if r.data == existing[:-1]: logger.info('no new commit(s), not updating {0} ({1})'.format( fn, commit[:10])) return True except TypeError: logger.warning('problem generating {0}, continuing'.format(fn)) with file(fn, 'a'): os.utime(fn, times) else: r.write(fn) logger.info('regenerated {0} with new commit hash: {1}'.format( fn, commit[:10]))
def generate_hash_file(fn): r = RstCloth() if os.path.exists(fn): with open(fn, 'r') as f: existing = f.read() else: existing = [] commit = get_commit() r.directive('|commit| replace', '``{0}``'.format(commit)) try: if r.data == existing[:-1]: logger.info('no new commit(s), not updating {0} ({1})'.format(fn, commit[:10])) return True except TypeError: logger.warning('problem generating {0}, continuing'.format(fn)) with file(fn, 'a'): os.utime(fn, times) else: r.write(fn) logger.info('regenerated {0} with new commit hash: {1}'.format(fn, commit[:10]))
def generate_param_table(params): table_data = ParamTable() table_data.set_column_widths(params[0]) table_data.add_header( render_header_row(params[0], table_data.num_rows, table_data.type_column)) for param in params: row = [RstCloth().pre(param['name'])] if table_data.type_column is True: row.append(process_type_cell(param['type'], 'table')) row.append( process_description(param['description'], param['field']['optional'])) table_data.add_row(row) table = TableBuilder(ListTable(table_data, widths=table_data.widths)) return table.output
def generate_hash_file(fn): r = RstCloth() if os.path.exists(fn): with open(fn, 'r') as f: existing = f.read() else: existing = [] commit = get_commit() r.directive('|commit| replace', '``{0}``'.format(commit)) try: if r.get_block('_all')[0] == existing[:-1]: print('[build]: no new commit(s), not updating {0} ({1})'.format(fn, commit[:10])) return True except TypeError: print('[ERROR] [build]: problem generating {0}, continuing'.format(fn)) with file(fn, 'a'): os.utime(fn, times) else: r.write(fn) print('[build]: regenerated {0} with new commit hash: {1}'.format(fn, commit[:10]))
def generate_image_pages(dir, name, alt, output, conf=None): r = RstCloth() conf = lazy_conf(conf) image = "/".join([dir, name]) b = name for img_output in output: img_output["width"] = str(img_output["width"]) + "px" r.newline() if "tag" in img_output: tag = "-" + img_output["tag"] + ".png" else: tag = ".png" options = [("alt", alt), ("align", "center"), ("figwidth", img_output["width"])] if "scale" in img_output: options.append(("scale", img_output["scale"])) if img_output["type"] == "print": r.directive("only", "latex", wrap=False, block=b) r.newline() r.directive( name="figure", arg="/images/{0}{1}".format(name, tag), fields=options, indent=3, content=alt, block=b ) else: alt_html = publish_parts(alt, writer_name="html")["body"].strip() img_tags = [ '<div class="figure align-center" style="max-width:{5};">', '<img src="{0}/{1}/_images/{2}{3}" alt="{4}">', "</img>", "{6}</div>", ] img_str = "".join(img_tags) r.directive("only", "website and not html", wrap=False, block=b) r.newline() r.directive( name="raw", arg="html", content=img_str.format( conf.project.url, conf.git.branches.current, name, tag, alt, img_output["width"], alt_html ), indent=3, block=b, ) r.newline(count=2) if img_output["width"] > 600: options[2] = ("figwidth", 600) r.directive("only", "website and html", wrap=False, block=b) r.newline() r.directive( name="figure", arg="/images/{0}{1}".format(name, tag), fields=options, indent=3, content=alt, block=b ) r.newline(block=b) r.write(image + ".rst") logger.debug("generated include file {0}.rst".format(image))
class CustomTocTree(object): def __init__(self, filename, conf=None, sort=False): self.spec = self._process_spec(filename, sort) self.conf = lazy_conf(conf) if "ref-toc" in filename: self._is_ref = True else: self._is_ref = False self.table = None self.contents = None self.dfn = None self.final = False def build_table(self): self.table = TableData() self.table.add_header(['Name', 'Description']) def build_dfn(self): self.dfn = RstCloth() self.dfn.directive('class', 'toc') self.dfn.newline() def build_contents(self): self.contents = RstCloth() self.contents.directive('class', 'hidden') self.contents.newline() self.contents.directive('toctree', fields=[('titlesonly', '')], indent=3) self.contents.newline() def _process_spec(self, spec, sort=False): o = [] with open(spec, 'r') as f: data = yaml.safe_load_all(f) for datum in data: if 'description' not in datum or datum['description'] is None: datum['description'] = '' if sort is False: pass elif 'name' not in datum: sort = False o.append(datum) if sort is True: o.sort(key=lambda o: o['name']) return o def finalize(self): if not self.final: for ref in self.spec: if 'edition' in ref: if 'edition' in self.conf.project: if ref['edition'] != self.conf.project.edition: continue if self.table is not None: if 'text' in ref: if ref['name'] is None: self.table.add_row(['', ref['text']]) else: self.table.add_row([ref['name'], ref['text']]) if 'name' in ref: self.table.add_row([ref['name'], ref['description']]) else: self.table = None if self.contents is not None and 'file' in ref: if 'name' in ref and self._is_ref is False: self.contents.content("{0} <{1}>".format( ref['name'], ref['file']), 6, wrap=False, block='toc') else: self.contents.content(ref['file'], 6, wrap=False, block='toc') if self.dfn is not None: if 'name' in ref: text = ref['name'] else: text = None if 'level' in ref: idnt = 3 * ref['level'] else: idnt = 3 if 'class' in ref: self.dfn.directive(name='class', arg=ref['class'], indent=idnt) idnt += 3 if 'text' in ref: if ref['name'] is None: self.dfn.content(ref['text'], idnt) else: self.dfn.definition(ref['name'], ref['text'], indent=idnt, bold=False, wrap=False) else: link = self.dfn.role('doc', ref['file'], text) self.dfn.definition(link, ref['description'], indent=idnt, bold=False, wrap=False) self.dfn.newline()
def render_step_file(input_fn, output_fn=None): steps = Steps(input_fn) r = RstCloth() web_output = WebStepsOutput(steps) web_output.render() r.content(web_output.rst.get_block(), indent=0, wrap=False) r.directive('only', 'latex') r.newline() print_output = PrintStepsOutput(steps) print_output.render() r.content(print_output.rst.get_block(), indent=3, wrap=False) if output_fn is None: output_fn = os.path.splitext(input_fn)[0] + '.rst' r.write(output_fn) print('[steps]: rendered step include at ' + output_fn)
class StepsOutput(object): """ Base class for rendered step form. The render() method generates the rst in the internal RstCloth object. """ def __init__(self, steps, conf=None): if not isinstance(steps, Steps): raise TypeError else: self.steps = steps self.conf = lazy_conf(conf) self.current_step = 1 self.rst = RstCloth() self.hook() def hook(self): self.indent = 3 def edition_check(self, step): if 'edition' in step: if 'edition' in self.conf.project: if step['edition'] != self.conf.project.edition: return False else: return True @staticmethod def annotate_optional(step): if 'optional' in step and step['optional'] is True: if isinstance(step['title'], dict): step['title']['text'] = 'Optional. ' + step['title']['text'] else: if 'title' in step: step['title'] = 'Optional. ' + step['title'] elif 'heading' in step: step['heading'] = 'Optional. ' + step['heading'] del step['optional'] return step else: return step def render(self): for step in self.steps.source_list: if self.edition_check(step) is False: continue step = self.annotate_optional(step) self.heading(step) self.pre(step) self.current_step = step['stepnum'] if 'action' in step: if isinstance(step['action'], list): for block in step['action']: self.code_step(block) else: self.code_step(step['action']) self.content(step) self.post(step) def content(self, doc): if 'content' in doc and doc['content'] is not None: self.rst.content(doc['content'], wrap=False, indent=self.indent) self.rst.newline() def pre(self, doc): if 'pre' in doc and doc['pre'] is not None: self.rst.content(doc['pre'], wrap=False, indent=self.indent) self.rst.newline() def post(self, doc, code_step=False): if 'post' in doc and doc['post'] is not None: self.rst.content(doc['post'], wrap=False, indent=self.indent) self.rst.newline() if code_step is False: self.post_step_hook() def post_step_hook(self): pass def _heading(self, block, override_char=None, indent=0): if 'heading' in block: if isinstance(block['heading'], dict): if 'character' in block['heading']: pass else: block['heading']['character'] = override_char else: block['heading'] = { 'text': block['heading'], 'character': override_char } if block['heading']['text'] is None: logger.error('step in "{0}" is missing a heading'.format(os.path.basename(self.steps.source_fn))) return self.rst.heading(text=block['heading']['text'], char=block['heading']['character'], indent=indent) self.rst.newline() def code_step(self, block): if 'code' in block and 'content' in block: raise InvalidStep if 'heading' in block: self.block_heading(block) self.pre(block) if 'code' in block: if 'language' not in block: block['language'] = 'none' if not isinstance(block['code'], list): block['code'] = block['code'].split('\n') self.rst.directive(name='code-block', arg=block['language'], content=block['code'], indent=self.indent) self.rst.newline() if 'content' in block: self.content(block['content']) self.post(block, code_step=True) def key_name(self): key_name = os.path.splitext(os.path.basename(self.steps.source_fn))[0] if key_name.startswith('step-') or key_name.startswith('steps-'): key_name = key_name.split('-', 1)[1] return key_name
def render_step_file(input_fn, output_fn=None, conf=None): input_fn_base = os.path.basename(input_fn) logger.debug('generating step file for {0}'.format(input_fn_base)) steps = Steps(input_fn) logger.debug('resolved step file input for {0}'.format(input_fn_base)) r = RstCloth() web_output = WebStepsOutput(steps, conf=conf) web_output.render() r.content(web_output.rst.data, indent=0, wrap=False) logger.debug('generated web output for {0}'.format(input_fn_base)) r.directive('only', 'latex') r.newline() print_output = PrintStepsOutput(steps, conf=conf) print_output.render() r.content(print_output.rst.data, indent=3, wrap=False) logger.debug('generated print output for {0}'.format(input_fn_base)) if output_fn is None: output_fn = os.path.splitext(input_fn)[0] + '.rst' r.write(output_fn) logger.debug('wrote step include at {0}'.format(output_fn))
def build_page(data, conf): fn = os.path.join(conf.paths.projectroot, conf.paths.includes, 'metadata.yaml') if not os.path.exists(fn): return None else: iconf = BuildConfiguration(fn) r = RstCloth() r.title(iconf.title) r.newline() r.directive('default-domain', iconf.domain) r.newline() if 'introduction' in iconf: r.content(iconf.introduction) r.newline() r.directive(name='contents', arg='Included Files', fields=[ ('backlinks', 'none'), ('class', 'long-toc'), ('depth', 1), ('local', ''), ]) r.newline() data = data.items() data.sort() for _, record in data: page_name = r.pre(record['name']) r.heading(text=page_name, char='-', indent=0) r.newline() r.heading('Meta', char='~', indent=0) r.newline() if record['num_clients'] == 0: r.content('{0} is not included in any files.'.format(page_name)) r.newline() add_content(r, record) elif record['num_clients'] == 1: if record['yaml_only']: r.content( '{0} is only included in yaml files.'.format(page_name)) r.newline() else: link = r.role('doc', record['clients'][0]) r.content('{0} is only included in {1}.'.format( page_name, link)) r.newline() add_meta(r, page_name, record) add_content(r, record) else: r.content('{0} is included in **{1}** files.'.format( page_name, record['num_clients']), wrap=False) r.newline() add_meta(r, page_name, record) if record['yaml_only'] is False: clients = [ p for p in record['clients'] if not p.startswith('/includes') ] if len(clients) == 1: client_link = r.role('doc', clients[0]) inc_str = '{0} is the only file that includes {1} that is not also an include.' r.content(inc_str.format(client_link, page_name)) r.newline() else: r.heading('Client Pages', char='~', indent=0) r.newline() for pg in clients: client_link = r.role('doc', pg) r.li(client_link, wrap=False) r.newline() add_include_example(r, page_name, record['path']) add_content(r, record) return r
def generate_image_pages(dir, name, alt, output, conf=None): r = RstCloth() conf = lazy_conf(conf) image = '/'.join([dir, name]) b = name for img_output in output: img_output['width'] = str(img_output['width']) + 'px' r.newline() if 'tag' in img_output: tag = '-' + img_output['tag'] + '.png' else: tag = '.png' options = [('alt', alt), ('align', 'center'), ('figwidth', img_output['width'])] if 'scale' in img_output: options.append(('scale', img_output['scale'])) if img_output['type'] == 'print': r.directive('only', 'latex', wrap=False, block=b) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3, content=alt, block=b) else: alt_html = publish_parts(alt, writer_name='html')['body'].strip() img_tags = ['<div class="figure align-center" style="max-width:{5};">', '<img src="{0}/{1}/_images/{2}{3}" alt="{4}">', '</img>', '{6}</div>' ] img_str = ''.join(img_tags) r.directive('only', 'website and not html', wrap=False, block=b) r.newline() r.directive(name='raw', arg='html', content=img_str.format(conf.project.url, conf.git.branches.current, name, tag, alt, img_output['width'], alt_html), indent=3, block=b) r.newline(count=2) if img_output['width'] > 600: options[2] = ('figwidth', 600) r.directive('only', 'website and html', wrap=False, block=b) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3, content=alt, block=b) r.newline(block=b) r.write(image + '.rst') logger.debug('generated include file {0}.rst'.format(image))
def generate_release_output(builder, platform, architecture, release): """ This is the contemporary version of the function used by the generate.py script""" r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') if architecture == 'core': r.content( 'curl -O http://downloads.mongodb.org/{0}/mongodb-{1}-{2}.tgz'. format(platform, builder, release), 3, wrap=False, block='cmd') else: r.content( 'curl -O http://downloads.10gen.com/linux/mongodb-{0}-subscription-{1}-{2}.tgz' .format(builder, architecture, release), 3, wrap=False, block='cmd') r.content('tar -zxvf mongodb-{0}-subscription-{1}-{2}.tgz'.format( builder, architecture, release), 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-subscription-{1}-{2}/ mongodb'.format( builder, architecture, release), 3, wrap=False, block='cmd') r.newline(block='footer') return r
class OptionRendered(object): def __init__(self, option): if not isinstance(option, Option): raise TypeError else: self.option = option self.rst = RstCloth() def resolve_option_name(self): if self.option.directive == "option": if self.option.name.startswith("<"): prefix = "" else: prefix = "--" if hasattr(self.option, "aliases"): if hasattr(self.option, "arguments"): return "{0}{1} {2}, {3}".format( prefix, self.option.name, self.option.arguments, "{0}, ".format(self.option.arguments).join(self.option.aliases), ) else: return "{0}{1}, {2}".format(prefix, self.option.name, ", ".join(self.option.aliases)) else: if hasattr(self.option, "arguments"): return "{0}{1} {2}".format(prefix, self.option.name, self.option.arguments) else: return "{0}{1}".format(prefix, self.option.name) else: return self.option.name def resolve_output_path(self, path): name_parts = self.option.name.split(",") if len(name_parts) > 1: clensed_name = name_parts[0] else: clensed_name = self.option.name fn = "-".join([self.option.directive, self.option.program, clensed_name]) + ".rst" return os.path.join(path, fn) def render(self, path): self.option.replace() self.rst.directive(self.option.directive, self.resolve_option_name()) self.rst.newline() if self.option.default is not None: self.content("*Default*: {0}".format(self.option.default)) self.rst.newline() if self.option.type is not None: self.content("*Type*: {0}".format(self.option.type)) self.rst.newline() if self.option.pre is not None: self.rst.content(self.option.pre.split("\n"), indent=3, wrap=False) self.rst.newline() if self.option.description is not None: self.rst.content(self.option.description.split("\n"), indent=3, wrap=False) self.rst.newline() if self.option.post is not None: self.rst.content(self.option.post.split("\n"), indent=3, wrap=False) self.rst.newline() output_file = self.resolve_output_path(path) self.rst.write(output_file)
class ListTable(OutputTable): def __init__(self, imported_table, widths=None, indent=0): self.table = imported_table self.indent = indent if widths is not None: self.widths = [ str(i) for i in widths ] else: self.widths = None self.r = RstCloth() self._render_table() self.output = self.r.data def _render_table(self): b = '_all' rows = [] _fields = [] if self.table.header is not None: _fields.append(('header-rows', '1')) rows.append(self.table.header[0]) idx = 0 else: idx = 1 if self.widths is not None: _fields.append(('widths', ' '.join(self.widths))) rows.extend(self.table.rows) self.r.directive('list-table', fields=_fields, indent=self.indent, block=b) self.r.newline(block=b) for row in rows: r = row[idx] self.r.li(r[0], bullet='* -', indent=self.indent + 3, wrap=False, block=b) self.r.newline(block=b) for cell in r[1:]: self.r.li(cell, bullet=' -', indent=self.indent + 3, wrap=False, block=b) self.r.newline(block=b) idx += 1
def generate_params(params, fn, conf): r = RstCloth() basename = os.path.basename(fn) params.sort(key=lambda p: p['position']) # Begin by generating the table for web output r.directive('only', '(html or singlehtml or dirhtml)', block='htm') r.newline(block='htm') # { filename: { $name: <param> } } ext_params = {} processed_params = [] for param in params: if 'file' in param: pos = param['position'] if param['file'] not in ext_params: fn, ext = populate_external_param(param['file'], basename, conf.paths.projectroot, conf.paths.source) ext_params[fn] = ext param = ext_params[conf.paths.source + param['file']][param['name']] param['position'] = pos processed_params.append(param) r.content(generate_param_table(processed_params), indent=3, block='html') r.newline(block='htm') # Then generate old-style param fields for non-web output r.directive('only', '(texinfo or latex or epub)', block='tex') r.newline(block='tex') for param in processed_params: key, val = generate_param_fields(param) r.field(name=key, value=val, indent=3, wrap=False, block='tex') r.newline(block='tex') return r
class OptionRendered(object): def __init__(self, option): if not isinstance(option, Option): raise TypeError else: self.option = option self.rst = RstCloth() def resolve_option_name(self): if self.option.directive == 'option': if self.option.name.startswith('<'): prefix = '' else: prefix = '--' if hasattr(self.option, 'aliases'): if hasattr(self.option, 'arguments'): return '{0}{1} {2}, {3}'.format( prefix, self.option.name, self.option.arguments, '{0}, '.format(self.option.arguments).join( self.option.aliases)) else: return '{0}{1}, {2}'.format(prefix, self.option.name, ', '.join(self.option.aliases)) else: if hasattr(self.option, 'arguments'): return '{0}{1} {2}'.format(prefix, self.option.name, self.option.arguments) else: return '{0}{1}'.format(prefix, self.option.name) else: return self.option.name def resolve_output_path(self, path): name_parts = self.option.name.split(',') if len(name_parts) > 1: clensed_name = name_parts[0] else: clensed_name = self.option.name fn = '-'.join([ self.option.directive, self.option.program, clensed_name ]) + '.rst' return os.path.join(path, fn) def render(self, path): self.option.replace() self.rst.directive(self.option.directive, self.resolve_option_name()) self.rst.newline() if self.option.type is not None: self.rst.content('*Type*: {0}'.format(self.option.type), indent=3) self.rst.newline() if self.option.default is not None: self.rst.content('*Default*: {0}'.format(self.option.default), indent=3) self.rst.newline() if self.option.pre is not None: self.rst.content(self.option.pre.split('\n'), indent=3, wrap=False) self.rst.newline() if self.option.description is not None: self.rst.content(self.option.description.split('\n'), indent=3, wrap=False) self.rst.newline() if self.option.post is not None: self.rst.content(self.option.post.split('\n'), indent=3, wrap=False) self.rst.newline() output_file = self.resolve_output_path(path) self.rst.write(output_file) logger.debug('wrote option to file {0}'.format(output_file))
def generate_release_output(builder, platform, architecture, release): """ This is the contemporary version of the function used by the generate.py script""" r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') if architecture == 'core': r.content('curl -O http://downloads.mongodb.org/{0}/mongodb-{1}-{2}.tgz'.format(platform, builder, release), 3, wrap=False, block='cmd') else: r.content('curl -O http://downloads.10gen.com/linux/mongodb-{0}-subscription-{1}-{2}.tgz'.format(builder, architecture, release), 3, wrap=False, block='cmd') r.content('tar -zxvf mongodb-{0}-subscription-{1}-{2}.tgz'.format(builder, architecture, release), 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-subscription-{1}-{2}/ mongodb'.format(builder, architecture, release), 3, wrap=False, block='cmd') r.newline(block='footer') return r
class CustomTocTree(object): def __init__(self, filename, conf=None, sort=False): self.spec = self._process_spec(filename, sort) self.conf = lazy_conf(conf) if "ref-toc" in filename: self._is_ref = True else: self._is_ref = False self.table = None self.contents = None self.dfn = None self.final = False def build_table(self): self.table = TableData() self.table.add_header(['Name', 'Description']) def build_dfn(self): self.dfn = RstCloth() self.dfn.directive('class', 'toc') self.dfn.newline() def build_contents(self): self.contents = RstCloth() self.contents.directive('class', 'hidden') self.contents.newline() self.contents.directive('toctree', fields=[('titlesonly', '')], indent=3) self.contents.newline() def _process_spec(self, spec, sort=False): o = [] with open(spec, 'r') as f: data = yaml.safe_load_all(f) for datum in data: if 'description' not in datum or datum['description'] is None: datum['description'] = '' if sort is False: pass elif 'name' not in datum: sort = False o.append(datum) if sort is True: o.sort(key=lambda o: o['name']) return o def finalize(self): if not self.final: for ref in self.spec: if 'edition' in ref: if 'edition' in self.conf.project: if ref['edition'] != self.conf.project.edition: continue if self.table is not None: if 'text' in ref: if ref['name'] is None: self.table.add_row( [ '', ref['text'] ] ) else: self.table.add_row( [ ref['name'], ref['text'] ]) if 'name' in ref: self.table.add_row([ ref['name'], ref['description'] ]) else: self.table = None if self.contents is not None and 'file' in ref: if 'name' in ref and self._is_ref is False: self.contents.content("{0} <{1}>".format(ref['name'], ref['file']), 6, wrap=False, block='toc') else: self.contents.content(ref['file'], 6, wrap=False, block='toc') if self.dfn is not None: if 'name' in ref: text = ref['name'] else: text = None if 'level' in ref: idnt = 3 * ref['level'] else: idnt = 3 if 'class' in ref: self.dfn.directive(name='class', arg=ref['class'], indent=idnt) idnt += 3 if 'text' in ref: if ref['name'] is None: self.dfn.content(ref['text'], idnt) else: self.dfn.definition(ref['name'], ref['text'], indent=idnt, bold=False, wrap=False) else: link = self.dfn.role('doc', ref['file'], text) self.dfn.definition(link, ref['description'], indent=idnt, bold=False, wrap=False) self.dfn.newline()
def generate_output(builder, platform, version, release): """ This is the legacy version of the function used by the makefile and CLI infrastructure""" r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') if release == 'core': r.content( 'curl -O http://downloads.mongodb.org/{0}/mongodb-{1}-{2}.tgz'. format(platform, builder, version), 3, wrap=False, block='cmd') else: r.content( 'curl -O http://downloads.10gen.com/linux/mongodb-{0}-subscription-{1}-{2}.tgz' .format(builder, release, version), 3, wrap=False, block='cmd') r.content('tar -zxvf mongodb-{0}-subscription-{1}-{2}.tgz'.format( builder, release, version), 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-subscription-{1}-{2}/ mongodb'.format( builder, release, version), 3, wrap=False, block='cmd') r.newline(block='footer') return r
def build_dfn(self): self.dfn = RstCloth() self.dfn.directive('class', 'toc') self.dfn.newline()
class StepsOutput(object): """ Base class for rendered step form. The render() method generates the rst in the internal RstCloth object. """ def __init__(self, steps, conf=None): if not isinstance(steps, Steps): raise TypeError else: self.steps = steps self.conf = lazy_conf(conf) self.current_step = 1 self.rst = RstCloth() self.hook() def hook(self): self.indent = 3 def edition_check(self, step): if 'edition' in step: if 'edition' in self.conf.project: if step['edition'] != self.conf.project.edition: return False else: return True @staticmethod def annotate_optional(step): if 'optional' in step and step['optional'] is True: if isinstance(step['title'], dict): step['title']['text'] = 'Optional. ' + step['title']['text'] else: if 'title' in step: step['title'] = 'Optional. ' + step['title'] elif 'heading' in step: step['heading'] = 'Optional. ' + step['heading'] del step['optional'] return step else: return step def render(self): for step in self.steps.source_list: if self.edition_check(step) is False: continue step = self.annotate_optional(step) self.heading(step) self.pre(step) self.current_step = step['stepnum'] if 'action' in step: if isinstance(step['action'], list): for block in step['action']: self.code_step(block) else: self.code_step(step['action']) self.content(step) self.post(step) def content(self, doc): if 'content' in doc and doc['content'] is not None: self.rst.content(doc['content'], wrap=False, indent=self.indent) self.rst.newline() def pre(self, doc): if 'pre' in doc and doc['pre'] is not None: self.rst.content(doc['pre'], wrap=False, indent=self.indent) self.rst.newline() def post(self, doc, code_step=False): if 'post' in doc and doc['post'] is not None: self.rst.content(doc['post'], wrap=False, indent=self.indent) self.rst.newline() if code_step is False: self.post_step_hook() def post_step_hook(self): pass def _heading(self, block, override_char=None, indent=0): if 'heading' in block: if isinstance(block['heading'], dict): if 'character' in block['heading']: pass else: block['heading']['character'] = override_char else: block['heading'] = { 'text': block['heading'], 'character': override_char } if block['heading']['text'] is None: logger.error('step in "{0}" is missing a heading'.format( os.path.basename(self.steps.source_fn))) return self.rst.heading(text=block['heading']['text'], char=block['heading']['character'], indent=indent) self.rst.newline() def code_step(self, block): if 'code' in block and 'content' in block: raise InvalidStep if 'heading' in block: self.block_heading(block) self.pre(block) if 'code' in block: if 'language' not in block: block['language'] = 'none' if not isinstance(block['code'], list): block['code'] = block['code'].split('\n') self.rst.directive(name='code-block', arg=block['language'], content=block['code'], indent=self.indent) self.rst.newline() if 'content' in block: self.content(block['content']) self.post(block, code_step=True) def key_name(self): key_name = os.path.splitext(os.path.basename(self.steps.source_fn))[0] if key_name.startswith('step-') or key_name.startswith('steps-'): key_name = key_name.split('-', 1)[1] return key_name
def render_page(doc, conf): r = RstCloth() out_fn = os.path.join(conf.paths.projectroot, conf.paths.source, doc.system_name + '.txt') r.title(doc.system_title) r.newline() r.content(doc.system_description) r.newline() r.write(out_fn)
def generate_image_pages(dir, name, alt, output, conf=None): r = RstCloth() conf = lazy_conf(conf) image = '/'.join([dir, name]) b = name for img_output in output: img_output['width'] = str(img_output['width']) + 'px' r.newline() if 'tag' in img_output: tag = '-' + img_output['tag'] + '.png' else: tag = '.png' options = [('alt', alt), ('align', 'center'), ('figwidth', img_output['width'])] if 'scale' in img_output: options.append(('scale', img_output['scale'])) if img_output['type'] == 'print': r.directive('only', 'latex', wrap=False, block=b) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3, content=alt, block=b) else: alt_html = publish_parts(alt, writer_name='html')['body'].strip() img_tags = ['<div class="figure align-center" style="max-width:{5};">', '<img src="{0}/{1}/_images/{2}{3}" alt="{4}">', '</img>', '{6}</div>' ] img_str = ''.join(img_tags) r.directive('only', 'website and not html', wrap=False, block=b) r.newline() r.directive(name='raw', arg='html', content=img_str.format(conf.project.url, conf.git.branches.current, name, tag, alt, img_output['width'], alt_html), indent=3, block=b) r.newline(count=2) if img_output['width'] > 600: options[2] = ('figwidth', 600) r.directive('only', 'website and html', wrap=False, block=b) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3, content=alt, block=b) r.newline(block=b) r.write(image + '.rst') print('[image]: generated include file {0}.rst'.format(image))
def generate_output(builder, platform, version, release): """ This is the legacy version of the function used by the makefile and CLI infrastructure""" r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') if release == 'core': r.content('curl -O http://downloads.mongodb.org/{0}/mongodb-{1}-{2}.tgz'.format(platform, builder, version), 3, wrap=False, block='cmd') else: r.content('curl -O http://downloads.10gen.com/linux/mongodb-{0}-subscription-{1}-{2}.tgz'.format(builder, release, version), 3, wrap=False, block='cmd') r.content('tar -zxvf mongodb-{0}-subscription-{1}-{2}.tgz'.format(builder, release, version), 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-subscription-{1}-{2}/ mongodb'.format(builder, release, version), 3, wrap=False, block='cmd') r.newline(block='footer') return r
class ListTable(OutputTable): def __init__(self, imported_table, widths=None, indent=0): self.table = imported_table self.indent = indent if widths is not None: self.widths = [str(i) for i in widths] else: self.widths = None self.r = RstCloth() self._render_table() self.output = self.r.data def _render_table(self): b = '_all' rows = [] _fields = [] if self.table.header is not None: _fields.append(('header-rows', '1')) rows.append(self.table.header[0]) idx = 0 else: idx = 1 if self.widths is not None: _fields.append(('widths', ' '.join(self.widths))) rows.extend(self.table.rows) self.r.directive('list-table', fields=_fields, indent=self.indent, block=b) self.r.newline(block=b) for row in rows: r = row[idx] self.r.li(r[0], bullet='* -', indent=self.indent + 3, wrap=False, block=b) self.r.newline(block=b) for cell in r[1:]: self.r.li(cell, bullet=' -', indent=self.indent + 3, wrap=False, block=b) self.r.newline(block=b) idx += 1
def build_page(data, conf): fn = os.path.join(conf.paths.projectroot, conf.paths.includes, 'metadata.yaml') if not os.path.exists(fn): return None else: iconf = BuildConfiguration(fn) r = RstCloth() r.title(iconf.title) r.newline() r.directive('default-domain', iconf.domain) r.newline() if 'introduction' in iconf: r.content(iconf.introduction) r.newline() r.directive(name='contents', arg='Included Files', fields=[ ('backlinks', 'none'), ('class', 'long-toc'), ('depth', 1), ('local', ''), ]) r.newline() data = data.items() data.sort() for _, record in data: page_name = r.pre(record['name']) r.heading(text=page_name, char='-', indent=0) r.newline() r.heading('Meta', char='~', indent=0) r.newline() if record['num_clients'] == 0: r.content('{0} is not included in any files.'.format(page_name)) r.newline() add_content(r, record) elif record['num_clients'] == 1: if record['yaml_only']: r.content('{0} is only included in yaml files.'.format(page_name)) r.newline() else: link = r.role('doc', record['clients'][0]) r.content('{0} is only included in {1}.'.format(page_name, link)) r.newline() add_meta(r, page_name, record) add_content(r, record) else: r.content('{0} is included in **{1}** files.'.format(page_name, record['num_clients']), wrap=False) r.newline() add_meta(r, page_name, record) if record['yaml_only'] is False: clients = [ p for p in record['clients'] if not p.startswith('/includes') ] if len(clients) == 1: client_link = r.role('doc', clients[0]) inc_str = '{0} is the only file that includes {1} that is not also an include.' r.content(inc_str.format(client_link, page_name)) r.newline() else: r.heading('Client Pages', char='~', indent=0) r.newline() for pg in clients: client_link = r.role('doc', pg) r.li(client_link, wrap=False) r.newline() add_include_example(r, page_name, record['path']) add_content(r, record) return r
class OptionRendered(object): def __init__(self, option): if not isinstance(option, Option): raise TypeError else: self.option = option self.rst = RstCloth() def resolve_option_name(self): if self.option.directive == 'option': if self.option.name.startswith('<'): prefix = '' else: prefix = '--' if hasattr(self.option, 'aliases'): if hasattr(self.option, 'arguments'): return '{0}{1} {2}, {3}'.format(prefix, self.option.name, self.option.arguments, '{0}, '.format(self.option.arguments).join(self.option.aliases)) else: return '{0}{1}, {2}'.format(prefix, self.option.name, ', '.join(self.option.aliases)) else: if hasattr(self.option, 'arguments'): return '{0}{1} {2}'.format(prefix, self.option.name, self.option.arguments) else: return '{0}{1}'.format(prefix, self.option.name) else: return self.option.name def resolve_output_path(self, path): name_parts = self.option.name.split(',') if len(name_parts) > 1: clensed_name = name_parts[0] else: clensed_name = self.option.name fn = '-'.join([ self.option.directive, self.option.program, clensed_name ]) + '.rst' return os.path.join(path, fn) def render(self, path): self.option.replace() self.rst.directive(self.option.directive, self.resolve_option_name()) self.rst.newline() if self.option.type is not None: self.rst.content('*Type*: {0}'.format(self.option.type), indent=3) self.rst.newline() if self.option.default is not None: self.rst.content('*Default*: {0}'.format(self.option.default), indent=3) self.rst.newline() if self.option.pre is not None: self.rst.content(self.option.pre.split('\n'), indent=3, wrap=False) self.rst.newline() if self.option.description is not None: self.rst.content(self.option.description.split('\n'), indent=3, wrap=False) self.rst.newline() if self.option.post is not None: self.rst.content(self.option.post.split('\n'), indent=3, wrap=False) self.rst.newline() output_file = self.resolve_output_path(path) self.rst.write(output_file) logger.debug('wrote option to file {0}'.format(output_file))
def build_page(data, conf): fn = os.path.join(conf.paths.projectroot, conf.paths.includes, "metadata.yaml") if not os.path.exists(fn): return None else: iconf = BuildConfiguration(fn) r = RstCloth() r.title(iconf.title) r.newline() r.directive("default-domain", iconf.domain) r.newline() if "introduction" in iconf: r.content(iconf.introduction) r.newline() r.directive( name="contents", arg="Included Files", fields=[("backlinks", "none"), ("class", "long-toc"), ("depth", 1), ("local", "")], ) r.newline() data = data.items() data.sort() for _, record in data: page_name = r.pre(record["name"]) r.heading(text=page_name, char="-", indent=0) r.newline() r.heading("Meta", char="~", indent=0) r.newline() if record["num_clients"] == 0: r.content("{0} is not included in any files.".format(page_name)) r.newline() add_content(r, record) elif record["num_clients"] == 1: if record["yaml_only"]: r.content("{0} is only included in yaml files.".format(page_name)) r.newline() else: link = r.role("doc", record["clients"][0]) r.content("{0} is only included in {1}.".format(page_name, link)) r.newline() add_meta(r, page_name, record) add_content(r, record) else: r.content("{0} is included in **{1}** files.".format(page_name, record["num_clients"]), wrap=False) r.newline() add_meta(r, page_name, record) if record["yaml_only"] is False: clients = [p for p in record["clients"] if not p.startswith("/includes")] if len(clients) == 1: client_link = r.role("doc", clients[0]) inc_str = "{0} is the only file that includes {1} that is not also an include." r.content(inc_str.format(client_link, page_name)) r.newline() else: r.heading("Client Pages", char="~", indent=0) r.newline() for pg in clients: client_link = r.role("doc", pg) r.li(client_link, wrap=False) r.newline() add_include_example(r, page_name, record["path"]) add_content(r, record) return r