2828from jinja2 import Environment , StrictUndefined , contextfilter , \
2929 contextfunction , environmentfunction
3030from jinja2 .runtime import Context
31+ import markdown_it
32+ import markupsafe
3133
3234from cms import TOKEN_MODE_DISABLED , TOKEN_MODE_FINITE , TOKEN_MODE_INFINITE , \
3335 TOKEN_MODE_MIXED , FEEDBACK_LEVEL_FULL , FEEDBACK_LEVEL_RESTRICTED , \
@@ -138,6 +140,19 @@ def today(ctx: Context, dt: datetime) -> bool:
138140 == now .replace (tzinfo = utc ).astimezone (timezone ).date ()
139141
140142
143+ def markdown_filter (text : str ) -> markupsafe .Markup :
144+ """Renders text as markdown and returns a Markup object
145+ corresponding to it.
146+
147+ text: The markdown text to render.
148+
149+ return: rendered HTML wrapped in the Markup class.
150+ """
151+ md = markdown_it .MarkdownIt ('js-default' )
152+ html = md .render (text )
153+ return markupsafe .Markup (html )
154+
155+
141156def instrument_generic_toolbox (env : Environment ):
142157 env .globals ["iter" ] = iter
143158 env .globals ["next" ] = next
@@ -163,6 +178,7 @@ def instrument_generic_toolbox(env: Environment):
163178 env .filters ["any" ] = any_
164179 env .filters ["dictselect" ] = dictselect
165180 env .filters ["make_timestamp" ] = make_timestamp
181+ env .filters ["markdown" ] = markdown_filter
166182
167183 env .tests ["contains" ] = lambda s , p : p in s
168184 env .tests ["endswith" ] = lambda s , p : s .endswith (p )
0 commit comments