Example #1
0
def _get_parser() -> typing.Tuple[shortcodes.Parser, shortcodes.Parser]:
    """Return the shortcodes parser, create it if necessary."""
    global _parser, _commented_parser
    if _parser is None:
        start, end = '{}'
        _parser = shortcodes.Parser(start, end)
        _commented_parser = shortcodes.Parser(f'<!-- {start}', f'{end} -->')
    return _parser, _commented_parser
Example #2
0
def collect():
    """Collect information by parsing shortcodes."""
    parser = shortcodes.Parser(inherit_globals=False, ignore_unknown=True)
    parser.register(_process_figure, "figure")
    figures = {}
    ivy.nodes.root().walk(
        lambda node: _parse_shortcodes(node, parser, figures))
    _flatten_figures(figures)
Example #3
0
def collect():
    """Collect information by parsing shortcodes."""
    parser = shortcodes.Parser(inherit_globals=False, ignore_unknown=True)
    parser.register(_process_index, "i", "/i")
    index = util.make_config("index")
    ivy.nodes.root().walk(lambda node: parser.parse(node.text, {
        "node": node,
        "index": index
    }))
Example #4
0
def init():

    # Check the site's config file for customized settings for the
    # shortcode parser.
    settings = ark.site.config('shortcodes', {})

    # Initialize a single parser instance.
    global scparser
    scparser = shortcodes.Parser(**settings)
Example #5
0
    def render_shortcodes(text, node):
        global parser
        if parser is None:
            settings = ivy.site.config.get('shortcode_settings') or {}
            parser = shortcodes.Parser(**settings)

        try:
            return parser.parse(text, node)
        except shortcodes.ShortcodeError as err:
            msg = "Shortcode Error\n"
            msg += f">> Node: {node.url}\n"
            msg += f">> {err.__class__.__name__}: {err}"
            if (cause := err.__cause__):
                msg += f"\n>> Cause: {cause.__class__.__name__}: {cause}"
            sys.exit(msg)
Example #6
0
def test_args_with_double_quoted_strings():
    text = '[% args arg1 "arg 2" key1=arg3 key2="arg 4" %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == 'arg1|arg 2|key1:arg3|key2:arg 4'
Example #7
0
def test_parse_single_shortcode_with_text():
    text = '..[% foo %]..'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == '..bar..'
Example #8
0
def test_double_escaped_shortcode():
    text = r'\\[% foo %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == r'\[% foo %]'
Example #9
0
def test_parse_string_no_shortcodes():
    text = 'foo'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == 'foo'
Example #10
0
def test_parse_single_shortcode():
    text = '[% foo %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == 'bar'
Example #11
0
def test_wrapping_wrapping_shortcode():
    text = '[% wrap div %][% wrap p %][% foo %][% endwrap %][% endwrap %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == '<div><p>bar</p></div>'
Example #12
0
def test_parse_empty_string():
    text = ''
    rendered = shortcodes.Parser().parse(text)
    assert rendered == ''
Example #13
0
        template_context = dict(url=pargs[0], id=id)
        extra_context = _get_extra_context(id, tag)
        template_context.update(extra_context)
    else:
        template_context = dict()
    template_context.update(defaults)
    template_context.update(kwargs)
    template = env.get_template('%s.html' % tag)
    output = template.render(**template_context)
    return output


"""
Register handlers
"""
parser = shortcodes.Parser()
for tag, defaults in SHORTCODE_DICT.items():
    tag_handler = partial(_handler, tag=tag, defaults=defaults)
    parser.register(tag_handler, tag)


def process_shortcode(tag):
    """
    Generates html from shortcode
    """
    # Replace unicode <br>
    text = tag.get_text().replace(u'\xa0', u' ')
    try:
        return parser.parse(text)
    except shortcodes.RenderingError as e:
        logger.error('Could not render short code in: "%s"' % text)
Example #14
0
def test_unbalanced_tags_exception():
    text = '[% wrap %] missing end tag...'
    with pytest.raises(shortcodes.NestingError):
        shortcodes.Parser().parse(text)
Example #15
0
def test_locally_registered_wrap():
    text = '[% localwrap div %]foo[% endlocalwrap %]'
    parser = shortcodes.Parser()
    parser.register(wrap_handler, 'localwrap', 'endlocalwrap')
    rendered = parser.parse(text)
    assert rendered == '<div>foo</div>'
