Ejemplo n.º 1
0
class CodeBlock(Directive):
    """Parse and mark up content of a code block.

    Configuration setting: syntax_highlight
       Highlight Code content with Pygments?
       Possible values: ('long', 'short', 'none')

    """
    optional_arguments = 1
    option_spec = {'class': directives.class_option,
                   'name': directives.unchanged,
                   'number-lines': directives.unchanged # integer or None
                  }
    has_content = True

    def run(self):
        self.assert_has_content()
        if self.arguments:
            language = self.arguments[0]
        else:
            language = ''
        set_classes(self.options)
        classes = ['code']
        if language:
            classes.append(language)
        if 'classes' in self.options:
            classes.extend(self.options['classes'])

        # set up lexical analyzer
        try:
            tokens = Lexer(u'\n'.join(self.content), language,
                           self.state.document.settings.syntax_highlight)
        except LexerError, error:
            raise self.warning(error)

        if 'number-lines' in self.options:
            # optional argument `startline`, defaults to 1
            try:
                startline = int(self.options['number-lines'] or 1)
            except ValueError:
                raise self.error(':number-lines: with non-integer start value')
            endline = startline + len(self.content)
            # add linenumber filter:
            tokens = NumberLines(tokens, startline, endline)

        node = nodes.literal_block('\n'.join(self.content), classes=classes)
        self.add_name(node)
        # if called from "include", set the source
        if 'source' in self.options:
            node.attributes['source'] = self.options['source']
        # analyze content and add nodes for every token
        for classes, value in tokens:
            # print (classes, value)
            if classes:
                node += nodes.inline(value, value, classes=classes)
            else:
                # insert as Text to decrease the verbosity of the output
                node += nodes.Text(value, value)

        return [node]
Ejemplo n.º 2
0
    def run(self):
        self.assert_has_content()
        if self.arguments:
            language = self.arguments[0]
        else:
            language = ''
        set_classes(self.options)
        classes = ['code']
        if language:
            classes.append(language)
        if 'classes' in self.options:
            classes.extend(self.options['classes'])

        # set up lexical analyzer
        try:
            tokens = Lexer(u'\n'.join(self.content), language,
                           self.state.document.settings.syntax_highlight)
        except LexerError as error:
            if self.state.document.settings.report_level > 2:
                # don't report warnings -> insert without syntax highligt
                tokens = Lexer(u'\n'.join(self.content), language, 'none')
            else:
                raise self.warning(error)

        if 'number-lines' in self.options:
            # optional argument `startline`, defaults to 1
            try:
                startline = int(self.options['number-lines'] or 1)
            except ValueError:
                raise self.error(':number-lines: with non-integer start value')
            endline = startline + len(self.content)
            # add linenumber filter:
            tokens = NumberLines(tokens, startline, endline)

        node = nodes.literal_block('\n'.join(self.content), classes=classes)
        self.add_name(node)
        # if called from "include", set the source
        if 'source' in self.options:
            node.attributes['source'] = self.options['source']
        # analyze content and add nodes for every token
        for classes, value in tokens:
            if classes:
                node += nodes.inline(value, value, classes=classes)
            else:
                # insert as Text to decrease the verbosity of the output
                node += nodes.Text(value)

        return [node]
Ejemplo n.º 3
0
    def run(self):
        self.assert_has_content()
        if self.arguments:
            language = self.arguments[0]
        else:
            language = ""
        set_classes(self.options)
        classes = ["code"]
        if language:
            classes.append(language)
        if "classes" in self.options:
            classes.extend(self.options["classes"])

        # set up lexical analyzer
        try:
            tokens = Lexer(
                u"\n".join(self.content),
                language,
                self.state.document.settings.syntax_highlight,
            )
        except LexerError as error:
            raise self.warning(error)

        if "number-lines" in self.options:
            # optional argument `startline`, defaults to 1
            try:
                startline = int(self.options["number-lines"] or 1)
            except ValueError:
                raise self.error(":number-lines: with non-integer start value")
            endline = startline + len(self.content)
            # add linenumber filter:
            tokens = NumberLines(tokens, startline, endline)

        node = nodes.literal_block("\n".join(self.content), classes=classes)
        self.add_name(node)
        # if called from "include", set the source
        if "source" in self.options:
            node.attributes["source"] = self.options["source"]
        # analyze content and add nodes for every token
        for classes, value in tokens:
            if classes:
                node += nodes.inline(value, value, classes=classes)
            else:
                # insert as Text to decrease the verbosity of the output
                node += nodes.Text(value)

        return [node]
