Exemple #1
0
 def __init__(self, raw_text, element, meta=None):
     self.raw_text = raw_text
     self.element = element
     if meta:
         self.meta = Expando(meta)
     else:
         self.meta = Expando({})
Exemple #2
0
    def test_plugin_node_filters_begin_text_resource(self):
        def empty_return(*args, **kwargs):
            return None

        with patch.object(ConstantReturnPlugin,
                          'begin_text_resource',
                          new=Mock(wraps=empty_return)) as mock1:
            with patch.object(NoReturnPlugin,
                              'begin_text_resource',
                              new=Mock(wraps=empty_return)) as mock2:
                self.site.config.plugins = [
                    'hyde.tests.test_plugin.ConstantReturnPlugin',
                    'hyde.tests.test_plugin.NoReturnPlugin'
                ]
                self.site.config.constantreturn = Expando(
                    dict(include_paths="media"))
                self.site.config.noreturn = Expando(
                    dict(include_file_pattern="*.html",
                         include_paths=["blog"]))
                gen = Generator(self.site)
                gen.generate_all()
                mock1_args = sorted(
                    set([arg[0][0].name for arg in mock1.call_args_list]))
                mock2_args = sorted(
                    set([arg[0][0].name for arg in mock2.call_args_list]))
                assert len(mock1_args) == 1
                assert len(mock2_args) == 1
                assert mock1_args == ["site.css"]
                assert mock2_args == ["merry-christmas.html"]
Exemple #3
0
    def test_plugin_filters_begin_text_resource(self):
        def empty_return(self, resource, text=''):
            return text

        with patch.object(ConstantReturnPlugin,
                          'begin_text_resource',
                          new=Mock(wraps=empty_return)) as mock1:
            with patch.object(NoReturnPlugin,
                              'begin_text_resource',
                              new=Mock(wraps=empty_return)) as mock2:
                self.site.config.plugins = [
                    'hyde.tests.test_plugin.ConstantReturnPlugin',
                    'hyde.tests.test_plugin.NoReturnPlugin'
                ]
                self.site.config.constantreturn = Expando(
                    dict(include_file_pattern="*.css"))
                self.site.config.noreturn = Expando(
                    dict(include_file_pattern=["*.html", "*.txt"]))
                gen = Generator(self.site)
                gen.generate_all()
                mock1_args = sorted(
                    set([arg[0][0].name for arg in mock1.call_args_list]))
                mock2_args = sorted(
                    set([arg[0][0].name for arg in mock2.call_args_list]))
                assert len(mock1_args) == 1
                assert len(mock2_args) == 4
                assert mock1_args == ["site.css"]
                assert mock2_args == [
                    "404.html", "about.html", "merry-christmas.html",
                    "robots.txt"
                ]
Exemple #4
0
    def _parse_raw_text(self):
        '''
        find the meta data and text
        '''
        # first, find yaml matter,
        # assuming only the bottom '---' to save space
        idx_ym = self.raw_text.find(YAML_FINDER, len(YAML_FINDER))
        if idx_ym > 0:
            ym = self.raw_text[:idx_ym - 1]
        else:
            ym = ''

        # make the meta dict
        meta = Expando(yaml.load(ym))
        if not meta:
            # if meta is None, make is a dict
            meta = Expando({})
        elif isinstance(self.meta, str):
            # if meta ends up as a string, assume it's empty
            meta = Expando({})
            idx_ym = -1

        # if a meta collision occurs, the yaml-matter is prefered
        # except in the case of 'class', which appends it to the existing version
        try:
            old_class = getattr(self.meta, "class")
            new_class = old_class + " " + getattr(meta, "class")
            setattr(self.meta, "class", new_class)
            delattr(meta, "class")
        except AttributeError:
            pass
        self.meta.update(meta)

        # attempt to enumerate class and id, if possible
        try:
            setattr(self.meta, "id", self.meta.id % self.idx)
        except (AttributeError, TypeError):
            pass
        try:
            setattr(self.meta, "class", getattr(self.meta, "class") % self.idx)
        except (AttributeError, TypeError):
            pass

        # now find the standard text
        if idx_ym > 0:
            self.slide_text = self.raw_text[idx_ym + len(YAML_FINDER):]
        else:
            self.slide_text = self.raw_text
