Beispiel #1
0
def render_steps(steps, conf):
    r = RstCloth()

    header_html = ('<div class="sequence-block">'
                   '<div class="bullet-block">'
                   '<div class="sequence-step">'
                   '{0}'
                   '</div>'
                   '</div>')

    for idx, step in enumerate(steps.steps):
        step.render() # run replacements

        if 'number' not in step:
            step.number = idx

        r.directive('only', 'html or dirhtml or singlehtml')
        r.newline()

        r.directive(name='raw',
                    arg='html',
                    content=header_html.format(step.number),
                    indent=3)
        r.newline()

        if 'heading' in step:
            r.heading(text=step.heading,
                      char=character_levels[step.level],
                      indent=3)
            r.newline()

        render_step_content(step, 3, r)

        r.directive(name='raw',
                    arg='html',
                    content="</div>",
                    indent=3)
        r.newline()

        r.directive('only', 'latex or epub')
        r.newline()


        if 'heading' in step:
            r.heading(text="Step {0}: {1}".format(step.number, step.heading),
                      char=character_levels[step.level],
                      indent=3)
            r.newline()
        else:
            r.heading(text="Step {0}".format(step.number),
                      char=character_levels[step.level],
                      indent=3)
            r.newline()

        render_step_content(step, 3, r)

    return r
Beispiel #2
0
def render_steps(steps, conf):
    r = RstCloth()

    header_html = ('<div class="sequence-block">'
                   '<div class="bullet-block">'
                   '<div class="sequence-step">'
                   '{0}'
                   '</div>'
                   '</div>')

    for idx, step in enumerate(steps.ordered_content()):
        step.render()  # run replacements

        if 'number' not in step:
            step.number = idx

        r.directive('only', 'html or dirhtml or singlehtml')
        r.newline()

        r.directive(name='raw',
                    arg='html',
                    content=header_html.format(step.number),
                    indent=3)
        r.newline()

        if 'heading' in step:
            r.heading(text=step.heading,
                      char=character_levels[step.level],
                      indent=3)
            r.newline()

        render_step_content(step, 3, r)

        r.directive(name='raw',
                    arg='html',
                    content="</div>",
                    indent=3)
        r.newline()

        r.directive('only', 'not(html or dirhtml or singlehtml)')
        r.newline()

        if 'heading' in step:
            r.heading(text="Step {0}: {1}".format(step.number, step.heading),
                      char=character_levels[step.level],
                      indent=3)
            r.newline()
        else:
            r.heading(text="Step {0}".format(step.number),
                      char=character_levels[step.level],
                      indent=3)
            r.newline()

        render_step_content(step, 3, r)

    return r
Beispiel #3
0
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):
        if not isinstance(steps, Steps):
            raise TypeError
        else:
            self.steps = steps

        self.conf = conf
        self.current_step = 1
        self.rst = RstCloth()
        self.hook()

    def hook(self):
        self.indent = 3

    def edition_check(self, step):
        return giza.content.helper.edition_check(step, self.conf)

    @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
