diff --git a/docs/extract-rst-targets.py b/docs/extract-rst-targets.py index b349eb385..544648589 100755 --- a/docs/extract-rst-targets.py +++ b/docs/extract-rst-targets.py @@ -6,6 +6,7 @@ import re from typing import Dict, Iterator tgt_pat = re.compile(r'^.. _(\S+?):$', re.MULTILINE) +title_pat = re.compile('^(.+)\n[-=^#*]{5,}$', re.MULTILINE) def find_explicit_targets(text: str) -> Iterator[str]: @@ -13,8 +14,15 @@ def find_explicit_targets(text: str) -> Iterator[str]: yield m.group(1) +def find_page_title(text: str) -> str: + for m in title_pat.finditer(text): + return m.group(1) + return '' + + def main() -> Dict[str, str]: refs = {} + docs = {} base = os.path.dirname(os.path.abspath(__file__)) for dirpath, dirnames, filenames in os.walk(base): if 'generated' in dirnames: @@ -25,6 +33,7 @@ def main() -> Dict[str, str]: raw = stream.read() href = os.path.relpath(stream.name, base).replace(os.sep, '/') href = href.rpartition('.')[0] + '/' + docs[href.rstrip('/')] = find_page_title(raw) first_line = raw.lstrip('\n').partition('\n')[0] first_target_added = False for explicit_target in find_explicit_targets(raw): @@ -37,7 +46,7 @@ def main() -> Dict[str, str]: refs[explicit_target] = href continue refs[explicit_target] = href + f'#{explicit_target.replace("_", "-")}' - return {'ref': refs} + return {'ref': refs, 'doc': docs} if __name__ == '__main__': diff --git a/kitty/cli.py b/kitty/cli.py index cbf7ce963..4d2ae181c 100644 --- a/kitty/cli.py +++ b/kitty/cli.py @@ -169,8 +169,13 @@ def file(x: str) -> str: @role def doc(x: str) -> str: t, q = text_and_target(x) - url = f'kitty+doc://{hostname()}/{q.lstrip("/")}' - return hyperlink_for_url(url, t) + if t == q: + from .conf.types import ref_map + m = ref_map()['doc'] + q = q.strip('/') + if q in m: + x = f'{m[q]} <{t}>' + return ref_hyperlink(x, 'doc-') @run_once @@ -197,17 +202,17 @@ def ac(x: str) -> str: @role def iss(x: str) -> str: - return ref_hyperlink(x, 'github-issue-') + return ref_hyperlink(x, 'issues-') @role def pull(x: str) -> str: - return ref_hyperlink(x, 'github-pr-') + return ref_hyperlink(x, 'pull-') @role def disc(x: str) -> str: - return ref_hyperlink(x, 'github-discussion-') + return ref_hyperlink(x, 'discussions-') OptionSpecSeq = List[Union[str, OptionDict]] diff --git a/kitty/conf/types.py b/kitty/conf/types.py index 5b89005df..8538cc3fa 100644 --- a/kitty/conf/types.py +++ b/kitty/conf/types.py @@ -55,6 +55,7 @@ def ref_map() -> Dict[str, Dict[str, str]]: def resolve_ref(ref: str, website_url: Callable[[str], str] = website_url) -> str: m = ref_map() href = m['ref'].get(ref, '') + prefix, rest = ref.partition('-')[::2] if href: pass elif ref.startswith('conf-kitty-'): @@ -67,20 +68,15 @@ def resolve_ref(ref: str, website_url: Callable[[str], str] = website_url) -> st href = "remote-control/#at_" + base.replace('_', '-') elif ref.startswith('action-group-'): href = f'actions/#{ref}' - elif ref.startswith('action-'): - frag = ref.partition('-')[-1].replace('_', '-') - href = f'actions/#{frag}' - elif ref.startswith('term-') or ref.startswith('envvar-'): + elif prefix == 'action': + href = f'actions/#{rest.replace("_", "-")}' + elif prefix in ('term', 'envvar'): href = 'glossary/#' + ref - elif ref.startswith('github-'): - href = 'https://github.com/kovidgoyal/kitty' - parts = ref.split('-') - if parts[1] == 'issue': - href = f'{href}/issues/{parts[2]}' - elif parts[1] == 'pr': - href = f'{href}/pull/{parts[2]}' - elif parts[1] == 'discussion': - href = f'{href}/discussions/{parts[2]}' + elif prefix == 'doc': + href = rest.lstrip('/') + elif prefix in ('issues', 'pull', 'discussions'): + t, num = ref.partition(':')[::2] + href = f'https://github.com/kovidgoyal/kitty/{prefix}/{rest}' if not (href.startswith('https://') or href.startswith('http://')): href = website_url(href) return href diff --git a/kitty/utils.py b/kitty/utils.py index 0ebce949e..0a30f4425 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -1084,6 +1084,8 @@ def docs_url(which: str = '', local_docs_root: Optional[str] = '') -> str: if frag.startswith('ref='): ref = frag[4:] which = resolve_ref(ref, lambda x: x) + if which.startswith('https://') or which.startswith('http://'): + return which base, frag = which.partition('#')[::2] base = base.strip('/') if ld: diff --git a/kitty_tests/check_build.py b/kitty_tests/check_build.py index abb5d1346..e8cb7aebd 100644 --- a/kitty_tests/check_build.py +++ b/kitty_tests/check_build.py @@ -90,10 +90,12 @@ class TestBuild(BaseTest): t('#ref=conf-kitten-ssh-xxx', f'kittens/ssh{suffix}#conf-kitten-ssh-xxx') t('#ref=at_close_tab', f'remote-control{suffix}#at_close-tab') t('#ref=action-copy', f'actions{suffix}#copy') + t('#ref=doc-/marks', f'marks{suffix}') run_tests(partial(docs_url, local_docs_root='/docs'), 'file:///docs/') w = website_url() run_tests(partial(docs_url, local_docs_root=None), w, '/') + self.ae(docs_url('#ref=issues-123'), 'https://github.com/kovidgoyal/kitty/issues/123') def main() -> None: