2021-03-17 03:11:19 +01:00
|
|
|
import time
|
2024-07-12 02:30:23 +02:00
|
|
|
from typing import Any
|
2016-11-09 02:00:28 +01:00
|
|
|
|
2016-11-09 21:52:42 +01:00
|
|
|
import markdown
|
2016-12-21 19:50:48 +01:00
|
|
|
import markdown.extensions.admonition
|
2016-11-10 06:32:15 +01:00
|
|
|
import markdown.extensions.codehilite
|
2017-11-16 00:49:39 +01:00
|
|
|
import markdown.extensions.extra
|
2016-11-10 06:32:15 +01:00
|
|
|
import markdown.extensions.toc
|
2021-03-17 03:11:19 +01:00
|
|
|
import orjson
|
|
|
|
from django.conf import settings
|
|
|
|
from django.contrib.staticfiles.storage import staticfiles_storage
|
2019-02-02 23:53:55 +01:00
|
|
|
from django.template import Library, engines
|
2022-07-22 02:19:49 +02:00
|
|
|
from django.template.backends.jinja2 import Jinja2
|
2017-11-16 00:49:39 +01:00
|
|
|
from django.utils.safestring import mark_safe
|
|
|
|
|
2020-06-25 15:00:33 +02:00
|
|
|
import zerver.lib.markdown.api_arguments_table_generator
|
|
|
|
import zerver.lib.markdown.api_return_values_table_generator
|
|
|
|
import zerver.lib.markdown.fenced_code
|
|
|
|
import zerver.lib.markdown.help_emoticon_translations_table
|
|
|
|
import zerver.lib.markdown.help_relative_links
|
|
|
|
import zerver.lib.markdown.help_settings_links
|
|
|
|
import zerver.lib.markdown.include
|
|
|
|
import zerver.lib.markdown.nested_code_blocks
|
2023-02-03 20:53:58 +01:00
|
|
|
import zerver.lib.markdown.static
|
2020-06-25 15:00:33 +02:00
|
|
|
import zerver.lib.markdown.tabbed_sections
|
2020-06-11 00:54:34 +02:00
|
|
|
import zerver.openapi.markdown_extension
|
|
|
|
from zerver.lib.cache import dict_to_items_tuple, ignore_unhashable_lru_cache, items_tuple_to_dict
|
2016-11-09 21:52:42 +01:00
|
|
|
|
2013-10-25 18:54:03 +02:00
|
|
|
register = Library()
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2024-07-12 02:30:17 +02:00
|
|
|
def and_n_others(values: list[str], limit: int) -> str:
|
2013-10-25 18:54:03 +02:00
|
|
|
# A helper for the commonly appended "and N other(s)" string, with
|
|
|
|
# the appropriate pluralization.
|
2020-06-13 08:59:37 +02:00
|
|
|
return " and {} other{}".format(
|
2021-02-12 08:19:30 +01:00
|
|
|
len(values) - limit,
|
|
|
|
"" if len(values) == limit + 1 else "s",
|
2020-06-13 08:59:37 +02:00
|
|
|
)
|
2013-10-25 18:54:03 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
@register.filter(name="display_list", is_safe=True)
|
2024-07-12 02:30:17 +02:00
|
|
|
def display_list(values: list[str], display_limit: int) -> str:
|
2013-10-25 18:54:03 +02:00
|
|
|
"""
|
|
|
|
Given a list of values, return a string nicely formatting those values,
|
|
|
|
summarizing when you have more than `display_limit`. Eg, for a
|
|
|
|
`display_limit` of 3 we get the following possible cases:
|
|
|
|
|
|
|
|
Jessica
|
|
|
|
Jessica and Waseem
|
|
|
|
Jessica, Waseem, and Tim
|
|
|
|
Jessica, Waseem, Tim, and 1 other
|
|
|
|
Jessica, Waseem, Tim, and 2 others
|
|
|
|
"""
|
|
|
|
if len(values) == 1:
|
|
|
|
# One value, show it.
|
2020-06-10 06:41:04 +02:00
|
|
|
display_string = f"{values[0]}"
|
2013-10-25 18:54:03 +02:00
|
|
|
elif len(values) <= display_limit:
|
|
|
|
# Fewer than `display_limit` values, show all of them.
|
2021-02-12 08:19:30 +01:00
|
|
|
display_string = ", ".join(f"{value}" for value in values[:-1])
|
2020-06-10 06:41:04 +02:00
|
|
|
display_string += f" and {values[-1]}"
|
2013-10-25 18:54:03 +02:00
|
|
|
else:
|
|
|
|
# More than `display_limit` values, only mention a few.
|
2021-02-12 08:19:30 +01:00
|
|
|
display_string = ", ".join(f"{value}" for value in values[:display_limit])
|
2013-10-25 18:54:03 +02:00
|
|
|
display_string += and_n_others(values, display_limit)
|
|
|
|
|
|
|
|
return display_string
|
2016-05-11 19:01:53 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2024-07-12 02:30:23 +02:00
|
|
|
md_extensions: list[markdown.Extension] | None = None
|
|
|
|
md_macro_extension: markdown.Extension | None = None
|
2017-11-22 17:20:58 +01:00
|
|
|
# Prevent the automatic substitution of macros in these docs. If
|
|
|
|
# they contain a macro, it is always used literally for documenting
|
|
|
|
# the macro system.
|
|
|
|
docs_without_macros = [
|
2018-10-17 05:08:27 +02:00
|
|
|
"incoming-webhooks-walkthrough.md",
|
2017-11-22 17:20:58 +01:00
|
|
|
]
|
2016-11-10 06:32:15 +01:00
|
|
|
|
2023-02-02 04:35:24 +01:00
|
|
|
|
2019-04-18 04:35:14 +02:00
|
|
|
# render_markdown_path is passed a context dictionary (unhashable), which
|
|
|
|
# results in the calls not being cached. To work around this, we convert the
|
|
|
|
# dict to a tuple of dict items to cache the results.
|
|
|
|
@dict_to_items_tuple
|
2018-01-12 09:02:01 +01:00
|
|
|
@ignore_unhashable_lru_cache(512)
|
2019-04-18 04:35:14 +02:00
|
|
|
@items_tuple_to_dict
|
2021-02-12 08:20:45 +01:00
|
|
|
@register.filter(name="render_markdown_path", is_safe=True)
|
2021-02-12 08:19:30 +01:00
|
|
|
def render_markdown_path(
|
2022-12-07 19:43:49 +01:00
|
|
|
markdown_file_path: str,
|
2024-07-12 02:30:23 +02:00
|
|
|
context: dict[str, Any] | None = None,
|
2022-12-07 19:43:49 +01:00
|
|
|
integration_doc: bool = False,
|
2022-12-07 19:41:17 +01:00
|
|
|
help_center: bool = False,
|
2021-02-12 08:19:30 +01:00
|
|
|
) -> str:
|
2020-08-11 01:47:54 +02:00
|
|
|
"""Given a path to a Markdown file, return the rendered HTML.
|
2016-11-09 01:19:53 +01:00
|
|
|
|
2020-08-11 01:47:49 +02:00
|
|
|
Note that this assumes that any HTML in the Markdown file is
|
2016-11-09 01:19:53 +01:00
|
|
|
trusted; it is intended to be used for documentation, not user
|
|
|
|
data."""
|
2018-04-18 04:31:57 +02:00
|
|
|
|
|
|
|
# We set this global hackishly
|
2020-06-25 15:00:33 +02:00
|
|
|
from zerver.lib.markdown.help_settings_links import set_relative_settings_links
|
2021-02-12 08:19:30 +01:00
|
|
|
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
set_relative_settings_links(bool(context is not None and context.get("html_settings_links")))
|
2020-06-25 15:00:33 +02:00
|
|
|
from zerver.lib.markdown.help_relative_links import set_relative_help_links
|
2021-02-12 08:19:30 +01:00
|
|
|
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
set_relative_help_links(bool(context is not None and context.get("html_settings_links")))
|
2018-04-18 04:31:57 +02:00
|
|
|
|
2024-07-14 21:37:35 +02:00
|
|
|
global md_extensions, md_macro_extension
|
2016-12-16 10:07:08 +01:00
|
|
|
if md_extensions is None:
|
|
|
|
md_extensions = [
|
2017-07-25 02:35:59 +02:00
|
|
|
markdown.extensions.extra.makeExtension(),
|
2016-11-10 06:32:15 +01:00
|
|
|
markdown.extensions.toc.makeExtension(),
|
2016-12-21 19:50:48 +01:00
|
|
|
markdown.extensions.admonition.makeExtension(),
|
2016-11-10 06:32:15 +01:00
|
|
|
markdown.extensions.codehilite.makeExtension(
|
|
|
|
linenums=False,
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
guess_lang=False,
|
2016-11-10 06:32:15 +01:00
|
|
|
),
|
2020-06-25 15:00:33 +02:00
|
|
|
zerver.lib.markdown.fenced_code.makeExtension(
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
run_content_validators=bool(
|
|
|
|
context is not None and context.get("run_content_validators", False)
|
|
|
|
),
|
2019-05-16 22:38:53 +02:00
|
|
|
),
|
2023-01-31 19:49:06 +01:00
|
|
|
zerver.lib.markdown.api_arguments_table_generator.makeExtension(),
|
2023-01-31 18:45:04 +01:00
|
|
|
zerver.lib.markdown.api_return_values_table_generator.makeExtension(),
|
2020-06-25 15:00:33 +02:00
|
|
|
zerver.lib.markdown.nested_code_blocks.makeExtension(),
|
|
|
|
zerver.lib.markdown.tabbed_sections.makeExtension(),
|
|
|
|
zerver.lib.markdown.help_settings_links.makeExtension(),
|
|
|
|
zerver.lib.markdown.help_relative_links.makeExtension(),
|
|
|
|
zerver.lib.markdown.help_emoticon_translations_table.makeExtension(),
|
2023-02-03 20:53:58 +01:00
|
|
|
zerver.lib.markdown.static.makeExtension(),
|
2016-12-16 10:07:08 +01:00
|
|
|
]
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
if context is not None and "api_url" in context:
|
2019-08-16 21:17:01 +02:00
|
|
|
# We need to generate the API code examples extension each
|
|
|
|
# time so the `api_url` config parameter can be set dynamically.
|
|
|
|
#
|
|
|
|
# TODO: Convert this to something more efficient involving
|
|
|
|
# passing the API URL as a direct parameter.
|
2021-02-12 08:19:30 +01:00
|
|
|
extensions = [
|
|
|
|
zerver.openapi.markdown_extension.makeExtension(
|
|
|
|
api_url=context["api_url"],
|
|
|
|
),
|
2021-06-02 18:36:25 +02:00
|
|
|
*md_extensions,
|
2021-02-12 08:19:30 +01:00
|
|
|
]
|
2021-06-02 18:36:25 +02:00
|
|
|
else:
|
|
|
|
extensions = md_extensions
|
|
|
|
|
2022-12-07 19:43:49 +01:00
|
|
|
if integration_doc:
|
|
|
|
md_macro_extension = zerver.lib.markdown.include.makeExtension(
|
|
|
|
base_path="templates/zerver/integrations/include/"
|
|
|
|
)
|
2022-12-07 19:41:17 +01:00
|
|
|
elif help_center:
|
2023-01-25 23:08:29 +01:00
|
|
|
md_macro_extension = zerver.lib.markdown.include.makeExtension(base_path="help/include/")
|
2022-12-07 19:41:17 +01:00
|
|
|
else:
|
|
|
|
md_macro_extension = zerver.lib.markdown.include.makeExtension(
|
2023-01-31 12:11:45 +01:00
|
|
|
base_path="api_docs/include/"
|
2022-12-07 19:41:17 +01:00
|
|
|
)
|
2019-08-16 21:17:01 +02:00
|
|
|
if not any(doc in markdown_file_path for doc in docs_without_macros):
|
2020-09-02 06:59:07 +02:00
|
|
|
extensions = [md_macro_extension, *extensions]
|
2017-11-22 17:20:58 +01:00
|
|
|
|
2019-08-16 21:17:01 +02:00
|
|
|
md_engine = markdown.Markdown(extensions=extensions)
|
2016-12-16 10:07:08 +01:00
|
|
|
md_engine.reset()
|
2016-11-10 06:32:15 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
jinja = engines["Jinja2"]
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
assert isinstance(jinja, Jinja2)
|
|
|
|
if markdown_file_path.startswith("/"):
|
|
|
|
with open(markdown_file_path) as fp:
|
|
|
|
markdown_string = fp.read()
|
|
|
|
else:
|
2018-08-09 02:46:32 +02:00
|
|
|
markdown_string = jinja.env.loader.get_source(jinja.env, markdown_file_path)[0]
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
|
|
|
|
API_ENDPOINT_NAME = context.get("API_ENDPOINT_NAME", "") if context is not None else ""
|
2021-05-23 13:27:41 +02:00
|
|
|
markdown_string = markdown_string.replace("API_ENDPOINT_NAME", API_ENDPOINT_NAME)
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
|
2018-08-09 22:45:54 +02:00
|
|
|
html = md_engine.convert(markdown_string)
|
markdown: Fix use of pure_markdown for non-pure markdown rendering.
`render_markdown_path` renders Markdown, and also (since baff121115a1)
runs Jinja2 on the resulting HTML.
The `pure_markdown` flag was added in 0a99fa2fd669, and did two
things: retried the path directly in the filesystem if it wasn't found
by the Jinja2 resolver, and also skipped the subsequent Jinja2
templating step (regardless of where the content was found). In this
context, the name `pure_markdown` made some sense. The only two
callsites were the TOS and privacy policy renders, which might have
had user-supplied arbitrary paths, and we wished to handle absolute
paths in addition to ones inside `templates/`.
Unfortunately, the follow-up of 01bd55bbcbf7 did not refactor the
logic -- it changed it, by making `pure_markdown` only do the former
of the two behaviors. Passing `pure_markdown=True` after that commit
still caused it to always run Jinja2, but allowed it to look elsewhere
in the filesystem.
This set the stage for calls, such as the one introduced in
dedea237456b, which passed both a context for Jinja2, as well as
`pure_markdown=True` implying that Jinja2 was not to be used.
Split the two previous behaviors of the `pure_markdown` flag, and use
pre-existing data to control them, rather than an explicit flag. For
handling policy information which is stored at an absolute path
outside of the template root, we switch to using the template search
path if and only if the path is relative. This also closes the
potential inconsistency based on CWD when `pure_markdown=True` was
passed and the path was relative, not absolute.
Decide whether to run Jinja2 based on if a context is passed in at
all. This restores the behavior in the initial 0a99fa2fd669 where a
call to `rendar_markdown_path` could be made to just render markdown,
and not some other unmentioned and unrelated templating language as
well.
2023-03-10 02:47:44 +01:00
|
|
|
if context is None:
|
2023-04-04 01:42:32 +02:00
|
|
|
return mark_safe(html) # noqa: S308
|
2018-08-09 02:46:32 +02:00
|
|
|
|
2023-04-04 01:42:32 +02:00
|
|
|
return mark_safe(jinja.from_string(html).render(context)) # noqa: S308
|
2021-03-17 03:11:19 +01:00
|
|
|
|
|
|
|
|
2024-07-12 02:30:17 +02:00
|
|
|
def webpack_entry(entrypoint: str) -> list[str]:
|
2021-03-17 03:11:19 +01:00
|
|
|
while True:
|
|
|
|
with open(settings.WEBPACK_STATS_FILE, "rb") as f:
|
|
|
|
stats = orjson.loads(f.read())
|
|
|
|
status = stats["status"]
|
2021-03-17 03:11:41 +01:00
|
|
|
if not settings.DEBUG or status != "compile":
|
2021-03-17 03:11:19 +01:00
|
|
|
break
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
|
|
if status != "done":
|
|
|
|
raise RuntimeError("Webpack compilation was not successful")
|
|
|
|
|
2022-08-04 08:42:26 +02:00
|
|
|
try:
|
|
|
|
files_from_entrypoints = [
|
|
|
|
staticfiles_storage.url(settings.WEBPACK_BUNDLES + filename)
|
|
|
|
for filename in stats["chunks"][entrypoint]
|
|
|
|
if filename.endswith((".css", ".js")) and not filename.endswith(".hot-update.js")
|
|
|
|
]
|
|
|
|
except KeyError:
|
|
|
|
raise KeyError(
|
2023-02-22 23:03:47 +01:00
|
|
|
f"'{entrypoint}' entrypoint could not be found. Please define it in web/webpack.assets.json."
|
2022-08-04 08:42:26 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
return files_from_entrypoints
|