Skip to content

Commit

Permalink
Add heading links to markdown parser
Browse files Browse the repository at this point in the history
  • Loading branch information
tcbegley committed May 6, 2024
1 parent 0b947bb commit a1cb0b2
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 3 deletions.
14 changes: 13 additions & 1 deletion docs/components_page/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import dash
import dash_bootstrap_components as dbc
from dash import html
from dash import ClientsideFunction, Input, Output, html
from jinja2 import Environment, FileSystemLoader

from .components.table.simple import table_body, table_header # noqa
Expand Down Expand Up @@ -149,6 +149,7 @@ def register_apps():
)
app = dash.Dash(
external_stylesheets=["/static/loading.css"],
external_scripts=["/static/js/clientside.js"],
requests_pathname_prefix=requests_pathname_prefix,
suppress_callback_exceptions=True,
serve_locally=SERVE_LOCALLY,
Expand All @@ -171,6 +172,17 @@ def register_apps():
)
else:
app.layout = parse(app, **kwargs)

app.clientside_callback(
ClientsideFunction(
namespace="clientside", function_name="scrollAfterLoad"
),
# id won't actually be updated, we just want the callback to run
# once Dash has initialised and hydrated the page
Output("url", "id"),
Input("url", "hash"),
)

if slug == "index":
routes["/docs/components"] = app
else:
Expand Down
26 changes: 24 additions & 2 deletions docs/components_page/markdown_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
PROP_NAME_PATTERN = re.compile(r"""(\n- )(\w+?) \(""")
NESTED_PROP_NAME_PATTERN = re.compile(r"""(\n\s+- )(\w+?) \(""")

HEADING_TEMPLATE = """<h{level} id="{id_}" style="scroll-margin-top:60px">
{heading}<a href="#{id_}" class="anchor-link">#</a>
</h{level}>"""


def parse(app, markdown_path, extra_env_vars=None):
extra_env_vars = extra_env_vars or {}
Expand All @@ -46,7 +50,8 @@ def parse(app, markdown_path, extra_env_vars=None):

markdown_blocks = SPLIT_PATTERN.split(raw)
markdown_blocks = [
dcc.Markdown(block.strip()) for block in markdown_blocks
dcc.Markdown(_preprocess_markdown(block), dangerously_allow_html=True)
for block in markdown_blocks
]

examples_docs = EXAMPLE_DOC_PATTERN.findall(raw)
Expand All @@ -55,7 +60,24 @@ def parse(app, markdown_path, extra_env_vars=None):
]

content.extend(_interleave(markdown_blocks, examples_docs))
return html.Div(content, key=str(markdown_path))
return html.Div([dcc.Location(id="url")] + content, key=str(markdown_path))


def _preprocess_markdown(text):
text = text.strip()
lines = text.split("\n")
new_lines = []
for line in lines:
if line.startswith("#"):
level, heading = line.split(" ", 1)
level = level.count("#")
id_ = heading.replace(" ", "-").lower()
new_lines.append(
HEADING_TEMPLATE.format(level=level, id_=id_, heading=heading)
)
else:
new_lines.append(line)
return "\n".join(new_lines)


def _parse_block(block, app, extra_env_vars):
Expand Down
13 changes: 13 additions & 0 deletions docs/static/docs.css
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,16 @@ span.hljs-meta {
.superhero-demo .dropdown-divider {
border-top: 1px solid rgba(0, 0, 0, 0.15);
}

.anchor-link {
color: var(--bs-secondary);
opacity: 0.5;
margin-left: 0.5rem;
text-decoration: none;
transition: color 0.15s ease-in-out, opacity 0.15s ease-in-out;
}

.anchor-link:hover, :hover>.anchor-link {
color: var(--bs-primary);
opacity: 1;
}
22 changes: 22 additions & 0 deletions docs/static/js/clientside.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const delays = [100, 100, 300, 500, 1000, 2000];

function scrollWithRetry(id, idx) {
const targetElement = document.getElementById(id);
if (targetElement) {
targetElement.scrollIntoView();
} else if (idx < delays.length) {
setTimeout(() => scrollWithRetry(id, idx + 1), delays[idx]);
}
}

if (!window.dash_clientside) {
window.dash_clientside = {};
}
window.dash_clientside.clientside = {
scrollAfterLoad: function(hash) {
if (hash) {
scrollWithRetry(hash.slice(1), 0);
}
return window.dash_clientside.no_update;
}
};

0 comments on commit a1cb0b2

Please sign in to comment.