Skip to content

Commit e76e1c4

Browse files
authored
Merge pull request #609 from Fortran-FOSS-Programmers/fix-absolute-paths-2
Ensure all internal links are relative
2 parents 90a393a + cc2ac64 commit e76e1c4

35 files changed

+369
-258
lines changed

example/pages/subdir/subsubpage.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ title: Subpage in subdirectory
44
This page is deeper in the hierarchy. You can use `|page|` in URLs to
55
link to other places in the page hierarchy, [such as this other
66
subpage](|page|/subpage1.html)
7+
8+
You can link to the API documentation with the Ford `[[link]]` style:
9+
[[ford_test_program]]

ford/__init__.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,6 @@ def main(proj_data: ProjectSettings, proj_docs: str):
415415
)
416416
sys.exit(1)
417417

418-
base_url = ".." if proj_data.relative else proj_data.project_url
419-
420418
print(" Correlating information from different parts of your project...")
421419
correlate_time_start = time.time()
422420
project.correlate()
@@ -437,20 +435,17 @@ def main(proj_data: ProjectSettings, proj_docs: str):
437435

438436
md = MetaMarkdown(
439437
proj_data.md_base_dir,
438+
base_url=proj_data.project_url,
440439
extensions=proj_data.md_extensions,
441440
aliases=aliases,
442441
project=project,
443-
relative=proj_data.relative,
444-
base_url=proj_data.project_url,
445442
)
446443

447444
# Convert the documentation from Markdown to HTML
448-
proj_docs = md.reset().convert(proj_docs)
449-
project.markdown(md, base_url)
445+
proj_docs = md.reset().convert(proj_docs, path=proj_data.project_url)
446+
project.markdown(md)
450447

451448
# Convert summaries and descriptions to HTML
452-
if proj_data.relative:
453-
ford.sourceform.set_base_url(".")
454449
if proj_data.summary is not None:
455450
proj_data.summary = md.convert(proj_data.summary)
456451
if proj_data.author_description is not None:

ford/_markdown.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ class MetaMarkdown(Markdown):
3636
Dictionary of text aliases
3737
project :
3838
Ford project instance
39-
relative :
40-
Should internal URLs be relative
4139
base_url :
4240
Base/project URL for relative links (required if
4341
``relative`` is True)
@@ -47,12 +45,11 @@ class MetaMarkdown(Markdown):
4745
def __init__(
4846
self,
4947
md_base: PathLike = ".",
48+
base_url: PathLike = ".",
5049
extensions: Optional[List[Union[str, Extension]]] = None,
5150
extension_configs: Optional[Dict[str, Dict]] = None,
5251
aliases: Optional[Dict[str, str]] = None,
5352
project: Optional[Project] = None,
54-
relative: bool = False,
55-
base_url: Optional[PathLike] = None,
5653
):
5754
"""make thing"""
5855

@@ -71,10 +68,9 @@ def __init__(
7168
if project is not None:
7269
default_extensions.append(FordLinkExtension(project=project))
7370

74-
if relative:
75-
if base_url is None:
76-
raise ValueError("Expected path for base_url, got None")
77-
default_extensions.append(RelativeLinksExtension(base_url=base_url))
71+
self.base_url = Path(base_url)
72+
if base_url != ".":
73+
default_extensions.append(RelativeLinksExtension())
7874

7975
if extensions is None:
8076
extensions = []
@@ -116,7 +112,14 @@ def convert(
116112
"""
117113

118114
self.current_context = context
119-
self.current_path = path
115+
if (
116+
path is None
117+
and context is not None
118+
and (url := context.get_url()) is not None
119+
):
120+
self.current_path = self.base_url / Path(url).parent
121+
else:
122+
self.current_path = path
120123
return super().convert(source)
121124

122125

@@ -235,7 +238,14 @@ def find_child(context):
235238
link.text = name
236239
return link
237240

238-
link.attrib["href"] = item.get_url()
241+
if (item_url := item.get_url()) is None:
242+
# This is really to keep mypy happy
243+
raise RuntimeError(f"Found item {name} but no url")
244+
245+
# Make sure links are relative to base url
246+
full_url = self.md.base_url / item_url
247+
rel_url = relpath(full_url, self.md.current_path)
248+
link.attrib["href"] = str(rel_url)
239249
link.text = item.name
240250
return link
241251

@@ -262,8 +272,8 @@ class RelativeLinksTreeProcessor(Treeprocessor):
262272

263273
md: MetaMarkdown
264274

265-
def __init__(self, md: MetaMarkdown, base_url: Path):
266-
self.base_url = base_url.resolve()
275+
def __init__(self, md: MetaMarkdown):
276+
self.base_url = md.base_url.resolve()
267277
super().__init__(md)
268278

269279
def _fix_attrib(self, tag: Element, attrib: str):
@@ -290,11 +300,7 @@ class RelativeLinksExtension(Extension):
290300
"""Markdown extension to register `RelativeLinksTreeProcessor`"""
291301

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

296305
def extendMarkdown(self, md: MetaMarkdown): # type: ignore[override]
297-
base_url: Path = self.getConfig("base_url")
298-
md.treeprocessors.register(
299-
RelativeLinksTreeProcessor(md, base_url=base_url), "relative_links", 5
300-
)
306+
md.treeprocessors.register(RelativeLinksTreeProcessor(md), "relative_links", 5)

ford/external_project.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def obj2dict(intObj):
6161
return None
6262
extDict = {
6363
"name": intObj.name,
64-
"external_url": intObj.get_url(),
64+
"external_url": f"./{intObj.get_url()}",
6565
"obj": intObj.obj,
6666
}
6767
if hasattr(intObj, "proctype"):

ford/fortran_project.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from ford.console import warn
3333
from ford.external_project import load_external_modules
3434
from ford.utils import ProgressBar
35-
import ford.sourceform
3635
from ford.sourceform import (
3736
_find_in_list,
3837
FortranBase,
@@ -340,11 +339,6 @@ def filter_modules(entity) -> List[FortranModule]:
340339
if not isinstance(container, str):
341340
container.prune()
342341

343-
if self.settings.project_url == ".":
344-
url = ".."
345-
else:
346-
url = self.settings.project_url
347-
348342
# Mapping of various entity containers in code units to the
349343
# corresponding container in the project
350344
CONTAINERS = {
@@ -386,11 +380,10 @@ def sum_lines(*argv, **kwargs):
386380
self.prog_lines = sum_lines(self.programs)
387381
self.block_lines = sum_lines(self.blockdata)
388382

389-
def markdown(self, md, base_url=".."):
383+
def markdown(self, md):
390384
"""
391385
Process the documentation with Markdown to produce HTML.
392386
"""
393-
ford.sourceform.set_base_url(base_url)
394387
if self.settings.warn:
395388
print()
396389

0 commit comments

Comments
 (0)