Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure all internal links are relative #609

Merged
merged 12 commits into from
Jan 4, 2024
3 changes: 3 additions & 0 deletions example/pages/subdir/subsubpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ title: Subpage in subdirectory
This page is deeper in the hierarchy. You can use `|page|` in URLs to
link to other places in the page hierarchy, [such as this other
subpage](|page|/subpage1.html)

You can link to the API documentation with the Ford `[[link]]` style:
[[ford_test_program]]
11 changes: 3 additions & 8 deletions ford/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,6 @@ def main(proj_data: ProjectSettings, proj_docs: str):
)
sys.exit(1)

base_url = ".." if proj_data.relative else proj_data.project_url

print(" Correlating information from different parts of your project...")
correlate_time_start = time.time()
project.correlate()
Expand All @@ -434,20 +432,17 @@ def main(proj_data: ProjectSettings, proj_docs: str):

md = MetaMarkdown(
proj_data.md_base_dir,
base_url=proj_data.project_url,
extensions=proj_data.md_extensions,
aliases=aliases,
project=project,
relative=proj_data.relative,
base_url=proj_data.project_url,
)

# Convert the documentation from Markdown to HTML
proj_docs = md.reset().convert(proj_docs)
project.markdown(md, base_url)
proj_docs = md.reset().convert(proj_docs, path=proj_data.project_url)
project.markdown(md)

# Convert summaries and descriptions to HTML
if proj_data.relative:
ford.sourceform.set_base_url(".")
if proj_data.summary is not None:
proj_data.summary = md.convert(proj_data.summary)
if proj_data.author_description is not None:
Expand Down
40 changes: 23 additions & 17 deletions ford/_markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ class MetaMarkdown(Markdown):
Dictionary of text aliases
project :
Ford project instance
relative :
Should internal URLs be relative
base_url :
Base/project URL for relative links (required if
``relative`` is True)
Expand All @@ -46,12 +44,11 @@ class MetaMarkdown(Markdown):
def __init__(
self,
md_base: PathLike = ".",
base_url: PathLike = ".",
extensions: Optional[List[Union[str, Extension]]] = None,
extension_configs: Optional[Dict[str, Dict]] = None,
aliases: Optional[Dict[str, str]] = None,
project: Optional[Project] = None,
relative: bool = False,
base_url: Optional[PathLike] = None,
):
"""make thing"""

Expand All @@ -70,10 +67,9 @@ def __init__(
if project is not None:
default_extensions.append(FordLinkExtension(project=project))

if relative:
if base_url is None:
raise ValueError("Expected path for base_url, got None")
default_extensions.append(RelativeLinksExtension(base_url=base_url))
self.base_url = Path(base_url)
if base_url != ".":
default_extensions.append(RelativeLinksExtension())

if extensions is None:
extensions = []
Expand Down Expand Up @@ -115,7 +111,14 @@ def convert(
"""

self.current_context = context
self.current_path = path
if (
path is None
and context is not None
and (url := context.get_url()) is not None
):
self.current_path = self.base_url / Path(url).parent
else:
self.current_path = path
return super().convert(source)


Expand Down Expand Up @@ -228,7 +231,14 @@ def find_child(context):
link.text = name
return link

link.attrib["href"] = item.get_url()
if (item_url := item.get_url()) is None:
# This is really to keep mypy happy
raise RuntimeError(f"Found item {name} but no url")

# Make sure links are relative to base url
full_url = self.md.base_url / item_url
rel_url = relpath(full_url, self.md.current_path)
link.attrib["href"] = str(rel_url)
link.text = item.name
return link

Expand All @@ -255,8 +265,8 @@ class RelativeLinksTreeProcessor(Treeprocessor):

md: MetaMarkdown

def __init__(self, md: MetaMarkdown, base_url: Path):
self.base_url = base_url.resolve()
def __init__(self, md: MetaMarkdown):
self.base_url = md.base_url.resolve()
super().__init__(md)

def _fix_attrib(self, tag: Element, attrib: str):
Expand All @@ -283,11 +293,7 @@ class RelativeLinksExtension(Extension):
"""Markdown extension to register `RelativeLinksTreeProcessor`"""

def __init__(self, **kwargs):
self.config = {"base_url": [kwargs["base_url"], "Base URL of project"]}
super().__init__(**kwargs)

def extendMarkdown(self, md: MetaMarkdown): # type: ignore[override]
base_url: Path = self.getConfig("base_url")
md.treeprocessors.register(
RelativeLinksTreeProcessor(md, base_url=base_url), "relative_links", 5
)
md.treeprocessors.register(RelativeLinksTreeProcessor(md), "relative_links", 5)
2 changes: 1 addition & 1 deletion ford/external_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def obj2dict(intObj):
return None
extDict = {
"name": intObj.name,
"external_url": intObj.get_url(),
"external_url": f"./{intObj.get_url()}",
"obj": intObj.obj,
}
if hasattr(intObj, "proctype"):
Expand Down
9 changes: 1 addition & 8 deletions ford/fortran_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
from ford.console import warn
from ford.external_project import load_external_modules
from ford.utils import ProgressBar
import ford.sourceform
from ford.sourceform import (
_find_in_list,
FortranBase,
Expand Down Expand Up @@ -340,11 +339,6 @@ def filter_modules(entity) -> List[FortranModule]:
if not isinstance(container, str):
container.prune()

if self.settings.project_url == ".":
url = ".."
else:
url = self.settings.project_url

# Mapping of various entity containers in code units to the
# corresponding container in the project
CONTAINERS = {
Expand Down Expand Up @@ -386,11 +380,10 @@ def sum_lines(*argv, **kwargs):
self.prog_lines = sum_lines(self.programs)
self.block_lines = sum_lines(self.blockdata)

def markdown(self, md, base_url=".."):
def markdown(self, md):
"""
Process the documentation with Markdown to produce HTML.
"""
ford.sourceform.set_base_url(base_url)
if self.settings.warn:
print()

Expand Down
Loading