Beispiel #4
0
class TestRstCloth(TestCase):
    @classmethod
    def setUp(self):
        self.r = RstCloth()

    def test_adding_without_blocks(self):
        self.r._add('foo')
        self.assertEqual(self.r.data[0], 'foo')

    def test_newline(self):
        self.r.newline()
        self.assertEqual(len(self.r.data), 1)

    def test_multi_newline(self):
        self.r.newline(count=4)
        self.assertEqual(len(self.r.data[0]), 4 - 1)

    def test_directive_simple(self):
        self.r.directive('test', block='d0')
        self.assertEqual(self.r.data[0], '.. test::')

    def test_directive_arg_named(self):
        self.r.directive('test', arg='what', block='d3')
        self.assertEqual(self.r.data[0], '.. test:: what')

    def test_directive_arg_positional(self):
        self.r.directive('test', 'what', block='d1')
        self.assertEqual(self.r.data[0], '.. test:: what')

    def test_directive_fields(self):
        self.r.directive('test', fields=[('a', 'b')], block='d2')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '   :a: b')

    def test_directive_fields_with_arg(self):
        self.r.directive('test', arg='what', fields=[('a', 'b')], block='d4')
        self.assertEqual(self.r.data[0], '.. test:: what')
        self.assertEqual(self.r.data[1], '   :a: b')

    def test_directive_fields_multiple(self):
        self.r.directive('test', fields=[('a', 'b'), ('c', 'd')], block='d5')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '   :a: b')
        self.assertEqual(self.r.data[2], '   :c: d')

    def test_directive_fields_multiple_arg(self):
        self.r.directive('test', arg='new', fields=[('a', 'b'), ('c', 'd')], block='d6')
        self.assertEqual(self.r.data[0], '.. test:: new')
        self.assertEqual(self.r.data[1], '   :a: b')
        self.assertEqual(self.r.data[2], '   :c: d')

    def test_directive_content(self):
        self.r.directive('test', content='string', block='d7')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '')
        self.assertEqual(self.r.data[2], '   string')

    def test_directive_with_multiline_content(self):
        self.r.directive('test', content=['string', 'second'], block='d8')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '')
        self.assertEqual(self.r.data[2], '   string')
        self.assertEqual(self.r.data[3], '   second')


    def test_directive_simple_indent(self):
        self.r.directive('test', indent=3, block='di0')
        self.assertEqual(self.r.data, ['   .. test::'])

    def test_directive_arg_named_indent(self):
        self.r.directive('test', arg='what', indent=3, block='di3')
        self.assertEqual(self.r.data, ['   .. test:: what'])

    def test_directive_arg_positional_indent(self):
        self.r.directive('test', 'what', indent=3, block='di1')
        self.assertEqual(self.r.data, ['   .. test:: what'])

    def test_directive_fields_indent(self):
        self.r.directive('test', fields=[('a', 'b')], indent=3, block='di2')
        self.assertEqual(self.r.data, ['   .. test::', '      :a: b'])

    def test_directive_fields_with_arg_indent(self):
        self.r.directive('test', arg='what', fields=[('a', 'b')], indent=3, block='di4')
        self.assertEqual(self.r.data, ['   .. test:: what', '      :a: b'])

    def test_directive_fields_multiple_indent(self):
        self.r.directive('test', indent=3, fields=[('a', 'b'), ('c', 'd')], block='di5')
        self.assertEqual(self.r.data, ['   .. test::', '      :a: b', '      :c: d'])

    def test_directive_fields_multiple_arg_indent(self):
        self.r.directive('test', arg='new', indent=3, fields=[('a', 'b'), ('c', 'd')], block='di6')
        self.assertEqual(self.r.data, ['   .. test:: new', '      :a: b', '      :c: d'])

    def test_directive_content_indent(self):
        self.r.directive('test', content='string', indent=3, block='di7')
        self.assertEqual(self.r.data, ['   .. test::', '   ', '      string'])

    def test_directive_with_multiline_content_indent(self):
        self.r.directive('test', indent=3, content=['string', 'second'], block='di8')
        self.assertEqual(self.r.data, ['   .. test::', '   ', '      string', '      second'])

    def test_single_role_no_text(self):
        ret = self.r.role('test', 'value')
        self.assertEqual(ret, ':test:`value`')

    def test_multi_role_no_text(self):
        ret = self.r.role(['test', 'role'], 'value')
        self.assertEqual(ret, ':test:role:`value`')

    def test_single_role_text(self):
        ret = self.r.role('test', 'value', 'link')
        self.assertEqual(ret, ':test:`link <value>`')

    def test_multi_role_text(self):
        ret = self.r.role(['test', 'role'], 'value', 'link')
        self.assertEqual(ret, ':test:role:`link <value>`')

    def test_single_role_no_text_args(self):
        ret = self.r.role(name='test', value='value')
        self.assertEqual(ret, ':test:`value`')

    def test_multi_role_no_text_args(self):
        ret = self.r.role(name=['test', 'role'], value='value')
        self.assertEqual(ret, ':test:role:`value`')

    def test_single_role_text_args(self):
        ret = self.r.role(name='test', value='value', text='link')
        self.assertEqual(ret, ':test:`link <value>`')

    def test_multi_role_text_args(self):
        ret = self.r.role(name=['test', 'role'], value='value', text='link')
        self.assertEqual(ret, ':test:role:`link <value>`')

    def test_bold(self):
        ret = self.r.bold('text')
        self.assertEqual(ret, '**text**')

    def test_emph(self):
        ret = self.r.emph('text')
        self.assertEqual(ret, '*text*')

    def test_pre(self):
        ret = self.r.pre('text')
        self.assertEqual(ret, '``text``')

    def test_inline_link(self):
        ret = self.r.inline_link('text', 'link')
        self.assertEqual(ret, '`text <link>`_')

    def test_footnote_ref(self):
        ret = self.r.footnote_ref('name')
        self.assertEqual(ret, '[#name]_')

    def test_codeblock_simple(self):
        self.r.codeblock('ls -lha', block='cb0')
        self.assertEqual(self.r.data, ['::', '   ls -lha'])

    def test_codeblock_with_language(self):
        self.r.codeblock('ls -lha', language='shell',block='cb1')
        self.assertEqual(self.r.data, ['.. code-block:: shell', '', '   ls -lha'])

    def test_footnote(self):
        self.r.footnote('footsnotes', 'text of the note', block='fn0')
        self.assertEqual(self.r.data[0], '.. [#footsnotes] text of the note')

    def test_footnote_with_indent(self):
        self.r.footnote('footsnotes', 'text of the note', block='fn1', indent=3)
        self.assertEqual(self.r.data[0], '   .. [#footsnotes] text of the note')

    def test_footnote_with_wrap(self):
        self.r.footnote('footsnotes', 'the ' * 40, block='fn2', wrap=True)
        self.assertEqual(self.r.data[0],
                         '.. [#footsnotes]' + ' the' * 14 + '\n  ' + ' the' * 17 + '\n  ' + ' the' * 9)

    def test_definition(self):
        self.r.definition('defitem', 'this is def text', block='dfn0')
        self.assertEqual(self.r.data, ['defitem', '   this is def text'])

    def test_definition_with_indent(self):
        self.r.definition('defitem', 'this is def text', indent=3, block='dfn1')
        self.assertEqual(self.r.data, ['   defitem', '      this is def text'])

    def test_title_default(self):
        self.r.title('test text', block='hd0')
        self.assertEqual(self.r.data, ['=========', 'test text', '========='])

    def test_title_alt(self):
        self.r.title('test text', char='-', block='hd1')
        self.assertEqual(self.r.data, ['---------', 'test text', '---------'])

    def test_heading_one(self):
        self.r.heading('test heading', char='-', indent=0, block='hd2')
        self.assertEqual(self.r.data, ['test heading', '------------'])

    def test_heading_two(self):
        self.r.heading('test heading', char='^', indent=0, block='hd3')
        self.assertEqual(self.r.data, ['test heading', '^^^^^^^^^^^^'])

    def test_h1(self):
        self.r.h1('test', block='hd4')
        self.assertEqual(self.r.data, ['test', '===='])

    def test_h2(self):
        self.r.h2('test', block='hd5')
        self.assertEqual(self.r.data, ['test', '----'])

    def test_h3(self):
        self.r.h3('test', block='hd6')
        self.assertEqual(self.r.data, ['test', '~~~~'])

    def test_h4(self):
        self.r.h4('test', block='hd7')
        self.assertEqual(self.r.data, ['test', '++++'])

    def test_h5(self):
        self.r.h5('test', block='hd8')
        self.assertEqual(self.r.data, ['test', '^^^^'])

    def test_h6(self):
        self.r.h6('test', block='hd9')
        self.assertEqual(self.r.data, ['test', ';;;;'])

    def test_replacement(self):
        self.r.replacement('foo', 'replace-with-bar', block='sub0')
        self.assertEqual(self.r.data, ['.. |foo| replace:: replace-with-bar'])

    def test_replacement_with_indent(self):
        self.r.replacement('foo', 'replace-with-bar', indent=3, block='sub1')
        self.assertEqual(self.r.data, ['   .. |foo| replace:: replace-with-bar'])

    def test_li_simple(self):
        self.r.li('foo', block='li0')
        self.assertEqual(self.r.data, ['- foo'])

    def test_li_simple_indent(self):
        self.r.li('foo', indent=3, block='li1')
        self.assertEqual(self.r.data, ['   - foo'])

    def test_li_simple_alt(self):
        self.r.li('foo', bullet='*', block='li2')
        self.assertEqual(self.r.data, ['* foo'])

    def test_li_simple_alt_indent(self):
        self.r.li('foo', bullet='*', indent=3, block='li3')
        self.assertEqual(self.r.data, ['   * foo'])

    def test_li_complex(self):
        self.r.li(['foo', 'bar'], block='li0')
        self.assertEqual(self.r.data, ['- foo bar'])

    def test_li_complex_indent(self):
        self.r.li(['foo', 'bar'], indent=3, block='li1')
        self.assertEqual(self.r.data, ['   - foo bar'])

    def test_li_complex_alt(self):
        self.r.li(['foo', 'bar'], bullet='*', block='li2')
        self.assertEqual(self.r.data, ['* foo bar'])

    def test_li_complex_alt_indent(self):
        self.r.li(['foo', 'bar'], bullet='*', indent=3, block='li3')
        self.assertEqual(self.r.data, ['   * foo bar'])

    def test_field_simple(self):
        self.r.field('fname', 'fvalue', block='fld0')
        self.assertEqual(self.r.data, [':fname: fvalue'])

    def test_field_long_simple(self):
        self.r.field('fname is fname', 'fvalue', block='fld1')
        self.assertEqual(self.r.data, [':fname is fname: fvalue'])

    def test_field_simple_long(self):
        self.r.field('fname', 'v' * 54, block='fld2')
        self.assertEqual(self.r.data, [':fname: ' + 'v' * 54])

    def test_field_simple_long_long(self):
        self.r.field('fname', 'v' * 55, block='fld3')
        self.assertEqual(self.r.data, [':fname:', '', '   ' + 'v' * 55])

    def test_field_indent_simple(self):
        self.r.field('fname', 'fvalue', indent=3, block='fld4')
        self.assertEqual(self.r.data, ['   :fname: fvalue'])

    def test_field_indent_long_simple(self):
        self.r.field('fname is fname', 'fvalue', indent=3, block='fld5')
        self.assertEqual(self.r.data, ['   :fname is fname: fvalue'])

    def test_field_indent_simple_long(self):
        self.r.field('fname', 'v' * 54, indent=3, block='fld6')
        self.assertEqual(self.r.data, ['   :fname: ' + 'v' * 54])

    def test_field_indent_simple_long_long(self):
        self.r.field('fname', 'v' * 55, indent=3, block='fld7')
        self.assertEqual(self.r.data, ['   :fname:', '   ', '      ' + 'v' * 55])

    def test_field_wrap_simple(self):
        self.r.field('fname', 'the ' * 100, block='fld8')
        self.assertEqual(self.r.data, [':fname:', '', '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 10])

    def test_field_wrap_indent_simple(self):
        self.r.field('fname', 'the ' * 100, indent=3, block='fld8')
        self.assertEqual(self.r.data, ['   :fname:', '   ', '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 10])

    def test_content_string(self):
        self.r.content('this is sparta', block='ct0')
        self.assertEqual(self.r.data, ['this is sparta'])

    def test_content_list(self):
        self.r.content(['this is sparta', 'this is spinal tap'], block='ct1')
        self.assertEqual(self.r.data, ['this is sparta', 'this is spinal tap'])

    def test_content_indent_string(self):
        self.r.content('this is sparta', indent=3, block='ct2')
        self.assertEqual(self.r.data, ['   this is sparta'])

    def test_content_indent_list(self):
        self.r.content(['this is sparta', 'this is spinal tap'], indent=3, block='ct3')
        self.assertEqual(self.r.data, ['   this is sparta', '   this is spinal tap'])

    def test_content_long(self):
        self.r.content('the ' * 100, block='ct4')
        self.assertEqual(self.r.data, [ 'the' + ' the' * 17, 'the ' * 17 + 'the', 'the ' * 17 + 'the', 'the ' * 17 + 'the', 'the ' * 17 + 'the', 'the ' * 9 + 'the' ])

    def test_ontent_indent_long(self):
        self.r.content('the ' * 100, indent=3 ,block='ct5')
        self.assertEqual(self.r.data, [ '   the' + ' the' * 17, "   " + 'the ' * 17 + 'the', '   ' + 'the ' * 17 + 'the', '   ' + 'the ' * 17 + 'the', '   ' + 'the ' * 17 + 'the', '   ' + 'the ' * 9 + 'the' ])

    def test_ontent_indent_long_nowrap(self):
        self.r.content('the ' * 100, wrap=False, indent=3 ,block='ct5')
        self.assertEqual(self.r.data, [ '   ' + 'the ' * 99 + 'the'])

    def test_ref_target_named(self):
        self.r.ref_target(name="foo-are-magic-ref0", block='ref0')
        self.assertEqual(self.r.data, ['.. _foo-are-magic-ref0:'])

    def test_ref_target_unnamed(self):
        self.r.ref_target("foo-are-magic-ref1", block='ref1')
        self.assertEqual(self.r.data, ['.. _foo-are-magic-ref1:'])

    def test_ref_target_named_with_indent(self):
        self.r.ref_target(name="foo-are-magic-ref2", indent=3, block='ref2')
        self.assertEqual(self.r.data, ['   .. _foo-are-magic-ref2:'])

    def test_ref_target_unnamed_wo_indent(self):
        self.r.ref_target("foo-are-magic-ref3", 3, block='ref3')
        self.assertEqual(self.r.data, ['   .. _foo-are-magic-ref3:'])
Beispiel #5
0
def build_page(data, conf):
    if 'includes' not in conf.system.files.data:
        return
    else:
        iconf = conf.system.files.data.includes

    r = RstCloth()

    r.title(iconf['title'])
    r.newline()
    r.directive('default-domain', iconf['domain'])
    r.newline()

    try:
        r.content(iconf['introduction'])
        r.newline()
    except KeyError:
        logger.debug('include meta file lacks an introduction.')

    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
Beispiel #6
0
def build_page(data, conf):
    if 'includes' not in conf.system.files.data:
        return
    else:
        iconf = conf.system.files.data.includes

    r = RstCloth()

    r.title(iconf['title'])
    r.newline()
    r.directive('default-domain', iconf['domain'])
    r.newline()

    try:
        r.content(iconf['introduction'])
        r.newline()
    except KeyError:
        logger.debug('include meta file lacks an introduction.')

    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
Beispiel #7
0
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):
        if not isinstance(steps, Steps):
            raise TypeError
        else:
            self.steps = steps

        self.conf = conf
        self.current_step = 1
        self.rst = RstCloth()
        self.hook()

    def hook(self):
        self.indent = 3

    def edition_check(self, step):
        return giza.content.helper.edition_check(step, self.conf)

    @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
Beispiel #8
0
class TestRstCloth(TestCase):
    @classmethod
    def setUp(self):
        self.r = RstCloth()

    def test_adding_without_blocks(self):
        self.r._add('foo')
        self.assertEqual(self.r.data[0], 'foo')

    def test_newline(self):
        self.r.newline()
        self.assertEqual(len(self.r.data), 1)

    def test_multi_newline(self):
        self.r.newline(count=4)
        self.assertEqual(len(self.r.data[0]), 4 - 1)

    def test_directive_simple(self):
        self.r.directive('test', block='d0')
        self.assertEqual(self.r.data[0], '.. test::')

    def test_directive_arg_named(self):
        self.r.directive('test', arg='what', block='d3')
        self.assertEqual(self.r.data[0], '.. test:: what')

    def test_directive_arg_positional(self):
        self.r.directive('test', 'what', block='d1')
        self.assertEqual(self.r.data[0], '.. test:: what')

    def test_directive_fields(self):
        self.r.directive('test', fields=[('a', 'b')], block='d2')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '   :a: b')

    def test_directive_fields_with_arg(self):
        self.r.directive('test', arg='what', fields=[('a', 'b')], block='d4')
        self.assertEqual(self.r.data[0], '.. test:: what')
        self.assertEqual(self.r.data[1], '   :a: b')

    def test_directive_fields_multiple(self):
        self.r.directive('test', fields=[('a', 'b'), ('c', 'd')], block='d5')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '   :a: b')
        self.assertEqual(self.r.data[2], '   :c: d')

    def test_directive_fields_multiple_arg(self):
        self.r.directive('test', arg='new', fields=[('a', 'b'), ('c', 'd')], block='d6')
        self.assertEqual(self.r.data[0], '.. test:: new')
        self.assertEqual(self.r.data[1], '   :a: b')
        self.assertEqual(self.r.data[2], '   :c: d')

    def test_directive_content(self):
        self.r.directive('test', content='string', block='d7')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '')
        self.assertEqual(self.r.data[2], '   string')

    def test_directive_with_multiline_content(self):
        self.r.directive('test', content=['string', 'second'], block='d8')
        self.assertEqual(self.r.data[0], '.. test::')
        self.assertEqual(self.r.data[1], '')
        self.assertEqual(self.r.data[2], '   string')
        self.assertEqual(self.r.data[3], '   second')


    def test_directive_simple_indent(self):
        self.r.directive('test', indent=3, block='di0')
        self.assertEqual(self.r.data, ['   .. test::'])

    def test_directive_arg_named_indent(self):
        self.r.directive('test', arg='what', indent=3, block='di3')
        self.assertEqual(self.r.data, ['   .. test:: what'])

    def test_directive_arg_positional_indent(self):
        self.r.directive('test', 'what', indent=3, block='di1')
        self.assertEqual(self.r.data, ['   .. test:: what'])

    def test_directive_fields_indent(self):
        self.r.directive('test', fields=[('a', 'b')], indent=3, block='di2')
        self.assertEqual(self.r.data, ['   .. test::', '      :a: b'])

    def test_directive_fields_with_arg_indent(self):
        self.r.directive('test', arg='what', fields=[('a', 'b')], indent=3, block='di4')
        self.assertEqual(self.r.data, ['   .. test:: what', '      :a: b'])

    def test_directive_fields_multiple_indent(self):
        self.r.directive('test', indent=3, fields=[('a', 'b'), ('c', 'd')], block='di5')
        self.assertEqual(self.r.data, ['   .. test::', '      :a: b', '      :c: d'])

    def test_directive_fields_multiple_arg_indent(self):
        self.r.directive('test', arg='new', indent=3, fields=[('a', 'b'), ('c', 'd')], block='di6')
        self.assertEqual(self.r.data, ['   .. test:: new', '      :a: b', '      :c: d'])

    def test_directive_content_indent(self):
        self.r.directive('test', content='string', indent=3, block='di7')
        self.assertEqual(self.r.data, ['   .. test::', '   ', '      string'])

    def test_directive_with_multiline_content_indent(self):
        self.r.directive('test', indent=3, content=['string', 'second'], block='di8')
        self.assertEqual(self.r.data, ['   .. test::', '   ', '      string', '      second'])

    def test_single_role_no_text(self):
        ret = self.r.role('test', 'value')
        self.assertEqual(ret, ':test:`value`')

    def test_multi_role_no_text(self):
        ret = self.r.role(['test', 'role'], 'value')
        self.assertEqual(ret, ':test:role:`value`')

    def test_single_role_text(self):
        ret = self.r.role('test', 'value', 'link')
        self.assertEqual(ret, ':test:`link <value>`')

    def test_multi_role_text(self):
        ret = self.r.role(['test', 'role'], 'value', 'link')
        self.assertEqual(ret, ':test:role:`link <value>`')

    def test_single_role_no_text_args(self):
        ret = self.r.role(name='test', value='value')
        self.assertEqual(ret, ':test:`value`')

    def test_multi_role_no_text_args(self):
        ret = self.r.role(name=['test', 'role'], value='value')
        self.assertEqual(ret, ':test:role:`value`')

    def test_single_role_text_args(self):
        ret = self.r.role(name='test', value='value', text='link')
        self.assertEqual(ret, ':test:`link <value>`')

    def test_multi_role_text_args(self):
        ret = self.r.role(name=['test', 'role'], value='value', text='link')
        self.assertEqual(ret, ':test:role:`link <value>`')

    def test_bold(self):
        ret = self.r.bold('text')
        self.assertEqual(ret, '**text**')

    def test_emph(self):
        ret = self.r.emph('text')
        self.assertEqual(ret, '*text*')

    def test_pre(self):
        ret = self.r.pre('text')
        self.assertEqual(ret, '``text``')

    def test_inline_link(self):
        ret = self.r.inline_link('text', 'link')
        self.assertEqual(ret, '`text <link>`_')

    def test_footnote_ref(self):
        ret = self.r.footnote_ref('name')
        self.assertEqual(ret, '[#name]')

    def test_codeblock_simple(self):
        self.r.codeblock('ls -lha', block='cb0')
        self.assertEqual(self.r.data, ['::', '   ls -lha'])

    def test_codeblock_with_language(self):
        self.r.codeblock('ls -lha', language='shell',block='cb1')
        self.assertEqual(self.r.data, ['.. code-block:: shell', '', '   ls -lha'])

    def test_footnote(self):
        self.r.footnote('footsnotes', 'text of the note', block='fn0')
        self.assertEqual(self.r.data[0], '.. [#footsnotes] text of the note')

    def test_footnote_with_indent(self):
        self.r.footnote('footsnotes', 'text of the note', block='fn1', indent=3)
        self.assertEqual(self.r.data[0], '   .. [#footsnotes] text of the note')

    def test_footnote_with_wrap(self):
        self.r.footnote('footsnotes', 'the ' * 40, block='fn2', wrap=True)
        self.assertEqual(self.r.data[0],
                         '.. [#footsnotes]' + ' the' * 14 + '\n  ' + ' the' * 17 + '\n  ' + ' the' * 9)

    def test_definition(self):
        self.r.definition('defitem', 'this is def text', block='dfn0')
        self.assertEqual(self.r.data, ['defitem', '   this is def text'])

    def test_definition_with_indent(self):
        self.r.definition('defitem', 'this is def text', indent=3, block='dfn1')
        self.assertEqual(self.r.data, ['   defitem', '      this is def text'])

    def test_title_default(self):
        self.r.title('test text', block='hd0')
        self.assertEqual(self.r.data, ['=========', 'test text', '========='])

    def test_title_alt(self):
        self.r.title('test text', char='-', block='hd1')
        self.assertEqual(self.r.data, ['---------', 'test text', '---------'])

    def test_heading_one(self):
        self.r.heading('test heading', char='-', indent=0, block='hd2')
        self.assertEqual(self.r.data, ['test heading', '------------'])

    def test_heading_two(self):
        self.r.heading('test heading', char='^', indent=0, block='hd3')
        self.assertEqual(self.r.data, ['test heading', '^^^^^^^^^^^^'])

    def test_h1(self):
        self.r.h1('test', block='hd4')
        self.assertEqual(self.r.data, ['test', '===='])

    def test_h2(self):
        self.r.h2('test', block='hd5')
        self.assertEqual(self.r.data, ['test', '----'])

    def test_h3(self):
        self.r.h3('test', block='hd6')
        self.assertEqual(self.r.data, ['test', '~~~~'])

    def test_h4(self):
        self.r.h4('test', block='hd7')
        self.assertEqual(self.r.data, ['test', '++++'])

    def test_h5(self):
        self.r.h5('test', block='hd8')
        self.assertEqual(self.r.data, ['test', '^^^^'])

    def test_h6(self):
        self.r.h6('test', block='hd9')
        self.assertEqual(self.r.data, ['test', ';;;;'])

    def test_replacement(self):
        self.r.replacement('foo', 'replace-with-bar', block='sub0')
        self.assertEqual(self.r.data, ['.. |foo| replace:: replace-with-bar'])

    def test_replacement_with_indent(self):
        self.r.replacement('foo', 'replace-with-bar', indent=3, block='sub1')
        self.assertEqual(self.r.data, ['   .. |foo| replace:: replace-with-bar'])

    def test_li_simple(self):
        self.r.li('foo', block='li0')
        self.assertEqual(self.r.data, ['- foo'])

    def test_li_simple_indent(self):
        self.r.li('foo', indent=3, block='li1')
        self.assertEqual(self.r.data, ['   - foo'])

    def test_li_simple_alt(self):
        self.r.li('foo', bullet='*', block='li2')
        self.assertEqual(self.r.data, ['* foo'])

    def test_li_simple_alt_indent(self):
        self.r.li('foo', bullet='*', indent=3, block='li3')
        self.assertEqual(self.r.data, ['   * foo'])

    def test_li_complex(self):
        self.r.li(['foo', 'bar'], block='li0')
        self.assertEqual(self.r.data, ['- foo bar'])

    def test_li_complex_indent(self):
        self.r.li(['foo', 'bar'], indent=3, block='li1')
        self.assertEqual(self.r.data, ['   - foo bar'])

    def test_li_complex_alt(self):
        self.r.li(['foo', 'bar'], bullet='*', block='li2')
        self.assertEqual(self.r.data, ['* foo bar'])

    def test_li_complex_alt_indent(self):
        self.r.li(['foo', 'bar'], bullet='*', indent=3, block='li3')
        self.assertEqual(self.r.data, ['   * foo bar'])

    def test_field_simple(self):
        self.r.field('fname', 'fvalue', block='fld0')
        self.assertEqual(self.r.data, [':fname: fvalue'])

    def test_field_long_simple(self):
        self.r.field('fname is fname', 'fvalue', block='fld1')
        self.assertEqual(self.r.data, [':fname is fname: fvalue'])

    def test_field_simple_long(self):
        self.r.field('fname', 'v' * 54, block='fld2')
        self.assertEqual(self.r.data, [':fname: ' + 'v' * 54])

    def test_field_simple_long_long(self):
        self.r.field('fname', 'v' * 55, block='fld3')
        self.assertEqual(self.r.data, [':fname:', '', '   ' + 'v' * 55])

    def test_field_indent_simple(self):
        self.r.field('fname', 'fvalue', indent=3, block='fld4')
        self.assertEqual(self.r.data, ['   :fname: fvalue'])

    def test_field_indent_long_simple(self):
        self.r.field('fname is fname', 'fvalue', indent=3, block='fld5')
        self.assertEqual(self.r.data, ['   :fname is fname: fvalue'])

    def test_field_indent_simple_long(self):
        self.r.field('fname', 'v' * 54, indent=3, block='fld6')
        self.assertEqual(self.r.data, ['   :fname: ' + 'v' * 54])

    def test_field_indent_simple_long_long(self):
        self.r.field('fname', 'v' * 55, indent=3, block='fld7')
        self.assertEqual(self.r.data, ['   :fname:', '   ', '      ' + 'v' * 55])

    def test_field_wrap_simple(self):
        self.r.field('fname', 'the ' * 100, block='fld8')
        self.assertEqual(self.r.data, [':fname:', '', '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 18, '  ' + ' the' * 10])

    def test_field_wrap_indent_simple(self):
        self.r.field('fname', 'the ' * 100, indent=3, block='fld8')
        self.assertEqual(self.r.data, ['   :fname:', '   ', '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 18, '     ' + ' the' * 10])

    def test_content_string(self):
        self.r.content('this is sparta', block='ct0')
        self.assertEqual(self.r.data, ['this is sparta'])

    def test_content_list(self):
        self.r.content(['this is sparta', 'this is spinal tap'], block='ct1')
        self.assertEqual(self.r.data, ['this is sparta', 'this is spinal tap'])

    def test_content_indent_string(self):
        self.r.content('this is sparta', indent=3, block='ct2')
        self.assertEqual(self.r.data, ['   this is sparta'])

    def test_content_indent_list(self):
        self.r.content(['this is sparta', 'this is spinal tap'], indent=3, block='ct3')
        self.assertEqual(self.r.data, ['   this is sparta', '   this is spinal tap'])

    def test_content_long(self):
        self.r.content('the ' * 100, block='ct4')
        self.assertEqual(self.r.data, [ 'the' + ' the' * 17, 'the ' * 17 + 'the', 'the ' * 17 + 'the', 'the ' * 17 + 'the', 'the ' * 17 + 'the', 'the ' * 9 + 'the' ])

    def test_ontent_indent_long(self):
        self.r.content('the ' * 100, indent=3 ,block='ct5')
        self.assertEqual(self.r.data, [ '   the' + ' the' * 17, "   " + 'the ' * 17 + 'the', '   ' + 'the ' * 17 + 'the', '   ' + 'the ' * 17 + 'the', '   ' + 'the ' * 17 + 'the', '   ' + 'the ' * 9 + 'the' ])

    def test_ontent_indent_long_nowrap(self):
        self.r.content('the ' * 100, wrap=False, indent=3 ,block='ct5')
        self.assertEqual(self.r.data, [ '   ' + 'the ' * 99 + 'the'])

    def test_ref_target_named(self):
        self.r.ref_target(name="foo-are-magic-ref0", block='ref0')
        self.assertEqual(self.r.data, ['.. _foo-are-magic-ref0:'])

    def test_ref_target_unnamed(self):
        self.r.ref_target("foo-are-magic-ref1", block='ref1')
        self.assertEqual(self.r.data, ['.. _foo-are-magic-ref1:'])

    def test_ref_target_named_with_indent(self):
        self.r.ref_target(name="foo-are-magic-ref2", indent=3, block='ref2')
        self.assertEqual(self.r.data, ['   .. _foo-are-magic-ref2:'])

    def test_ref_target_unnamed_wo_indent(self):
        self.r.ref_target("foo-are-magic-ref3", 3, block='ref3')
        self.assertEqual(self.r.data, ['   .. _foo-are-magic-ref3:'])