Skip to content

Commit

Permalink
Merge pull request readthedocs#166 from gibfahn/allow_overwriting_lin…
Browse files Browse the repository at this point in the history
…k_schemes

Add `accepted_url_schemes` option to allow toplevel refs
  • Loading branch information
ericholscher authored Aug 9, 2019
2 parents 59dcaaa + 0e96d97 commit 04580ae
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ AutoStructify comes with the following options. See [http://recommonmark.readthe
* __enable_inline_math__: enable the Inline Math feature.
* __enable_eval_rst__: enable the evaluate embedded reStructuredText feature.
* __url_resolver__: a function that maps a existing relative position in the document to a http link
* __known_url_schemes__: a list of url schemes to treat as URLs, schemes not in this list will be assumed to be Sphinx cross-references.
Defaults to `None`, which means treat all URL schemes as URLs.
Example: `['http', 'https', 'mailto']`

## Development

Expand Down
21 changes: 20 additions & 1 deletion recommonmark/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@ class CommonMarkParser(parsers.Parser):
supported = ('md', 'markdown')
translate_section_name = None

default_config = {
'known_url_schemes': None,
}

def __init__(self):
self._level_to_elem = {}

def parse(self, inputstring, document):
self.document = document
self.current_node = document
self.config = self.default_config.copy()
try:
new_cfg = self.document.settings.env.config.recommonmark_config
self.config.update(new_cfg)
except AttributeError:
pass
self.setup_parse(inputstring, document)
self.setup_sections()
parser = Parser()
Expand Down Expand Up @@ -153,7 +163,16 @@ def visit_link(self, mdnode):
next_node = ref_node

url_check = urlparse(destination)
if not url_check.scheme and not url_check.fragment:
# If there's not a url scheme (e.g. 'https' for 'https:...' links),
# or there is a scheme but it's not in the list of known_url_schemes,
# then assume it's a cross-reference and pass it to Sphinx as an `:any:` ref.
known_url_schemes = self.config.get('known_url_schemes')
if known_url_schemes:
scheme_known = url_check.scheme in known_url_schemes
else:
scheme_known = bool(url_check.scheme)

if not url_check.fragment and not scheme_known:
wrap_node = addnodes.pending_xref(
reftarget=unquote(destination),
reftype='any',
Expand Down
1 change: 1 addition & 0 deletions recommonmark/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __init__(self, *args, **kwargs):
'enable_inline_math': True,
'commonmark_suffixes': ['.md'],
'url_resolver': lambda x: x,
'known_url_schemes': None,
}

def parse_ref(self, ref):
Expand Down
41 changes: 41 additions & 0 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class TestParsing(unittest.TestCase):
def assertParses(self, source, expected, alt=False): # noqa
parser = CommonMarkParser()
parser.parse(dedent(source), new_document('<string>'))
self.maxDiff = None
self.assertMultiLineEqual(
dedent(expected).lstrip(),
dedent(parser.document.asdom().toprettyxml(indent=' ')),
Expand Down Expand Up @@ -223,6 +224,46 @@ def test_links(self):
"""
)

def test_known_schemes(self):
self.assertParses(
"""
[https link](https://example.com)
[http link](http://example.com)
[mailto link](mailto:[email protected])
[custom scheme](custom:example.com)
[ref link](path/to/file:heading)
[ref link with spaces](<path/to/file:heading with spaces>)
""",
"""
<?xml version="1.0" ?>
<document source="&lt;string&gt;">
<paragraph>
<reference refuri="https://example.com">https link</reference>
<reference refuri="http://example.com">http link</reference>
<reference refuri="mailto:[email protected]">mailto link</reference>
<reference refuri="custom:example.com">custom scheme</reference>
<pending_xref refdomain="None" refexplicit="True" reftarget="path/to/file:heading" reftype="any" refwarn="True">
<reference refuri="path/to/file:heading">ref link</reference>
</pending_xref>
<pending_xref refdomain="None" refexplicit="True" reftarget="path/to/file:heading with spaces" reftype="any" refwarn="True">
<reference refuri="path/to/file:heading%20with%20spaces">ref link with spaces</reference>
</pending_xref>
</paragraph>
</document>
"""
)
pass

def test_image(self):
self.assertParses(
"""
Expand Down

0 comments on commit 04580ae

Please sign in to comment.