{"action":"created","comment":{"url":"https://api.github.com/repos/zulip/zulip/pulls/comments/183823285","pull_request_review_id":114895546,"id":183823285,"diff_hunk":"@@ -0,0 +1,86 @@\n+from __future__ import absolute_import\n+import re\n+import os\n+import markdown\n+import six\n+from typing import Any, Dict, Iterable, List, MutableSequence, Optional, Tuple, Union, Text\n+from typing.re import Match\n+from xml.etree.cElementTree import Element\n+from markdown.preprocessors import Preprocessor\n+\n+REGEXP = re.compile(r'\\{setting\\((?P<setting_name>.*?)\\)\\}')\n+\n+link_mapping = {\n+    # a mapping from the setting name as it appears in the user interface to\n+    # the name of its setting type and a relative link that can be used to get\n+    # to that setting\n+    'Your account': ['Settings', '/#settings/your-account'],\n+    'Custom emoji': ['Manage organization', '/#organization/emoji-settings'],\n+}\n+\n+settings_markdown = \"\"\"\n+1. From your desktop, click on the **gear**\n+   (<i class=\"icon-vector-cog\"></i>) in the upper right corner.\n+\n+1. Select **%s**.\n+\n+1. On the left, click %s.\n+\"\"\"\n+\n+\n+class SettingHelpExtension(markdown.Extension):\n+\n+    def __init__(self, *args, relative_links=False, **kwargs):\n+        self.relative_links = relative_links\n+\n+    def extendMarkdown(self, md: markdown.Markdown, md_globals: Dict[str, Any]) -> None:\n+        \"\"\" Add SettingHelpExtension to the Markdown instance. \"\"\"\n+        md.registerExtension(self)\n+        print(md.preprocessors.__dict__)\n+        md.preprocessors.add('setting', Setting(relative_links=self.relative_links),\n+                             '_begin')\n+\n+\n+class Setting(Preprocessor):\n+    def __init__(self, *args, relative_links: bool, **kwargs):\n+        super().__init__(*args, **kwargs)\n+        self.relative_links = relative_links\n+\n+    def run(self, lines: List[str]) -> List[str]:\n+        done = False\n+        while not done:\n+            for line in lines:\n+                loc = lines.index(line)\n+                match = REGEXP.search(line)\n+\n+                if match:\n+                    text = [self.handleMatch(match)]\n+                    # The line that contains the directive to include the macro\n+                    # may be preceded or followed by text or tags, in that case\n+                    # we need to make sure that any preceding or following text\n+                    # stays the same.\n+                    line_split = REGEXP.split(line, maxsplit=0)\n+                    preceding = line_split[0]\n+                    following = line_split[-1]\n+                    text = [preceding] + text + [following]\n+                    lines = lines[:loc] + text + lines[loc+1:]\n+                    break\n+            else:\n+                done = True\n+        return lines\n+\n+    def handleMatch(self, match: Match[Text]) -> Optional[Element]:\n+        setting_name = match.group('setting_name')\n+        setting_type_name = link_mapping[setting_name][0]\n+        setting_link = link_mapping[setting_name][1]\n+        if self.relative_links:\n+            setting_reference = \"[%s](%s)\" % (setting_name, setting_link)\n+        else:\n+            setting_reference = \"**%s**\" % (setting_name,)","path":"zerver/lib/bugdown/help_settings_links.py","position":null,"original_position":79,"commit_id":"8d2a50b5b3b9e89ddc47a65d5dabe1c8d469859d","original_commit_id":"de7e32edb1d3b4cd01fc40c4487b71688eefba9e","user":{"login":"timabbott","id":2746074,"avatar_url":"https://avatars0.githubusercontent.com/u/2746074?v=4","gravatar_id":"","url":"https://api.github.com/users/timabbott","html_url":"https://github.com/timabbott","followers_url":"https://api.github.com/users/timabbott/followers","following_url":"https://api.github.com/users/timabbott/following{/other_user}","gists_url":"https://api.github.com/users/timabbott/gists{/gist_id}","starred_url":"https://api.github.com/users/timabbott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/timabbott/subscriptions","organizations_url":"https://api.github.com/users/timabbott/orgs","repos_url":"https://api.github.com/users/timabbott/repos","events_url":"https://api.github.com/users/timabbott/events{/privacy}","received_events_url":"https://api.github.com/users/timabbott/received_events","type":"User","site_admin":false},"body":"For without `html_settings_links=True`, I think what we'll want is a unit test.  It's a bit hard to explain how to do that, so I'm tempted to just show by example (aka write the test when I merge this).\r\n\r\nBut for you to manually verify, you can always just set the variable to false and reload the page.","created_at":"2018-04-24T17:48:13Z","updated_at":"2018-04-24T17:48:13Z","html_url":"https://github.com/zulip/zulip/pull/9119#discussion_r183823285","pull_request_url":"https://api.github.com/repos/zulip/zulip/pulls/9119","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/zulip/zulip/pulls/comments/183823285"},"html":{"href":"https://github.com/zulip/zulip/pull/9119#discussion_r183823285"},"pull_request":{"href":"https://api.github.com/repos/zulip/zulip/pulls/9119"}},"in_reply_to_id":182624600},"pull_request":{"url":"https://api.github.com/repos/zulip/zulip/pulls/9119","id":182352287,"html_url":"https://github.com/zulip/zulip/pull/9119","diff_url":"https://github.com/zulip/zulip/pull/9119.diff","patch_url":"https://github.com/zulip/zulip/pull/9119.patch","issue_url":"https://api.github.com/repos/zulip/zulip/issues/9119","number":9119,"state":"open","locked":false,"title":"[WIP] bugdown: Add {settings|My Setting} macro","user":{"login":"Lyla-Fischer","id":549661,"avatar_url":"https://avatars3.githubusercontent.com/u/549661?v=4","gravatar_id":"","url":"https://api.github.com/users/Lyla-Fischer","html_url":"https://github.com/Lyla-Fischer","followers_url":"https://api.github.com/users/Lyla-Fischer/followers","following_url":"https://api.github.com/users/Lyla-Fischer/following{/other_user}","gists_url":"https://api.github.com/users/Lyla-Fischer/gists{/gist_id}","starred_url":"https://api.github.com/users/Lyla-Fischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Lyla-Fischer/subscriptions","organizations_url":"https://api.github.com/users/Lyla-Fischer/orgs","repos_url":"https://api.github.com/users/Lyla-Fischer/repos","events_url":"https://api.github.com/users/Lyla-Fischer/events{/privacy}","received_events_url":"https://api.github.com/users/Lyla-Fischer/received_events","type":"User","site_admin":false},"body":"#8889\r\n\r\nRelated to https://github.com/zulip/zulip/pull/9105 \r\n\r\n@adnrs96 Can you check this to make sure I'm on the right path?","created_at":"2018-04-18T02:34:55Z","updated_at":"2018-04-24T17:48:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"19b1a02bf941ed33e04b7ccd49fb6ddcdb542cff","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":804160549,"url":"https://api.github.com/repos/zulip/zulip/labels/size:%20XL","name":"size: XL","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/zulip/zulip/pulls/9119/commits","review_comments_url":"https://api.github.com/repos/zulip/zulip/pulls/9119/comments","review_comment_url":"https://api.github.com/repos/zulip/zulip/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zulip/zulip/issues/9119/comments","statuses_url":"https://api.github.com/repos/zulip/zulip/statuses/8d2a50b5b3b9e89ddc47a65d5dabe1c8d469859d","head":{"label":"Lyla-Fischer:macros","ref":"macros","sha":"8d2a50b5b3b9e89ddc47a65d5dabe1c8d469859d","user":{"login":"Lyla-Fischer","id":549661,"avatar_url":"https://avatars3.githubusercontent.com/u/549661?v=4","gravatar_id":"","url":"https://api.github.com/users/Lyla-Fischer","html_url":"https://github.com/Lyla-Fischer","followers_url":"https://api.github.com/users/Lyla-Fischer/followers","following_url":"https://api.github.com/users/Lyla-Fischer/following{/other_user}","gists_url":"https://api.github.com/users/Lyla-Fischer/gists{/gist_id}","starred_url":"https://api.github.com/users/Lyla-Fischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Lyla-Fischer/subscriptions","organizations_url":"https://api.github.com/users/Lyla-Fischer/orgs","repos_url":"https://api.github.com/users/Lyla-Fischer/repos","events_url":"https://api.github.com/users/Lyla-Fischer/events{/privacy}","received_events_url":"https://api.github.com/users/Lyla-Fischer/received_events","type":"User","site_admin":false},"repo":{"id":93885533,"name":"zulip","full_name":"Lyla-Fischer/zulip","owner":{"login":"Lyla-Fischer","id":549661,"avatar_url":"https://avatars3.githubusercontent.com/u/549661?v=4","gravatar_id":"","url":"https://api.github.com/users/Lyla-Fischer","html_url":"https://github.com/Lyla-Fischer","followers_url":"https://api.github.com/users/Lyla-Fischer/followers","following_url":"https://api.github.com/users/Lyla-Fischer/following{/other_user}","gists_url":"https://api.github.com/users/Lyla-Fischer/gists{/gist_id}","starred_url":"https://api.github.com/users/Lyla-Fischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Lyla-Fischer/subscriptions","organizations_url":"https://api.github.com/users/Lyla-Fischer/orgs","repos_url":"https://api.github.com/users/Lyla-Fischer/repos","events_url":"https://api.github.com/users/Lyla-Fischer/events{/privacy}","received_events_url":"https://api.github.com/users/Lyla-Fischer/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Lyla-Fischer/zulip","description":"Zulip server - powerful open source group chat","fork":true,"url":"https://api.github.com/repos/Lyla-Fischer/zulip","forks_url":"https://api.github.com/repos/Lyla-Fischer/zulip/forks","keys_url":"https://api.github.com/repos/Lyla-Fischer/zulip/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Lyla-Fischer/zulip/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Lyla-Fischer/zulip/teams","hooks_url":"https://api.github.com/repos/Lyla-Fischer/zulip/hooks","issue_events_url":"https://api.github.com/repos/Lyla-Fischer/zulip/issues/events{/number}","events_url":"https://api.github.com/repos/Lyla-Fischer/zulip/events","assignees_url":"https://api.github.com/repos/Lyla-Fischer/zulip/assignees{/user}","branches_url":"https://api.github.com/repos/Lyla-Fischer/zulip/branches{/branch}","tags_url":"https://api.github.com/repos/Lyla-Fischer/zulip/tags","blobs_url":"https://api.github.com/repos/Lyla-Fischer/zulip/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Lyla-Fischer/zulip/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Lyla-Fischer/zulip/git/refs{/sha}","trees_url":"https://api.github.com/repos/Lyla-Fischer/zulip/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Lyla-Fischer/zulip/statuses/{sha}","languages_url":"https://api.github.com/repos/Lyla-Fischer/zulip/languages","stargazers_url":"https://api.github.com/repos/Lyla-Fischer/zulip/stargazers","contributors_url":"https://api.github.com/repos/Lyla-Fischer/zulip/contributors","subscribers_url":"https://api.github.com/repos/Lyla-Fischer/zulip/subscribers","subscription_url":"https://api.github.com/repos/Lyla-Fischer/zulip/subscription","commits_url":"https://api.github.com/repos/Lyla-Fischer/zulip/commits{/sha}","git_commits_url":"https://api.github.com/repos/Lyla-Fischer/zulip/git/commits{/sha}","comments_url":"https://api.github.com/repos/Lyla-Fischer/zulip/comments{/number}","issue_comment_url":"https://api.github.com/repos/Lyla-Fischer/zulip/issues/comments{/number}","contents_url":"https://api.github.com/repos/Lyla-Fischer/zulip/contents/{+path}","compare_url":"https://api.github.com/repos/Lyla-Fischer/zulip/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Lyla-Fischer/zulip/merges","archive_url":"https://api.github.com/repos/Lyla-Fischer/zulip/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Lyla-Fischer/zulip/downloads","issues_url":"https://api.github.com/repos/Lyla-Fischer/zulip/issues{/number}","pulls_url":"https://api.github.com/repos/Lyla-Fischer/zulip/pulls{/number}","milestones_url":"https://api.github.com/repos/Lyla-Fischer/zulip/milestones{/number}","notifications_url":"https://api.github.com/repos/Lyla-Fischer/zulip/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Lyla-Fischer/zulip/labels{/name}","releases_url":"https://api.github.com/repos/Lyla-Fischer/zulip/releases{/id}","deployments_url":"https://api.github.com/repos/Lyla-Fischer/zulip/deployments","created_at":"2017-06-09T18:17:49Z","updated_at":"2018-04-24T15:23:10Z","pushed_at":"2018-04-24T17:44:42Z","git_url":"git://github.com/Lyla-Fischer/zulip.git","ssh_url":"git@github.com:Lyla-Fischer/zulip.git","clone_url":"https://github.com/Lyla-Fischer/zulip.git","svn_url":"https://github.com/Lyla-Fischer/zulip","homepage":"","size":200513,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"zulip:master","ref":"master","sha":"697fd3c69b1fc8923097f3f152bbd980a44d844d","user":{"login":"zulip","id":4921959,"avatar_url":"https://avatars2.githubusercontent.com/u/4921959?v=4","gravatar_id":"","url":"https://api.github.com/users/zulip","html_url":"https://github.com/zulip","followers_url":"https://api.github.com/users/zulip/followers","following_url":"https://api.github.com/users/zulip/following{/other_user}","gists_url":"https://api.github.com/users/zulip/gists{/gist_id}","starred_url":"https://api.github.com/users/zulip/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zulip/subscriptions","organizations_url":"https://api.github.com/users/zulip/orgs","repos_url":"https://api.github.com/users/zulip/repos","events_url":"https://api.github.com/users/zulip/events{/privacy}","received_events_url":"https://api.github.com/users/zulip/received_events","type":"Organization","site_admin":false},"repo":{"id":43160685,"name":"zulip","full_name":"zulip/zulip","owner":{"login":"zulip","id":4921959,"avatar_url":"https://avatars2.githubusercontent.com/u/4921959?v=4","gravatar_id":"","url":"https://api.github.com/users/zulip","html_url":"https://github.com/zulip","followers_url":"https://api.github.com/users/zulip/followers","following_url":"https://api.github.com/users/zulip/following{/other_user}","gists_url":"https://api.github.com/users/zulip/gists{/gist_id}","starred_url":"https://api.github.com/users/zulip/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zulip/subscriptions","organizations_url":"https://api.github.com/users/zulip/orgs","repos_url":"https://api.github.com/users/zulip/repos","events_url":"https://api.github.com/users/zulip/events{/privacy}","received_events_url":"https://api.github.com/users/zulip/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zulip/zulip","description":"Zulip server - powerful open source team chat","fork":false,"url":"https://api.github.com/repos/zulip/zulip","forks_url":"https://api.github.com/repos/zulip/zulip/forks","keys_url":"https://api.github.com/repos/zulip/zulip/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zulip/zulip/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zulip/zulip/teams","hooks_url":"https://api.github.com/repos/zulip/zulip/hooks","issue_events_url":"https://api.github.com/repos/zulip/zulip/issues/events{/number}","events_url":"https://api.github.com/repos/zulip/zulip/events","assignees_url":"https://api.github.com/repos/zulip/zulip/assignees{/user}","branches_url":"https://api.github.com/repos/zulip/zulip/branches{/branch}","tags_url":"https://api.github.com/repos/zulip/zulip/tags","blobs_url":"https://api.github.com/repos/zulip/zulip/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zulip/zulip/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zulip/zulip/git/refs{/sha}","trees_url":"https://api.github.com/repos/zulip/zulip/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zulip/zulip/statuses/{sha}","languages_url":"https://api.github.com/repos/zulip/zulip/languages","stargazers_url":"https://api.github.com/repos/zulip/zulip/stargazers","contributors_url":"https://api.github.com/repos/zulip/zulip/contributors","subscribers_url":"https://api.github.com/repos/zulip/zulip/subscribers","subscription_url":"https://api.github.com/repos/zulip/zulip/subscription","commits_url":"https://api.github.com/repos/zulip/zulip/commits{/sha}","git_commits_url":"https://api.github.com/repos/zulip/zulip/git/commits{/sha}","comments_url":"https://api.github.com/repos/zulip/zulip/comments{/number}","issue_comment_url":"https://api.github.com/repos/zulip/zulip/issues/comments{/number}","contents_url":"https://api.github.com/repos/zulip/zulip/contents/{+path}","compare_url":"https://api.github.com/repos/zulip/zulip/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zulip/zulip/merges","archive_url":"https://api.github.com/repos/zulip/zulip/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zulip/zulip/downloads","issues_url":"https://api.github.com/repos/zulip/zulip/issues{/number}","pulls_url":"https://api.github.com/repos/zulip/zulip/pulls{/number}","milestones_url":"https://api.github.com/repos/zulip/zulip/milestones{/number}","notifications_url":"https://api.github.com/repos/zulip/zulip/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zulip/zulip/labels{/name}","releases_url":"https://api.github.com/repos/zulip/zulip/releases{/id}","deployments_url":"https://api.github.com/repos/zulip/zulip/deployments","created_at":"2015-09-25T16:37:25Z","updated_at":"2018-04-24T17:00:56Z","pushed_at":"2018-04-24T17:44:45Z","git_url":"git://github.com/zulip/zulip.git","ssh_url":"git@github.com:zulip/zulip.git","clone_url":"https://github.com/zulip/zulip.git","svn_url":"https://github.com/zulip/zulip","homepage":"https://zulip.org/","size":200505,"stargazers_count":7043,"watchers_count":7043,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2161,"mirror_url":null,"archived":false,"open_issues_count":1004,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":2161,"open_issues":1004,"watchers":7043,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zulip/zulip/pulls/9119"},"html":{"href":"https://github.com/zulip/zulip/pull/9119"},"issue":{"href":"https://api.github.com/repos/zulip/zulip/issues/9119"},"comments":{"href":"https://api.github.com/repos/zulip/zulip/issues/9119/comments"},"review_comments":{"href":"https://api.github.com/repos/zulip/zulip/pulls/9119/comments"},"review_comment":{"href":"https://api.github.com/repos/zulip/zulip/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zulip/zulip/pulls/9119/commits"},"statuses":{"href":"https://api.github.com/repos/zulip/zulip/statuses/8d2a50b5b3b9e89ddc47a65d5dabe1c8d469859d"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"timabbott"}}