added backlink generation

This commit is contained in:
Amy G. Bowersox 2024-08-09 18:32:26 -06:00
parent 1842d33358
commit ba4b6f2cf0
3 changed files with 31 additions and 3 deletions

View File

@ -325,6 +325,8 @@ class ObsidianLinks(Extension):
if not text: if not text:
text = contents text = contents
if node: if node:
# record a backlink from the current node to the found one
node.backlinks.add(self._context.current_node)
return node.link_target(self._context.url_prefix, return node.link_target(self._context.url_prefix,
self._context.current_node if self._context.relative_links else None), text self._context.current_node if self._context.relative_links else None), text
return None, text return None, text

View File

@ -12,8 +12,7 @@ from .tree import SourceNode
"""The default template used to render Markdown data.""" """The default template used to render Markdown data."""
DEFAULT_TEMPLATE = """ DEFAULT_TEMPLATE = """<html>
<html>
<head> <head>
<title>{{ title }}</title> <title>{{ title }}</title>
<link rel="stylesheet" href="{{ default_stylesheet }}"/> <link rel="stylesheet" href="{{ default_stylesheet }}"/>
@ -21,6 +20,19 @@ DEFAULT_TEMPLATE = """
<body> <body>
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
{{ text }} {{ text }}
{% if backlinks|length > 0 %}
<div class="generated-header">
<hr />
<span>Links to this page</span>
</div>
<div class="backlink-items-container">
{% for item in backlinks %}
<div class="backlink-item">
<a class="internal-link" href="{{ item.link }}">{{ item.title }}</a>
</div>
{% endfor %}
</div>
{% endif %}
</body> </body>
</html> </html>
""" """
@ -68,6 +80,13 @@ def template_vars(node: SourceNode, ctxt: Context) -> dict[str, Any]:
""" """
tvars = node.make_vars() tvars = node.make_vars()
# Compute backlinks for this node.
backlinks = sorted(node.backlinks, key=lambda n: n.page_title)
tvars['backlinks'] = [{'title': n.page_title,
'link': n.link_target(ctxt.url_prefix, node if ctxt.relative_links else None)}
for n in backlinks]
# Add reference to the default stylesheet.
if ctxt.relative_links: if ctxt.relative_links:
stylesheet_path = ctxt.source_dir / STYLESHEET_NAME stylesheet_path = ctxt.source_dir / STYLESHEET_NAME
rel_path = ctxt.source_dir / node.path rel_path = ctxt.source_dir / node.path

View File

@ -29,6 +29,7 @@ class SourceNode:
Attributes: Attributes:
metadata (dict[str, Any]): The metadata from the current node. metadata (dict[str, Any]): The metadata from the current node.
text (str): The parsed HTML text of the current node. text (str): The parsed HTML text of the current node.
backlinks (set[SourceNode]): Set of nodes that link to this one.
""" """
def __init__(self, root: Path, path: Path, is_dir: bool) -> None: def __init__(self, root: Path, path: Path, is_dir: bool) -> None:
""" """
@ -45,6 +46,7 @@ class SourceNode:
self._is_md = path.match(MARKDOWN_PAT) self._is_md = path.match(MARKDOWN_PAT)
self.metadata: dict[str, Any] = {} self.metadata: dict[str, Any] = {}
self.text: str | None = None self.text: str | None = None
self.backlinks: set[Any] = set()
def __str__(self) -> str: def __str__(self) -> str:
"""Returns the string representation of the nmode.""" """Returns the string representation of the nmode."""
@ -70,6 +72,11 @@ class SourceNode:
"""Returns the root path this node is under.""" """Returns the root path this node is under."""
return self._root return self._root
@property
def page_title(self) -> str:
"""Returns the standard page title for this node."""
return self._path.stem
def target_file(self, dest_dir: Path) -> Path: def target_file(self, dest_dir: Path) -> Path:
""" """
Computes the path of the target file as it will be written to the destination directory. Computes the path of the target file as it will be written to the destination directory.
@ -143,7 +150,7 @@ class SourceNode:
""" """
return { return {
"text": self.text, "text": self.text,
"title": self._path.stem "title": self.page_title
} }