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
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)
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 }))
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)
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)
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'
def test_parse_single_shortcode_with_text(): text = '..[% foo %]..' rendered = shortcodes.Parser().parse(text) assert rendered == '..bar..'
def test_double_escaped_shortcode(): text = r'\\[% foo %]' rendered = shortcodes.Parser().parse(text) assert rendered == r'\[% foo %]'
def test_parse_string_no_shortcodes(): text = 'foo' rendered = shortcodes.Parser().parse(text) assert rendered == 'foo'
def test_parse_single_shortcode(): text = '[% foo %]' rendered = shortcodes.Parser().parse(text) assert rendered == 'bar'
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>'
def test_parse_empty_string(): text = '' rendered = shortcodes.Parser().parse(text) assert rendered == ''
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)
def test_unbalanced_tags_exception(): text = '[% wrap %] missing end tag...' with pytest.raises(shortcodes.NestingError): shortcodes.Parser().parse(text)
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>'
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
def test_locally_registered_handler(): text = '[% local %]' parser = shortcodes.Parser() parser.register(foo_handler, 'local') rendered = parser.parse(text) assert rendered == 'bar'
def test_context_object(): text = '[% context %]' rendered = shortcodes.Parser().parse(text, 101) assert rendered == '101'
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>'
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'
def test_nonascii_args(): text = '[% args pøs0 k€¥="välué" %]' rendered = shortcodes.Parser().parse(text) assert rendered == 'pøs0|k€¥:välué'
def test_handler_exception(): text = '[% divbyzero %]' with pytest.raises(shortcodes.RenderingError) as exinfo: shortcodes.Parser().parse(text) assert isinstance(exinfo.value.__cause__, ZeroDivisionError)
def test_wrapping_simple_text(): text = '[% wrap div %]foo[% endwrap %]' rendered = shortcodes.Parser().parse(text) assert rendered == '<div>foo</div>'
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__
def test_invalid_tag_exception(): text = '[% notregistered %]' with pytest.raises(shortcodes.InvalidTagError): shortcodes.Parser().parse(text)