Esempio n. 1
0
def lightbox_directive(name, arguments, options, content, lineno,
                       content_offset, block_text, state, state_machine):
    """
    lightbox image directive

    usage:

    .. lightbox:: thumb_url img_url

        Title
    """
    classes = ["lightbox-img"]
    if 'align' in options:
        directives.choice(options['align'], align_values)

        if isinstance(state, states.SubstitutionDef):
            # Check for align_v_values.
            if options['align'] not in align_v_values:
                raise DirectiveError(
                    3, 'Error in "%s" directive: "%s" is not a valid value '
                    'for the "align" option within a substitution '
                    'definition.  Valid values for "align" are: "%s".' %
                    (name, options['align'], '", "'.join(align_v_values)))
        elif options['align'] not in align_h_values:
            raise DirectiveError(
                3, 'Error in "%s" directive: "%s" is not a valid value for '
                'the "align" option.  Valid values for "align" are: "%s".' %
                (name, options['align'], '", "'.join(align_h_values)))

        classes.append('align-%s' % options['align'])

    thumb_href = arguments[0]
    img_href = arguments[1]
    title = u" ".join(content)
    alt = options.get('alt', '')

    html = '<a title="%(title)s" rel="lightbox" href="%(img_href)s"><img %(classes)s src="%(thumb_href)s" title="%(title)s" alt="%(alt)s"/></a>' % {
        "classes": 'class="%s"' % " ".join(classes) if classes else "",
        "title": title,
        "img_href": img_href,
        "thumb_href": thumb_href,
        "alt": alt,
    }
    return [nodes.raw("", html, format="html")]
Esempio n. 2
0
    def run(self):

        from docutils.parsers.rst.directives.body import CodeBlock, NumberLines

        if not self.document.settings.file_insertion_enabled:
            raise DirectiveError(2,
                                 'Directive "{}" disabled.'.format(self.name))

        source_dir = Path(self.document["source"]).absolute().parent
        include_arg = "".join(
            [s.strip() for s in self.arguments[0].splitlines()])

        if include_arg.startswith("<") and include_arg.endswith(">"):
            # # docutils "standard" includes
            path = Path(self.klass.standard_include_path).joinpath(
                include_arg[1:-1])
        else:
            # if using sphinx interpret absolute paths "correctly",
            # i.e. relative to source directory
            try:
                sphinx_env = self.document.settings.env
                _, include_arg = sphinx_env.relfn2path(self.arguments[0])
                sphinx_env.note_included(include_arg)
            except AttributeError:
                pass
            path = Path(include_arg)
        path = source_dir.joinpath(path)

        # read file
        encoding = self.options.get("encoding",
                                    self.document.settings.input_encoding)
        error_handler = self.document.settings.input_encoding_error_handler
        # tab_width = self.options.get("tab-width", self.document.settings.tab_width)
        try:
            file_content = path.read_text(encoding=encoding,
                                          errors=error_handler)
        except Exception as error:
            raise DirectiveError(
                4,
                'Directive "{}": error reading file: {}\n{}.'.format(
                    self.name, path, error),
            )

        # get required section of text
        startline = self.options.get("start-line", None)
        endline = self.options.get("end-line", None)
        file_content = "\n".join(file_content.splitlines()[startline:endline])
        startline = startline or 0
        for split_on_type in ["start-after", "end-before"]:
            split_on = self.options.get(split_on_type, None)
            if not split_on:
                continue
            split_index = file_content.find(split_on)
            if split_index < 0:
                raise DirectiveError(
                    4,
                    'Directive "{}"; option "{}": text not found "{}".'.format(
                        self.name, split_on_type, split_on),
                )
            if split_on_type == "start-after":
                startline += split_index + len(split_on)
                file_content = file_content[split_index + len(split_on):]
            else:
                file_content = file_content[:split_index]

        if "literal" in self.options:
            literal_block = nodes.literal_block(file_content,
                                                source=str(path),
                                                classes=self.options.get(
                                                    "class", []))
            literal_block.line = 1  # TODO don;t think this should be 1?
            self.add_name(literal_block)
            if "number-lines" in self.options:
                try:
                    startline = int(self.options["number-lines"] or 1)
                except ValueError:
                    raise DirectiveError(
                        3, ":number-lines: with non-integer "
                        "start value")
                endline = startline + len(file_content.splitlines())
                if file_content.endswith("\n"):
                    file_content = file_content[:-1]
                tokens = NumberLines([([], file_content)], startline, endline)
                for classes, value in tokens:
                    if classes:
                        literal_block += nodes.inline(value,
                                                      value,
                                                      classes=classes)
                    else:
                        literal_block += nodes.Text(value)
            else:
                literal_block += nodes.Text(file_content)
            return [literal_block]
        if "code" in self.options:
            self.options["source"] = str(path)
            state_machine = MockStateMachine(self.renderer, self.lineno)
            state = MockState(self.renderer, state_machine, self.lineno)
            codeblock = CodeBlock(
                name=self.name,
                arguments=[self.options.pop("code")],
                options=self.options,
                content=file_content.splitlines(),
                lineno=self.lineno,
                content_offset=0,
                block_text=file_content,
                state=state,
                state_machine=state_machine,
            )
            return codeblock.run()

        # Here we perform a nested render, but temporarily setup the document/reporter
        # with the correct document path and lineno for the included file.
        source = self.renderer.document["source"]
        rsource = self.renderer.reporter.source
        line_func = getattr(self.renderer.reporter, "get_source_and_line",
                            None)
        try:
            self.renderer.document["source"] = str(path)
            self.renderer.reporter.source = str(path)
            self.renderer.reporter.get_source_and_line = lambda l: (str(path),
                                                                    l)
            self.renderer.nested_render_text(file_content, startline + 1)
        finally:
            self.renderer.document["source"] = source
            self.renderer.reporter.source = rsource
            if line_func is not None:
                self.renderer.reporter.get_source_and_line = line_func
            else:
                del self.renderer.reporter.get_source_and_line
        return []