Exemple #5
0
def test_expando_update():
    d1 = {"a": 123, "b": "abc"}
    x = Expando(d1)
    assert x.a == d1['a']
    assert x.b == d1['b']
    d = {"b": {"c": 456, "d": {"e": "abc"}}, "f": "lmn"}
    x.update(d)
    assert  x.a == d1['a']
    assert x.b.c == d['b']['c']
    assert x.b.d.e == d['b']['d']['e']
    assert x.f == d["f"]
    d2 = {"a": 789, "f": "opq"}
    y = Expando(d2)
    x.update(y)
    assert x.a == 789
    assert x.f == "opq"
Exemple #6
0
    def test_can_compress_with_stylus(self):
        s = Site(TEST_SITE)
        s.config.mode = "production"
        s.config.plugins = ['hyde.ext.plugins.stylus.StylusPlugin']
        paths = [
            '/usr/local/share/npm/bin/stylus', '~/local/bin/stylus',
            '~/bin/stylus'
        ]
        stylus = [path for path in paths if File(path).exists]
        if not stylus:
            assert False, "Cannot find the stylus executable"

        stylus = stylus[0]
        s.config.stylus = Expando(dict(app=stylus))
        source = TEST_SITE.child('content/media/css/site.styl')
        target = File(
            Folder(s.config.deploy_root_path).child('media/css/site.css'))
        gen = Generator(s)
        gen.generate_resource_at_path(source)

        assert target.exists
        text = target.read_all()
        expected_text = File(
            STYLUS_SOURCE.child('expected-site-compressed.css')).read_all()
        assert text.strip() == expected_text.strip()
Exemple #7
0
def syntax(env, value, lexer=None, filename=None):
    """
    Processes the contained block using `pygments`
    """
    try:
        import pygments
        from pygments import lexers
        from pygments import formatters
    except ImportError:
        logger.error(u"pygments library is required to"
                     " use syntax highlighting tags.")
        raise TemplateError("Cannot load pygments")

    pyg = (lexers.get_lexer_by_name(lexer)
           if lexer else lexers.guess_lexer(value))
    settings = {}
    if hasattr(env.config, 'syntax'):
        settings = getattr(env.config.syntax, 'options', Expando({})).to_dict()

    formatter = formatters.HtmlFormatter(**settings)
    code = pygments.highlight(value, pyg, formatter)
    code = code.replace('\n\n', '\n&nbsp;\n').replace('\n', '<br />')
    caption = filename if filename else pyg.name
    if hasattr(env.config, 'syntax'):
        if not getattr(env.config.syntax, 'use_figure', True):
            return Markup(code)
    return Markup(
        '<div class="codebox"><figure class="code">%s<figcaption>%s</figcaption></figure></div>\n\n'
        % (code, caption))
Exemple #8
0
    def begin_site(self):
        """
        Initialize plugin. Add tag to the site context variable
        and methods for walking tagged resources.
        """

        self.logger.debug("Adding tags from metadata")
        config = self.site.config
        content = self.site.content
        tags = {}
        add_method(Node,
            'walk_resources_tagged_with', walk_resources_tagged_with)
        walker = get_tagger_sort_method(self.site)
        for resource in walker():
            try:
                taglist = attrgetter("meta.tags")(resource)
            except AttributeError:
                continue
            for tag in taglist:
                if not tag in tags:
                    tags[tag] = [resource]
                    add_method(Node,
                        'walk_resources_tagged_with_%s' % tag,
                        walk_resources_tagged_with,
                        tag=tag)
                else:
                    tags[tag].append(resource)

        self.site.tagger = Expando(dict(tags=tags))
