snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
187
zerver/lib/markdown/help_settings_links.py
Normal file
187
zerver/lib/markdown/help_settings_links.py
Normal file
@@ -0,0 +1,187 @@
|
||||
import re
|
||||
from re import Match
|
||||
from typing import Any
|
||||
|
||||
from markdown import Markdown
|
||||
from markdown.extensions import Extension
|
||||
from markdown.preprocessors import Preprocessor
|
||||
from typing_extensions import override
|
||||
|
||||
from zerver.lib.markdown.priorities import PREPROCESSOR_PRIORITIES
|
||||
|
||||
REGEXP = re.compile(r"\{settings_tab\|(?P<setting_identifier>.*?)\}")
|
||||
|
||||
|
||||
# If any changes to this link mapping are made,
|
||||
# `starlight_help/src/components/NavigationSteps.astro` should be updated accordingly.
|
||||
# This manual update mechanism will cease to exist once we have switched to the
|
||||
# starlight_help system.
|
||||
link_mapping = {
|
||||
# a mapping from the setting identifier that is the same as the final URL
|
||||
# breadcrumb to that setting to the name of its setting type, the setting
|
||||
# name as it appears in the user interface, and a relative link that can
|
||||
# be used to get to that setting
|
||||
"profile": ["Personal settings", "Profile", "/#settings/profile"],
|
||||
"account-and-privacy": [
|
||||
"Personal settings",
|
||||
"Account & privacy",
|
||||
"/#settings/account-and-privacy",
|
||||
],
|
||||
"preferences": ["Personal settings", "Preferences", "/#settings/preferences"],
|
||||
"notifications": ["Personal settings", "Notifications", "/#settings/notifications"],
|
||||
"your-bots": ["Personal settings", "Bots", "/#settings/your-bots"],
|
||||
"alert-words": ["Personal settings", "Alert words", "/#settings/alert-words"],
|
||||
"uploaded-files": ["Personal settings", "Uploaded files", "/#settings/uploaded-files"],
|
||||
"topics": ["Personal settings", "Topics", "/#settings/topics"],
|
||||
"muted-users": ["Personal settings", "Muted users", "/#settings/muted-users"],
|
||||
"organization-profile": [
|
||||
"Organization settings",
|
||||
"Organization profile",
|
||||
"/#organization/organization-profile",
|
||||
],
|
||||
"organization-settings": [
|
||||
"Organization settings",
|
||||
"Organization settings",
|
||||
"/#organization/organization-settings",
|
||||
],
|
||||
"organization-permissions": [
|
||||
"Organization settings",
|
||||
"Organization permissions",
|
||||
"/#organization/organization-permissions",
|
||||
],
|
||||
"default-user-settings": [
|
||||
"Organization settings",
|
||||
"Default user settings",
|
||||
"/#organization/organization-level-user-defaults",
|
||||
],
|
||||
"emoji-settings": ["Organization settings", "Custom emoji", "/#organization/emoji-settings"],
|
||||
"auth-methods": [
|
||||
"Organization settings",
|
||||
"Authentication methods",
|
||||
"/#organization/auth-methods",
|
||||
],
|
||||
"users": [
|
||||
"Organization settings",
|
||||
"Users",
|
||||
"/#organization/users/active",
|
||||
],
|
||||
"deactivated": [
|
||||
"Organization settings",
|
||||
"Users",
|
||||
"/#organization/users/deactivated",
|
||||
],
|
||||
"invitations": [
|
||||
"Organization settings",
|
||||
"Users",
|
||||
"/#organization/users/invitations",
|
||||
],
|
||||
"bots": [
|
||||
"Organization settings",
|
||||
"Bots",
|
||||
"/#organization/bots",
|
||||
],
|
||||
"default-channels-list": [
|
||||
"Organization settings",
|
||||
"Default channels",
|
||||
"/#organization/default-channels-list",
|
||||
],
|
||||
"linkifier-settings": [
|
||||
"Organization settings",
|
||||
"Linkifiers",
|
||||
"/#organization/linkifier-settings",
|
||||
],
|
||||
"playground-settings": [
|
||||
"Organization settings",
|
||||
"Code playgrounds",
|
||||
"/#organization/playground-settings",
|
||||
],
|
||||
"profile-field-settings": [
|
||||
"Organization settings",
|
||||
"Custom profile fields",
|
||||
"/#organization/profile-field-settings",
|
||||
],
|
||||
"channel-folder-settings": [
|
||||
"Organization settings",
|
||||
"Channel folders",
|
||||
"/#organization/channel-folders",
|
||||
],
|
||||
"data-exports-admin": [
|
||||
"Organization settings",
|
||||
"Data exports",
|
||||
"/#organization/data-exports-admin",
|
||||
],
|
||||
}
|
||||
|
||||
settings_markdown = """
|
||||
1. Click on the **gear** (<i class="zulip-icon zulip-icon-gear"></i>) icon in the upper
|
||||
right corner of the web or desktop app.
|
||||
|
||||
1. Select **{setting_type_name}**.
|
||||
|
||||
1. On the left, click {setting_reference}.
|
||||
"""
|
||||
|
||||
|
||||
def getMarkdown(setting_type_name: str, setting_name: str, setting_link: str) -> str:
|
||||
if relative_settings_links:
|
||||
relative_link = f"[{setting_name}]({setting_link})"
|
||||
# The "Bots" label appears in both Personal and Organization settings
|
||||
# in the user interface so we need special text for this setting.
|
||||
if setting_name in ["Bots", "Users"]:
|
||||
return f"1. Navigate to the {relative_link} \
|
||||
tab of the **{setting_type_name}** menu."
|
||||
return f"1. Go to {relative_link}."
|
||||
return settings_markdown.format( # nocoverage
|
||||
setting_type_name=setting_type_name,
|
||||
setting_reference=f"**{setting_name}**",
|
||||
)
|
||||
|
||||
|
||||
class SettingHelpExtension(Extension):
|
||||
@override
|
||||
def extendMarkdown(self, md: Markdown) -> None:
|
||||
"""Add SettingHelpExtension to the Markdown instance."""
|
||||
md.registerExtension(self)
|
||||
md.preprocessors.register(Setting(), "setting", PREPROCESSOR_PRIORITIES["setting"])
|
||||
|
||||
|
||||
relative_settings_links: bool = False
|
||||
|
||||
|
||||
def set_relative_settings_links(value: bool) -> None:
|
||||
global relative_settings_links
|
||||
relative_settings_links = value
|
||||
|
||||
|
||||
class Setting(Preprocessor):
|
||||
@override
|
||||
def run(self, lines: list[str]) -> list[str]:
|
||||
done = False
|
||||
while not done:
|
||||
for line in lines:
|
||||
loc = lines.index(line)
|
||||
match = REGEXP.search(line)
|
||||
|
||||
if match:
|
||||
text = [self.handleMatch(match)]
|
||||
# The line that contains the directive to include the macro
|
||||
# may be preceded or followed by text or tags, in that case
|
||||
# we need to make sure that any preceding or following text
|
||||
# stays the same.
|
||||
line_split = REGEXP.split(line, maxsplit=0)
|
||||
preceding = line_split[0]
|
||||
following = line_split[-1]
|
||||
text = [preceding, *text, following]
|
||||
lines = lines[:loc] + text + lines[loc + 1 :]
|
||||
break
|
||||
else:
|
||||
done = True
|
||||
return lines
|
||||
|
||||
def handleMatch(self, match: Match[str]) -> str:
|
||||
setting_identifier = match.group("setting_identifier")
|
||||
return getMarkdown(*link_mapping[setting_identifier])
|
||||
|
||||
|
||||
def makeExtension(*args: Any, **kwargs: Any) -> SettingHelpExtension:
|
||||
return SettingHelpExtension(*args, **kwargs)
|
||||
Reference in New Issue
Block a user