Esempio n. 3
0
    def run(self, tag_cache={}):

        if not self.content:
            return []

        if self.arguments:
            arguments = self.arguments[0].strip().split(',')
        else:
            arguments = []

        tag_list_id = CURRENT_PLAN_ID or 'list'

        output = []; add = output.append
        tag_id = None

        for tag in arguments:

            if tag in tag_cache:
                add(tag_cache[tag])
                continue

            ori_tag = tag
            tag = tag.strip().rstrip(u',').strip()

            if not tag:
                continue

            if tag.startswith('id:'):
                tag_id = tag[3:]
                continue

            if tag.startswith('@'):
                tag_class = u'-'.join(tag[1:].lower().split())
                tag_type = 'zuser'
                tag_text = tag
            elif tag.startswith('#'):
                tag_class = u'-'.join(tag[1:].lower().split())
                tag_type = '2'
                tag_text = tag
            elif ':' in tag:
                tag_split = tag.split(':', 1)
                if len(tag_split) == 2:
                    tag_type, tag_text = tag_split
                else:
                    tag_type = tag_split[0]
                    tag_text = u""
                tag_type = tag_type.strip().lower()
                if tag_type == 'dep' and ':' not in tag_text:
                    tag_class = u'dep-%s-%s' % (CURRENT_PLAN_ID, tag_text)
                else:
                    tag_class = u'-'.join(tag.replace(':', ' ').lower().split())
            else:
                tag_class = u'-'.join(tag.lower().split())
                tag_type = '1'
                tag_text = tag.upper()

            if ':' in tag:
                lead = tag.split(':', 1)[0]
                tag_name = '%s:%s' % (lead.lower(), tag_text)
            else:
                tag_name = tag_text

            tag_span = (
                u'<span class="tag tag-type-%s tag-val-%s" tagname="%s" tagnorm="%s">%s</span> ' %
                (tag_type, tag_class, tag_name, tag.lower(), tag_text)
                )

            tag_cache[ori_tag] = tag_span
            add(tag_span)

        output.sort()

        if not tag_id:
            global TAG_COUNTER
            TAG_COUNTER = TAG_COUNTER + 1
            tag_id = 'temp-%s' % TAG_COUNTER

        tag_id = '%s-%s' % (tag_list_id, tag_id)

        if tag_id in SEEN_TAGS_CACHE:
            raise DirectiveError(2, "The tag id %r has already been used!" % tag_id)

        SEEN_TAGS_CACHE.add(tag_id)

        if not output:
            pass
            # add(u'<span class="tag tag-untagged"></span>')

        output.append(u'<a class="tag-link" href="#tag-ref-%s-main">&middot;</a>' % tag_id)
        output.insert(
            0, (u'<div class="tag-segment" id="tag-ref-%s">' % tag_id)
            )

        add(u'</div>')

        tag_info = nodes.raw('', u''.join(output), format='html')
        tag_content_container = nodes.bullet_list(
            ids=['tag-ref-%s-content' % tag_id]
            )

        tag_content = nodes.list_item()
        self.state.nested_parse(self.content, self.content_offset, tag_content)

        tag_content_container += tag_content

        prefix = nodes.raw('', u'<div id="tag-ref-%s-main" class="tag-content">' % tag_id, format='html')
        suffix = nodes.raw('', u'</div>', format='html')

        return [prefix, tag_content_container, tag_info, suffix]