Exemple #9
0
def test_expando_to_dict_with_update():
    d1 = {"a": 123, "b": "abc"}
    x = Expando(d1)
    d = {"b": {"c": 456, "d": {"e": "abc"}}, "f": "lmn"}
    x.update(d)
    expected = {}
    expected.update(d1)
    expected.update(d)
    assert expected == x.to_dict()
    d2 = {"a": 789, "f": "opq"}
    y = Expando(d2)
    x.update(y)
    expected.update(d2)
    assert expected == x.to_dict()
Exemple #10
0
    def settings(self):
        """Settings for this plugin.

        This property combines default settings with those specified in the
        site config to produce the final settings for this plugin.
        """
        settings = Expando({})
        settings.sanity_check = True
        settings.conf_path = "."
        settings.block_map = {}
        try:
            user_settings = getattr(self.site.config, self.plugin_name)
        except AttributeError:
            pass
        else:
            for name in dir(user_settings):
                if not name.startswith("_"):
                    setattr(settings, name, getattr(user_settings, name))
        return settings
Exemple #11
0
    def settings(self):
        """Settings for this plugin.

        This property combines default settings with those specified in the
        site config to produce the final settings for this plugin.
        """
        settings = Expando({})
        settings.sanity_check = True
        settings.conf_path = "."
        settings.block_map = {}
        try:
            user_settings = getattr(self.site.config, self.plugin_name)
        except AttributeError:
            pass
        else:
            for name in dir(user_settings):
                if not name.startswith("_"):
                    setattr(settings,name,getattr(user_settings,name))
        return settings
Exemple #12
0
    def settings(self):
        """
        The settings for this plugin the site config.
        """

        opts = Expando({})
        try:
            opts = getattr(self.site.config, self.plugin_name)
        except AttributeError:
            pass
        return opts
Exemple #13
0
 def test_can_execute_optipng(self):
     s = Site(TEST_SITE)
     s.config.mode = "production"
     s.config.plugins = ['hyde.ext.plugins.optipng.OptiPNGPlugin']
     s.config.optipng = Expando(dict(args=dict(quiet="")))
     source =File(TEST_SITE.child('content/media/images/hyde-lt-b.png'))
     target = File(Folder(s.config.deploy_root_path).child('media/images/hyde-lt-b.png'))
     gen = Generator(s)
     gen.generate_resource_at_path(source)
     assert target.exists
     assert target.size < source.size
Exemple #14
0
    def test_uglify_with_extra_options(self):
        s = Site(TEST_SITE)
        s.config.plugins = ['hyde.ext.plugins.js.UglifyPlugin']
        s.config.mode = "production"
        s.config.uglify = Expando(dict(args={"nc":""}))
        source = TEST_SITE.child('content/media/js/jquery.js')
        target = File(Folder(s.config.deploy_root_path).child('media/js/jquery.js'))
        gen = Generator(s)
        gen.generate_resource_at_path(source)

        assert target.exists
        expected = File(UGLIFY_SOURCE.child('expected-jquery-nc.js'))
        # TODO: Very fragile. Better comparison needed.
        text = target.read_all()
        assert text.startswith("(function(")
Exemple #15
0
    def test_can_execute_stylus(self):
        s = Site(TEST_SITE)
        s.config.plugins = ['hyde.ext.plugins.stylus.StylusPlugin']
        paths = ['/usr/local/share/npm/bin/stylus']
        for path in paths:
            if File(path).exists:
                s.config.stylus = Expando(dict(app=path))
        source = TEST_SITE.child('content/media/css/site.styl')
        target = File(Folder(s.config.deploy_root_path).child('media/css/site.css'))
        gen = Generator(s)
        gen.generate_resource_at_path(source)

        assert target.exists
        text = target.read_all()
        expected_text = File(STYLUS_SOURCE.child('expected-site.css')).read_all()
        assert text.strip() == expected_text.strip()