Example #16
0
def make_app(config=None, **kw):
    "factory to create the app"

    app = ChillFlask('chill')

    if config:
        config_file = config if config[0] == os.sep else os.path.join(
            os.getcwd(), config)
        app.config.from_pyfile(config_file)
    app.config.update(kw)

    cache.init_app(app)

    # Set the freezer destination path to be absolute if needed.
    freeze_folder = app.config.get('FREEZER_DESTINATION', None)
    if freeze_folder:
        if freeze_folder[0] != os.sep:
            freeze_folder = os.path.join(os.getcwd(), freeze_folder)

        app.config['FREEZER_DESTINATION'] = freeze_folder

    # TODO: fix conflict with page_uri
    root_folder = app.config.get('ROOT_FOLDER', None)
    if root_folder:
        if root_folder[0] != os.sep:
            root_folder = os.path.join(os.getcwd(), root_folder)

        app.config['ROOT_FOLDER'] = root_folder
        #root_path = '/' # See no need to have this be different
        if os.path.isdir(root_folder):
            app.add_url_rule('/<path:filename>', view_func=app.send_root_file)

    media_folder = app.config.get('MEDIA_FOLDER', None)
    if media_folder:
        if media_folder[0] != os.sep:
            media_folder = os.path.join(os.getcwd(), media_folder)

        app.config['MEDIA_FOLDER'] = media_folder
        media_path = app.config.get('MEDIA_PATH', '/media/')
        if os.path.isdir(media_folder) and media_path[0] == '/':
            app.add_url_rule('%s<path:filename>' % media_path,
                             view_func=app.send_media_file)

    document_folder = app.config.get('DOCUMENT_FOLDER', None)
    if document_folder:
        if document_folder[0] != os.sep:
            document_folder = os.path.join(os.getcwd(), document_folder)
        app.config['DOCUMENT_FOLDER'] = document_folder

    template_folder = app.config.get('THEME_TEMPLATE_FOLDER',
                                     app.template_folder)
    app.config['THEME_TEMPLATE_FOLDER'] = template_folder if template_folder[
        0] == os.sep else os.path.join(os.getcwd(), template_folder)

    queries_folder = app.config.get('THEME_SQL_FOLDER', 'queries')
    app.config['THEME_SQL_FOLDER'] = queries_folder if queries_folder[
        0] == os.sep else os.path.join(os.getcwd(), queries_folder)

    chill_queries_folder = os.path.join(os.path.dirname(__file__), 'queries')
    user_queries_folder = app.config.get('THEME_SQL_FOLDER')
    app.queries = multiple_directory_files_loader(chill_queries_folder,
                                                  user_queries_folder)

    # Set the jinja2 template folder eith fallback for app.template_folder
    app.jinja_env.loader = FileSystemLoader(
        app.config.get('THEME_TEMPLATE_FOLDER'))

    @app.teardown_appcontext
    def teardown_db(exception):
        db = getattr(g, '_database', None)
        if db is not None:
            db.dispose()

    # STATIC_URL='http://cdn.example.com/whatever/works/'
    @app.context_processor
    def inject_paths():
        """
        Inject the variables 'theme_static_path' and 'media_path' into the templates.

        Template variable will always have a trailing slash.

        """
        theme_static_path = app.config.get('THEME_STATIC_PATH', '/theme/')
        media_path = app.config.get('MEDIA_PATH', '/media/')
        #static_url = app.config.get('STATIC_URL', app.static_url_path)
        if not theme_static_path.endswith('/'):
            theme_static_path += '/'
        if not media_path.endswith('/'):
            media_path += '/'
        return dict(theme_static_path=theme_static_path, media_path=media_path)

    @app.context_processor
    def inject_config():
        """
        Inject the config into the templates.
        """
        return dict(config=dict(app.config))

    # Add the markdown filter for the templates
    md = Markdown(app)

    @app.template_filter('readfile')
    def readfile(filename):
        "A template filter to read files from the DOCUMENT_FOLDER"
        document_folder = app.config.get('DOCUMENT_FOLDER')
        if document_folder:
            # Restrict access to just the DOCUMENT_FOLDER.
            filepath = os.path.normpath(os.path.join(document_folder,
                                                     filename))
            if os.path.commonprefix([document_folder, filepath
                                     ]) != document_folder:
                app.logger.warn(
                    "The filepath: '{0}' is outside of the DOCUMENT_FOLDER".
                    format(filepath))
                return filename

            with open(os.path.join(document_folder, filename), 'r') as f:
                content = f.read().decode('utf-8')
            return content

        app.logger.warn(
            "jinja2 filter 'readfile' can't find file: '{0}'".format(filename))
        return filename

    # register any blueprints here
    #app.logger.warning("Not registering resource blueprint")
    #app.register_blueprint(resource)

    from chill.public import PageView
    #app.logger.warning("Not registering page blueprint")
    page = Blueprint('public',
                     __name__,
                     static_folder=None,
                     template_folder=None)

    # TODO: The shortcode start and end is rather custom.  Make this
    # configurable or no?
    # The defualt from the shortcodes.py is '[%' and '%]'.
    app.parser = shortcodes.Parser(start='[chill', end=']', esc='\\')

    @app.template_filter('shortcodes')
    def shortcodes_filter(content):
        "Parse the rendered string for chill shortcodes"
        return Markup(app.parser.parse(content))

    theme_static_folder = app.config.get('THEME_STATIC_FOLDER', None)
    if theme_static_folder:
        if theme_static_folder[0] != os.sep:
            theme_static_folder = os.path.join(os.getcwd(),
                                               theme_static_folder)

        app.config['THEME_STATIC_FOLDER'] = theme_static_folder
        theme_static_path = app.config.get('THEME_STATIC_PATH', '/theme/')
        if os.path.isdir(theme_static_folder) and theme_static_path[0] == '/':
            app.add_url_rule('%s<path:filename>' % theme_static_path,
                             view_func=app.send_theme_file)

    page.add_url_rule('/', view_func=PageView.as_view('page'))
    page.add_url_rule('/index.html', view_func=PageView.as_view('index'))
    page.add_url_rule('/<path:uri>/', view_func=PageView.as_view('page_uri'))
    page.add_url_rule('/<path:uri>/index.html',
                      view_func=PageView.as_view('uri_index'))
    app.register_blueprint(page,
                           url_prefix=app.config.get('PUBLIC_URL_PREFIX', ''))

    return app