Esempio n. 4
0
File: rst.py Progetto: tav/yatiblog
    def run(
        self, tag_cache={}, tag_normalised_cache={}, TODO=u'✗', DONE=u'✓',
        letters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -'
        ):

        if not self.content:
            return []

        if self.arguments:
            arguments = self.arguments[0].strip().split(',')
        else:
            arguments = []

        tag_list_id = CURRENT_PLAN_ID or 'list'

        output = []; add = output.append
        implicit_tags = {}
        tag_id = None

        def add_tag(
            ori_tag, tag_span, cache=tag_normalised_cache, add=add,
            implicit_tags=implicit_tags,
            done_tags=CURRENT_PLAN_SETTINGS.get('done', []),
            todo_tags=CURRENT_PLAN_SETTINGS.get('todo', []),
            ):
            add(tag_span)
            norm_tag = cache[ori_tag]
            if norm_tag in done_tags:
                implicit_tags['done'] = True
            if norm_tag in todo_tags:
                implicit_tags['todo'] = True

        for tag in arguments:

            if tag in tag_cache:
                add_tag(tag, tag_cache[tag])
                continue

            ori_tag = tag
            tag = tag.strip().rstrip(u',').strip()

            if not tag:
                continue

            if tag.startswith('id:'):
                tag_id = tag[3:]
                continue

            if tag.startswith('@'):
                tag_class = u'-'.join(tag[1:].lower().split())
                tag_type = 'zuser'
                tag_text = tag
            elif tag.startswith('#'):
                tag_class = u'-'.join(tag[1:].lower().split())
                tag_type = '2'
                tag_text = tag
            elif ':' in tag:
                tag_split = tag.split(':', 1)
                if len(tag_split) == 2:
                    tag_type, tag_text = tag_split
                else:
                    tag_type = tag_split[0]
                    tag_text = u""
                tag_type = tag_type.strip().lower()
                if tag_type == 'dep' and ':' not in tag_text:
                    tag_class = u'dep-%s-%s' % (CURRENT_PLAN_ID, tag_text)
                else:
                    tag_class = u'-'.join(tag.replace(':', ' ').lower().split())
            else:
                tag_class = u'-'.join(tag.lower().split())
                tag_type = '1'
                tag_text = tag.upper()

            if ':' in tag:
                lead = tag.split(':', 1)[0]
                tag_name = '%s:%s' % (lead.lower(), tag_text)
            else:
                tag_name = tag_text

            tag_span = (
                u'<span class="tag tag-type-%s tag-val-%s" tagname="%s" '
                 'tagnorm="%s">%s</span> ' %
                (tag_type, tag_class, tag_name, tag.lower(), tag_text)
                )

            tag_cache[ori_tag] = tag_span
            tag_normalised_cache[ori_tag] = tag_class
            add_tag(ori_tag, tag_span)

        content = u'\n'.join(self.content)
        if content.startswith(TODO):
            if self.content:
                self.content[0] = self.content[0].replace(TODO, u'*%s*' % TODO, 1)
            if 'todo' not in implicit_tags:
                add(
                    u'<span class="tag tag-type-1 tag-val-todo" '
                     'tagname="TODO" tagnorm="todo">TODO</span> '
                    )
        elif content.startswith(DONE):
            if self.content:
                self.content[0] = self.content[0].replace(DONE, u'*%s*' % DONE, 1)
            if 'done' not in implicit_tags:
                add(
                    u'<span class="tag tag-type-1 tag-val-done" '
                     'tagname="DONE" tagnorm="done">DONE</span> '
                    )

        output.sort()

        if not tag_id:
            tag_id = '-'.join(''.join([
                char for char in
                content.split('\n')[0].strip()[1:].strip()
                if char in letters
                ]).split()).lower()

        if not tag_id:
            global TAG_COUNTER
            TAG_COUNTER = TAG_COUNTER + 1
            tag_id = 'temp-%s' % TAG_COUNTER

        tag_id = 'planitem-%s' % tag_id

        if tag_id in SEEN_TAGS_CACHE:
            raise DirectiveError(2, "The tag id %r has already been used!" % tag_id)

        SEEN_TAGS_CACHE.add(tag_id)

        if not output:
            pass
            # add(u'<span class="tag tag-untagged"></span>')

        add(u'<a class="tag-link" href="#%s">#</a>' % tag_id)
        output.insert(
            0, (u'<div class="tag-segment" id="%s-tags">' % tag_id)
            )

        output.append(u'</div>')

        tag_info = nodes.raw('', u''.join(output), format='html')
        tag_content_container = nodes.container(
            ids=['%s-content' % tag_id]
            )

        self.state.nested_parse(
            self.content, self.content_offset, tag_content_container
            )

        prefix = nodes.raw(
            '', u'<div id="%s" class="tag-content">' % tag_id, format='html'
            )
        suffix = nodes.raw('', u'</div>', format='html')

        return [prefix, tag_content_container, tag_info, suffix]