Exemple #16
0
def test_expando_to_dict_with_update():
    d1 = {"a": 123, "b": "abc"}
    x = Expando(d1)
    d = {"b": {"c": 456, "d": {"e": "abc"}}, "f": "lmn"}
    x.update(d)
    expected = {}
    expected.update(d1)
    expected.update(d)
    assert expected == x.to_dict()
    d2 = {"a": 789, "f": "opq"}
    y = Expando(d2)
    x.update(y)
    expected.update(d2)
    assert expected == x.to_dict()
Exemple #17
0
 def begin_site(self):
     """
     Initialize plugin. Add tag to the site context variable
     and methods for walking tagged resources.
     """
     self.logger.debug("Adding tags from metadata")
     config = self.site.config
     content = self.site.content
     tags = {}
     add_method(Node,
         'walk_resources_tagged_with', walk_resources_tagged_with)
     walker = get_tagger_sort_method(self.site)
     for resource in walker():
         self._process_tags_in_resource(resource, tags)
     self._process_tag_metadata(tags)
     self.site.tagger = Expando(dict(tags=tags))
     self._generate_archives()
Exemple #18
0
def test_expando_update():
    d1 = {"a": 123, "b": "abc"}
    x = Expando(d1)
    assert x.a == d1['a']
    assert x.b == d1['b']
    d = {"b": {"c": 456, "d": {"e": "abc"}}, "f": "lmn"}
    x.update(d)
    assert x.a == d1['a']
    assert x.b.c == d['b']['c']
    assert x.b.d.e == d['b']['d']['e']
    assert x.f == d["f"]
    d2 = {"a": 789, "f": "opq"}
    y = Expando(d2)
    x.update(y)
    assert x.a == 789
    assert x.f == "opq"
Exemple #19
0
 def test_can_execute_optipng(self):
     s = Site(TEST_SITE)
     s.config.mode = "production"
     s.config.plugins = ['hyde.ext.plugins.optipng.OptiPNGPlugin']
     paths = ['/usr/local/bin/optipng', '/usr/bin/optipng']
     optipng = [path for path in paths if File(path).exists]
     if not optipng:
         assert False, "Cannot find the optipng executable"
     optipng = optipng[0]
     s.config.optipng = Expando(dict(app=optipng, args=dict(quiet="")))
     source = File(TEST_SITE.child('content/media/images/hyde-lt-b.png'))
     target = File(
         Folder(
             s.config.deploy_root_path).child('media/images/hyde-lt-b.png'))
     gen = Generator(s)
     gen.generate_resource_at_path(source)
     assert target.exists
     assert target.size < source.size
Exemple #20
0
    def test_walk_resources_sorted_by_index(self):
        s = Site(TEST_SITE)
        s.load()
        config = {"index": {"attr": ['meta.index', 'name']}}
        s.config.sorter = Expando(config)
        MetaPlugin(s).begin_site()
        SorterPlugin(s).begin_site()

        assert hasattr(s.content, 'walk_resources_sorted_by_index')
        expected = [
            "angry-post.html", "another-sad-post.html", "happy-post.html"
        ]

        pages = [
            page.name for page in s.content.walk_resources_sorted_by_index()
        ]

        assert pages == sorted(expected, key=lambda f: (File(f).kind, f))
Exemple #21
0
def markdown(env, value):
    """
    Markdown filter with support for extensions.
    """
    try:
        import markdown as md
    except ImportError:
        logger.error(u"Cannot load the markdown library.")
        raise TemplateError("Cannot load the markdown library")
    output = value
    d = {}
    if hasattr(env.config, 'markdown'):
        d['extensions'] = getattr(env.config.markdown, 'extensions', [])
        d['extension_configs'] = getattr(env.config.markdown,
                                         'extension_configs',
                                         Expando({})).to_dict()
    marked = md.Markdown(**d)

    return marked.convert(output)