Ejemplo n.º 4
0
    def run(self):
        config = None
        meta_node = None
        settings_node = None
        global_caption = None
        show_source = True
        editor = self.options['editor'] if 'editor' in self.options else None
        self.assert_has_content()
        source = "\n".join(self.content)
        source_path = self.state_machine.document.settings._source.split(
            "doc/manual/", 1)[1]
        screenshot_dir = path.join(
            "doc", "manual",
            path.dirname(self.state_machine.document.settings._source).split(
                "doc/manual/", 1)[1], "_static")
        name = source_path[:-4].replace("/", "_")
        if not name in counters:
            counters[name] = 0
        else:
            counters[name] += 1
        design = "metal"

        visu_config_parts = self.config_parts.copy()
        try:
            # we need one surrouding element to prevent parse errors
            xml = etree.fromstring("<root>%s</root>" % source)
            for child in xml:
                if etree.iselement(child):

                    if child.tag == "settings":
                        # meta settings
                        settings_node = child
                    elif child.tag == "meta":
                        # config meta settings
                        meta_node = child
                    elif child.tag == "caption":
                        global_caption = child.text
                    else:
                        # the config example
                        config = child
        except Exception as e:
            print("Parse error: %s" % str(e))

        example_content = etree.tostring(config, encoding='utf-8')
        if meta_node is not None:
            example_content = b"...\n%s...\n%s" % (etree.tostring(
                meta_node, encoding='utf-8'), example_content)
            visu_config_parts['meta'] = etree.tostring(
                meta_node, encoding='utf-8').decode('utf-8')

        settings = {
            "selector": ".widget_container",
            "screenshots": [],
            "screenshotDir": screenshot_dir
        }
        if 'scale' in self.options:
            scale = max(1, min(100, int(self.options['scale'] or 100)))
            settings['scale'] = scale

        shot_index = 0
        if editor is not None:
            # change screenshot + selector
            settings['editor'] = editor
            settings['widget'] = config.tag
            if editor == "attributes":
                settings[
                    'selector'] = ".treeType_%s ul.attributes" % config.tag
            elif editor == "elements":
                settings['selector'] = ".treeType_%s" % config.tag
            settings['screenshots'].append({
                "name":
                "%s_editor_%s" % (name, editor),
                "data": {}
            })
            show_source = False

        elif settings_node is not None:
            # read meta settings
            design = settings_node.get("design", "metal")
            settings['selector'] = settings_node.get("selector",
                                                     ".widget_container")
            if settings_node.get("sleep"):
                settings['sleep'] = settings_node.get("sleep")

            for screenshot in settings_node.iter('screenshot'):
                shot = {
                    "name":
                    screenshot.get("name",
                                   name + str(counters[name] + shot_index)),
                    "data": []
                }
                if screenshot.get("sleep"):
                    shot['sleep'] = screenshot.get("sleep")
                if screenshot.get("clickpath", None):
                    shot['clickPath'] = screenshot.get('clickpath')
                if screenshot.get("waitfor", None):
                    shot['waitFor'] = screenshot.get('waitfor')

                shot_index += 1

                for data in screenshot.iter('data'):
                    values = {
                        'address': data.get("address", "0/0/0"),
                        'value': data.text
                    }
                    if data.get("type"):
                        values['type'] = data.get("type")

                    shot['data'].append(values)

                for caption in screenshot.iter('caption'):
                    if 'caption' not in shot:
                        shot['caption'] = caption.text
                    else:
                        shot['caption'] += caption.text

                settings['screenshots'].append(shot)

            for caption in settings_node.iterchildren('caption'):
                global_caption = caption.text

        # no screenshots defined, add a default one
        if len(settings['screenshots']) == 0:
            settings['screenshots'].append({"name": name + str(shot_index)})

        # replace the design value in the config
        visu_config_parts['start'] = visu_config_parts['start'].replace(
            "%%%DESIGN%%%", design)
        if config.tag == "page":
            visu_config_parts['content_start'] = ""
            visu_config_parts['content_end'] = ""

        # build the real config source
        visu_config = visu_config_parts['start'] + \
                      visu_config_parts['meta'] + \
                      visu_config_parts['content_start']  + \
                      etree.tostring(config, encoding='utf-8').decode('utf-8') + \
                      visu_config_parts['content_end'] + \
                      visu_config_parts['end']

        # validate generated config against XSD
        try:
            etree.fromstring(visu_config, parser)
        except etree.XMLSyntaxError as e:
            raise self.error(str(e))

        if not path.exists(self.example_dir):
            makedirs(self.example_dir)

        with open("%s_%s.xml" %
                  (path.join(self.example_dir, name), counters[name]),
                  encoding='utf-8',
                  mode="w") as f:
            f.write(u"%s\n%s" % (json.dumps(settings), visu_config))

        # create the code-block
        classes = ['code', 'xml']
        # set up lexical analyzer
        try:
            tokens = Lexer(example_content, 'xml',
                           self.state.document.settings.syntax_highlight)
        except LexerError as error:
            raise self.warning(error)

        if 'number-lines' in self.options:
            # optional argument `startline`, defaults to 1
            try:
                startline = int(self.options['number-lines'] or 1)
            except ValueError:
                raise self.error(':number-lines: with non-integer start value')
            endline = startline + len(self.content)
            # add linenumber filter:
            tokens = NumberLines(tokens, startline, endline)

        if 'hide-source' in self.options and show_source:
            show_source = self.options['hide-source'] != "true"

        res_nodes = []
        for shot in settings['screenshots']:

            reference = "_static/%s.png" % shot['name']
            options = dict(uri=reference)
            if 'caption' in shot:
                options['alt'] = shot['caption']

            image_node = nodes.image(rawsource=shot['name'], **options)
            figure_node = nodes.figure('', image_node)
            if 'align' in self.options:
                figure_node['align'] = self.options['align']

            if 'caption' in shot:
                self.add_caption(shot['caption'], figure_node)

            elif not show_source and global_caption and len(
                    settings['screenshots']) == 1:
                self.add_caption(global_caption, figure_node)

            res_nodes.append(figure_node)

        if show_source:
            example_content = example_content.decode('utf-8')
            node = nodes.literal_block(example_content, example_content)
            node['language'] = 'xml'
            node['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options
            node['classes'] += self.options.get('class', [])

            set_source_info(self, node)

            if global_caption:
                self.options.setdefault(
                    'name', nodes.fully_normalize_name(global_caption))
                node = container_wrapper(self, node, global_caption)
            self.add_name(node)
            res_nodes.append(node)

        return res_nodes