Example #17
0
def test_locally_registered_handler():
    text = '[% local %]'
    parser = shortcodes.Parser()
    parser.register(foo_handler, 'local')
    rendered = parser.parse(text)
    assert rendered == 'bar'
Example #18
0
def test_context_object():
    text = '[% context %]'
    rendered = shortcodes.Parser().parse(text, 101)
    assert rendered == '101'
Example #19
0
def test_wrapping_and_text_mix():
    text = '[% wrap div %]..[% wrap p %].[% foo %].[% endwrap %]..[% endwrap %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == '<div>..<p>.bar.</p>..</div>'
Example #20
0
def test_args_with_single_quoted_strings():
    text = "[% args arg1 'arg 2' key1=arg3 key2='arg 4' %]"
    rendered = shortcodes.Parser().parse(text)
    assert rendered == 'arg1|arg 2|key1:arg3|key2:arg 4'
Example #21
0
def test_nonascii_args():
    text = '[% args pøs0 k€¥="välué" %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == 'pøs0|k€¥:välué'
Example #22
0
def test_handler_exception():
    text = '[% divbyzero %]'
    with pytest.raises(shortcodes.RenderingError) as exinfo:
        shortcodes.Parser().parse(text)
    assert isinstance(exinfo.value.__cause__, ZeroDivisionError)
Example #23
0
def test_wrapping_simple_text():
    text = '[% wrap div %]foo[% endwrap %]'
    rendered = shortcodes.Parser().parse(text)
    assert rendered == '<div>foo</div>'
Example #24
0
import sys

try:
    import shortcodes
except ImportError:
    shortcodes = None

# The shortcodes package is an optional dependency.
if shortcodes:

    # Check the site's config file for customized settings for the shortcode
    # parser.
    settings = ivy.site.config.get('shortcodes', {})

    # Initialize a single parser instance.
    parser = shortcodes.Parser(**settings)

    # Filter each node's content on the 'node_text' filter hook and render
    # any shortcodes contained in it.
    @ivy.hooks.register('node_text')
    def render(text, node):
        try:
            return parser.parse(text, node)
        except shortcodes.ShortcodeError as err:
            msg = "-------------------\n"
            msg += "  Shortcode Error  \n"
            msg += "-------------------\n\n"
            msg += "  %s\n\n" % node
            msg += "  %s: %s" % (err.__class__.__name__, err)
            if err.__context__:
                cause = err.__context__
Example #25
0
def test_invalid_tag_exception():
    text = '[% notregistered %]'
    with pytest.raises(shortcodes.InvalidTagError):
        shortcodes.Parser().parse(text)