Exemple #22
0
    def test_can_execute_less(self):
        s = Site(TEST_SITE)
        s.config.plugins = ['hyde.ext.plugins.less.LessCSSPlugin']
        paths = ['/usr/local/share/npm/bin/lessc', '~/local/bin/lessc']
        less = [path for path in paths if File(path).exists]
        if not less:
            assert False, "Cannot find the lessc executable"
        less = less[0]
        s.config.less = Expando(dict(app=less))
        source = TEST_SITE.child('content/media/css/site.less')
        target = File(Folder(s.config.deploy_root_path).child('media/css/site.css'))
        gen = Generator(s)
        gen.generate_resource_at_path(source)

        assert target.exists
        text = target.read_all()
        expected_text = File(LESS_SOURCE.child('expected-site.css')).read_all()

        assert text == expected_text
        return
Exemple #23
0
    def test_can_uglify(self):
        s = Site(TEST_SITE)
        s.config.plugins = ['hyde.ext.plugins.uglify.UglifyPlugin']
        s.config.mode = "production"
        paths = ['/usr/local/share/npm/bin/uglifyjs', '~/local/bin/uglifyjs',
                 '/usr/bin/uglifyjs', '~/bin/uglifyjs']
        uglify = [path for path in paths if File(path).exists]
        if not uglify:
            assert False, "Cannot find the uglify executable"

        uglify = uglify[0]
        s.config.uglify = Expando(dict(app=uglify))
        source = TEST_SITE.child('content/media/js/jquery.js')
        target = File(Folder(s.config.deploy_root_path).child('media/js/jquery.js'))
        gen = Generator(s)
        gen.generate_resource_at_path(source)

        assert target.exists
        expected = File(UGLIFY_SOURCE.child('expected-jquery.js'))
        # TODO: Very fragile. Better comparison needed.
        assert target.read_all() == expected.read_all()
Exemple #24
0
    def test_walk_resources_sorted(self):
        s = Site(TEST_SITE)
        s.load()
        s.config.plugins = ['hyde.ext.meta.SorterPlugin']
        s.config.sorter = Expando(
            dict(kind=dict(attr=['source_file.kind', 'name'])))

        SorterPlugin(s).begin_site()

        assert hasattr(s.content, 'walk_resources_sorted_by_kind')
        expected = [
            "404.html", "about.html", "apple-touch-icon.png",
            "merry-christmas.html", "crossdomain.xml", "favicon.ico",
            "robots.txt", "site.css"
        ]

        pages = [
            page.name for page in s.content.walk_resources_sorted_by_kind()
        ]

        assert pages == sorted(expected, key=lambda f: (File(f).kind, f))
Exemple #25
0
def test_expando_to_dict():
    d = {"a": 123, "b": {"c": 456, "d": {"e": "abc"}}}
    x = Expando(d)
    assert d == x.to_dict()
Exemple #26
0
def presenter(env, raw_text, id=None, resource=None):
    '''
    A filter that builds a presentation
    '''
    # get the config data relevant to this presentation's settings
    try:
        res_meta = getattr(resource.meta, "presenter")
    except AttributeError:
        res_meta = None
    try:
        res_meta_id = getattr(res_meta, id)
    except AttributeError:
        res_meta_id = None
    try:
        conf_id = getattr(config_cache, id)
    except AttributeError:
        conf_id = None

    # gather relevant settings for the presentation and slides
    settings = {"raw_text": raw_text, "slide_items": {"env": env}}
    # look for the proper settings for the presentation
    for k, v in default.items():
        try:
            # try resource.meta.presenter.KEY
            settings[k] = getattr(res_meta, k)
        except AttributeError:
            try:
                # try resource.meta.presenter.ID.KEY
                settings[k] = getattr(res_meta_id, k)
            except AttributeError:
                try:
                    # try config.presenter.ID.KEY
                    settings[k] = getattr(conf_id, k)
                except AttributeError:
                    # take the default value
                    settings[k] = v
    # set the id meta data
    if id:
        if settings["meta"]:
            settings["meta"].update({"id": id})
        else:
            settings["meta"] = Expando({"id": id})
    # look for the proper settings for the slides
    for k, v in slide_default.items():
        try:
            # try resource.meta.presenter.slides.KEY
            settings["slide_items"][k] = getattr(getattr(res_meta, "slides"),
                                                 k)
        except AttributeError:
            try:
                # try resource.meta.presenter.slides.ID.KEY
                settings["slide_items"][k] = getattr(
                    getattr(res_meta_id, "slides"), k)
            except AttributeError:
                try:
                    # try config.presenter.slides.ID.KEY
                    settings["slide_items"][k] = getattr(
                        getattr(conf_id, "slides"), k)
                except AttributeError:
                    # take the default value
                    settings["slide_items"][k] = v

    # get the resource's presentation list
    try:
        pres = resource.pres
    except AttributeError:
        resource.pres = []
        pres = resource.pres

    # create a presentation for this resource
    P = Presentation(**settings)
    pres.append(P)

    return P.html
