Feature Suggestion: Reference parts of source files in code blocks
001ben opened this issue · comments
Contribution guidelines
- I've read the contribution guidelines and wholeheartedly agree
I want to suggest an idea and checked that ...
- ... to my best knowledge, my idea wouldn't break something for other users
- ... the documentation does not mention anything about my idea
- ... there are no open or closed issues that are related to my idea
Description
The mkdocs framework is incredibly useful, especially to add documents to technical projects where we may refer to parts of an existing codebase as we're documenting.
Github supports references to regions of source files where where it provides a link to the file, and shows the snippet of code in issues/PR's like so:
Lines 21 to 23 in 415daf6
Referencing code in a similar way would be an incredible value add for technical documentation, currently i don't think it's straightforward to achieve this.
Code blocks + snippets currently would let you include an entire external file inside a highlighted code block like so:
```python title="src/some_file.py"
--8<-- "src/some_file.py"
```
From my limited knowledge I believe the following functionality is missing:
- hyperlinking from the title of a fenced code block
- limiting the output from the snippet to only include a subset of lines from the file
- bonus: the additional fancy output which displays the line numbers and commit SHA
There have been a number of previous issues/discussions around this sort of functionality, including:
Previous discussions note that some of this functionality is more related to markdown processing, but potentially there is some functionality - i.e. potentially title hyperlinking/formatting, which might need to live here?
Use Cases
This feature would assist documenting and explaining source code within technical projects
Screenshots / Mockups
No response
Thanks for suggesting. As you already said, this is in large parts beyond the scope of this project, but besides the simple solutions involving Snippets, there's also mkdocstrings by @pawamoy, with which I'm working closely. We're planning to improve interop between mkdocstrings and Material for MkDocs in the future, but we're currently still in ideation phase. The things you mentioned are largely already supported by mkdocstrings, though. I invite you to check out the project and deepen the discussion over at their repository!
I'm closing this issue, as there are no actionables for us.
Ah fantastic! thank you for the heads up :D
I've build a small workaround to implement this using mkdocs-simple-hooks
package:
import re
import urllib.request
def replacer(match):
filename = f'{match.group(3)}.{match.group(4)}'
url = f'https://raw.githubusercontent.com/{match.group(1)}/{match.group(2)}/{filename}'
code = urllib.request.urlopen(url).read().decode('utf-8')
return '\n'.join(
[f'``` {match.group(4)} title="{filename}"'] +
code.split('\n')[int(match.group(5)) - 1:int(match.group(6))] +
['```', f'View at [GitHub]({match.group(0)})']
)
def page_markdown(markdown, **kwargs):
return re.sub(
re.compile(
r'^https://github.com/([\w/\-]+)/blob/([0-9a-f]+)/([\w\d\-/\.]+)\.(\w+)#L(\d+)-L(\d+)$',
re.MULTILINE,
),
replacer,
markdown,
)
It is applied in aeternity/aepp-sdk-js#1617
I've build a small workaround to implement this using
mkdocs-simple-hooks
package:import re import urllib.request def replacer(match): filename = f'{match.group(3)}.{match.group(4)}' url = f'https://raw.githubusercontent.com/{match.group(1)}/{match.group(2)}/{filename}' code = urllib.request.urlopen(url).read().decode('utf-8') return '\n'.join( [f'``` {match.group(4)} title="{filename}"'] + code.split('\n')[int(match.group(5)) - 1:int(match.group(6))] + ['```', f'View at [GitHub]({match.group(0)})'] ) def page_markdown(markdown, **kwargs): return re.sub( re.compile( r'^https://github.com/([\w/\-]+)/blob/([0-9a-f]+)/([\w\d\-/\.]+)\.(\w+)#L(\d+)-L(\d+)$', re.MULTILINE, ), replacer, markdown, )It is applied in aeternity/aepp-sdk-js#1617
Hey dude, really appreciatte the stuff you did there, also been trying out your solution, but unfortunately they don't seem to work inside of admonitions, i'd gladly appreciatte if you could maybe guide me to the right direction here
@MetalKnight56 It needs to preserve spacing of the original url, here is an updated hook:
import re
import urllib.request
def replacer(match):
filename = f"{match.group('filename')}.{match.group('extension')}"
url = f"https://raw.githubusercontent.com/{match.group('user')}/{match.group('commit')}/{filename}"
code = urllib.request.urlopen(url).read().decode('utf-8')
extension = 'js' if match.group('extension') == 'vue' else match.group('extension')
spacing = match.group('spacing')
return '\n'.join(
[f'{spacing}``` {extension} title="{filename}"'] +
list(map(
lambda x: spacing + x,
code.split('\n')[int(match.group('begin')) - 1:int(match.group('end'))],
)) +
[f'{spacing}```', f'{spacing}View at [GitHub]({match.group(0)})']
)
def page_markdown(markdown, **kwargs):
return re.sub(
re.compile(
r'^(?P<spacing>[ ]*)https://github.com/(?P<user>[\w/\-]+)/blob/(?P<commit>[0-9a-f]+)/(?P<filename>[\w\d\-/\.]+)\.(?P<extension>\w+)#L(?P<begin>\d+)-L(?P<end>\d+)$',
re.MULTILINE,
),
replacer,
markdown,
)
!!! note "Phasellus posuere in sem ut cursus"
Test
https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/StoreAeSdkPlugin.js#L34-L36