-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
145 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Tree | ||
|
||
Markdown Exec provides a `tree` formatter that can be used | ||
to render file-system trees easily: | ||
|
||
````md exec="1" source="tabbed-left" tabs="Markdown|Rendered" | ||
```tree | ||
root1 | ||
file1 | ||
dir1 | ||
file | ||
dir2 | ||
file1 | ||
file2 | ||
file2 | ||
file3 | ||
root2 | ||
file1 | ||
``` | ||
```` | ||
|
||
By default, the language used for syntax highlight is `bash`. | ||
It means you can add comments with `#`: | ||
|
||
````md exec="1" source="tabbed-left" tabs="Markdown|Rendered" | ||
```tree | ||
root1 # comment 1 | ||
file1 | ||
dir1 | ||
file | ||
dir2 | ||
file1 # comment 2 | ||
file2 # comment 3 | ||
file2 | ||
file3 | ||
root2 | ||
file1 | ||
``` | ||
```` | ||
|
||
You can change the syntax highlight language with the `result` option: | ||
|
||
````md exec="1" source="tabbed-left" tabs="Markdown|Rendered" | ||
```tree result="javascript" | ||
root1 // comment 1 | ||
file1 | ||
dir1 | ||
file | ||
dir2 | ||
file1 // comment 2 | ||
file2 // comment 3 | ||
file2 | ||
file3 | ||
root2 | ||
file1 | ||
``` | ||
```` | ||
|
||
You can force an entry to be displayed as a directory instead of a regular file | ||
by appending a trailing slash to the name: | ||
|
||
````md exec="1" source="tabbed-left" tabs="Markdown|Rendered" | ||
```tree | ||
root1 | ||
dir1/ | ||
dir2/ | ||
dir3/ | ||
``` | ||
```` | ||
|
||
It is recommended to always append trailing slashes to directory anyway. | ||
|
||
WARNING: **Limitation** | ||
Spaces in file names are not supported when searching for a trailing slash. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
"""Formatter for file-system trees.""" | ||
|
||
from __future__ import annotations | ||
|
||
from textwrap import dedent | ||
from typing import Any | ||
|
||
from markdown import Markdown | ||
|
||
from markdown_exec.rendering import code_block, markdown | ||
|
||
|
||
def _rec_build_tree(lines: list[str], parent: list, offset: int, base_indent: int): | ||
while offset < len(lines): | ||
line = lines[offset] | ||
lstripped = line.lstrip() | ||
indent = len(line) - len(lstripped) | ||
if indent == base_indent: | ||
parent.append((lstripped, [])) | ||
offset += 1 | ||
elif indent > base_indent: | ||
offset = _rec_build_tree(lines, parent[-1][1], offset, indent) | ||
else: | ||
return offset | ||
return offset | ||
|
||
|
||
def _build_tree(code: str) -> list[tuple[str, list]]: | ||
lines = dedent(code.strip()).split("\n") | ||
root_layer: list[tuple[str, list]] = [] | ||
_rec_build_tree(lines, root_layer, 0, 0) | ||
return root_layer | ||
|
||
|
||
def _rec_format_tree(tree, root=True) -> list[str]: # noqa: WPS231 | ||
lines = [] | ||
n_items = len(tree) | ||
for index, node in enumerate(tree): | ||
last = index == n_items - 1 | ||
prefix = "" if root else f"{'└' if last else '├'}── " # noqa: WPS509 | ||
if node[1]: | ||
lines.append(f"{prefix}📁 {node[0]}") | ||
sublines = _rec_format_tree(node[1], root=False) | ||
if root: | ||
lines.extend(sublines) | ||
else: | ||
indent_char = " " if last else "│" | ||
lines.extend([f"{indent_char} {line}" for line in sublines]) | ||
else: | ||
name = node[0].split()[0] | ||
icon = "📁" if name.endswith("/") else "📄" | ||
lines.append(f"{prefix}{icon} {node[0]}") | ||
return lines | ||
|
||
|
||
def _format_tree( # noqa: WPS231 | ||
code: str, | ||
md: Markdown, | ||
html: bool, | ||
source: str, | ||
result: str, | ||
tabs: tuple[str, str], | ||
**options: Any, | ||
) -> str: | ||
markdown.setup(md) | ||
output = "\n".join(_rec_format_tree(_build_tree(code))) | ||
return markdown.convert(code_block(result or "bash", output)) |