Exemple #27
0
def test_expando_two_levels():
    d = {"a": 123, "b": {"c": 456}}
    x = Expando(d)
    assert x.a == d['a']
    assert x.b.c == d['b']['c']
Exemple #28
0
def test_expando_three_levels():
    d = {"a": 123, "b": {"c": 456, "d": {"e": "abc"}}}
    x = Expando(d)
    assert x.a == d['a']
    assert x.b.c == d['b']['c']
    assert x.b.d.e == d['b']['d']['e']
Exemple #29
0
def test_expando_to_dict():
    d = {"a": 123, "b": {"c": 456, "d": {"e": "abc"}}}
    x = Expando(d)
    assert d == x.to_dict()
Exemple #30
0
    def test_nav_with_grouper_sorted(self):

        cfg = """
        nodemeta: meta.yaml
        plugins:
          - hyde.ext.plugins.meta.MetaPlugin
          - hyde.ext.plugins.sorter.SorterPlugin
          - hyde.ext.plugins.grouper.GrouperPlugin
        sorter:
          kind:
              attr:
                  - source_file.kind
              filters:
                  is_processable: True
        grouper:
          section:
              description: Sections in the site
              sorter: kind
              groups:
                  -
                      name: start
                      description: Getting Started
                  -
                      name: awesome
                      description: Awesome
                  -
                      name: plugins
                      description: Plugins

        """
        self.s.config = Config(TEST_SITE, config_dict=yaml.load(cfg))
        self.s.load()
        MetaPlugin(self.s).begin_site()
        SorterPlugin(self.s).begin_site()
        GrouperPlugin(self.s).begin_site()

        text ="""
{% set sorted = site.grouper['section'].groups|sort(attribute='name') %}
{% for group in sorted %}
<ul>
    <li>
        <h2>{{ group.name|title }}</h2>
        <h3>{{ group.description }}</h3>
        <ul class="links">
            {% for resource in group.walk_resources_in_node(site.content) %}
            <li>{{resource.name}}</li>
            {% endfor %}
        </ul>
    </li>
</ul>
{% endfor %}

"""
        expected = """
<ul>
    <li>
        <h2>Awesome</h2>
        <h3>Awesome</h3>
        <ul class="links">
        </ul>
    </li>
</ul>
<ul>
    <li>
        <h2>Plugins</h2>
        <h3>Plugins</h3>
        <ul class="links">
            <li>plugins.html</li>
            <li>tags.html</li>
        </ul>
    </li>
</ul>
<ul>
    <li>
        <h2>Start</h2>
        <h3>Getting Started</h3>
        <ul class="links">
            <li>installation.html</li>
            <li>overview.html</li>
            <li>templating.html</li>
        </ul>
    </li>
</ul>


"""
        self.s.config.grouper.section.groups.append(Expando({"name": "awesome", "description": "Aweesoome"}));
        gen = Generator(self.s)
        gen.load_site_if_needed()
        gen.load_template_if_needed()
        out = gen.template.render(text, {'site':self.s})
        assert_html_equals(out, expected)
Exemple #31
0
def test_expando_one_level():
    d = {"a": 123, "b": "abc"}
    x = Expando(d)
    assert x.a == d['a']
    assert x.b == d['b']