diff --git a/docs/api/ford._markdown.rst b/docs/api/ford._markdown.rst new file mode 100644 index 00000000..0107889a --- /dev/null +++ b/docs/api/ford._markdown.rst @@ -0,0 +1,7 @@ +ford._markdown module +========================== + +.. automodule:: ford._markdown + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/ford.rst b/docs/api/ford.rst index 9dffa186..719e4915 100644 --- a/docs/api/ford.rst +++ b/docs/api/ford.rst @@ -17,6 +17,7 @@ Submodules ford.fortran_project ford.graphs ford.intrinsics + ford._markdown ford.md_admonition ford.md_environ ford.md_striped_table diff --git a/docs/developers_guide/index.rst b/docs/developers_guide/index.rst index 2cc21490..05ee9117 100644 --- a/docs/developers_guide/index.rst +++ b/docs/developers_guide/index.rst @@ -49,18 +49,19 @@ This is a very rough outline of how FORD works internally. #. After each file has been parsed, the lists of entities are added to the `Project`'s lists of all the entities in the whole project. -#. After all the files have been parsed, the documentation comments are - converted from Markdown to HTML, recursively down from the source - files. At this point, metadata in the comments is also parsed. - #. Entities defined in other files are now "correlated" with their concrete objects. This is done recursively from `Project.correlate`, first by finding which modules are ``use``\ d by each entity, and then looking up names in the corresponding `FortranModule`. -#. Another recursive pass is done of the project to convert internal - `links ` to actual HTML links using `sub_links`. +#. After all the files have been parsed, the documentation comments + are converted from Markdown to HTML, recursively down from the + source files. At this point, metadata in the comments is also + parsed. Several markdown extensions, `AliasPreprocessor`, + `FordLinkProcessor`, `RelativeLinksTreeProcessor`, handle aliases, + links, and absolute to relative link conversion respectively. The + `MetaMarkdown` class just wraps constructing the markdown object. #. The static pages are processed with `get_page_tree`. diff --git a/docs/user_guide/writing_documentation.rst b/docs/user_guide/writing_documentation.rst index 721b6b19..f9656664 100644 --- a/docs/user_guide/writing_documentation.rst +++ b/docs/user_guide/writing_documentation.rst @@ -45,7 +45,7 @@ the source-code this way. This:: !! The ammount of pet food (in kilograms) which you have on hand. integer, intent(out) :: angry !! The number of pets angry because they weren't fed. - + !... return end subroutine feed_pets @@ -65,7 +65,7 @@ looks better/more readable than:: real, intent(inout) :: food !! The number of pets angry because they weren't fed. integer, intent(out) :: angry - + !... return end subroutine feed_pets @@ -280,28 +280,58 @@ this is ``[[component(type):item(type)]]``: as a type and its public constructor). If multiple items with the same name exist and ``type`` is not specified then FORD’s behaviour is undefined; it will link to the first of those items which it - finds. The available options are “procedure”, “subroutine”, - “function”, “proc” (all of which are interchangeable and specify a - procedure), “interface”, “absinterface” (both of which are for - abstract interfaces), “block” (for the legacy ``block data`` program - unit), and “type”, “file”, “module”, and “program” (which are - self-explanatory). + finds. The available options are: + + - "procedure", "proc", "subroutine", "function" for any kind of + procedure defined within the project + - "interface", "absinterface" for abstract interfaces + - "block" for the legacy ``block data`` construct + - "type" + - "file" + - "module" + - "submodule" + - "program" + - "namelist" + + The majority of these can also be prefixed with "ext" to refer to + entities defined in `external projects ` - ``item`` (optional) specifies an item within ``component`` which is to be linked to. The link’s target will be ``item``\ ’s location on ``component``\ ’s page. If ``item`` is not present then the colon in the link must be omitted. - ``type`` (optional, but ``item`` must also be present) is ``item``\ ’s type of Fortran construct. It can be used in the same - manner as the component ``type``, but has different options. These - are “variable”, “type”, “constructor”, “interface”, “absinterface” - (abstract interface), “subroutine”, “function”, “final” (finalization - procedure), “bound” (type-bound procedure), “modproc” (module - procedure in a generic interface block), and “common”. None of these - options are interchangeable. If no description is given then its - meaning should be self-explanatory. If you specify an option that can - not exist within ``component`` (for example, if ``component`` is a - module and ``item`` is “bound”) then a warning message is issued and - the link is not generated. + manner as the component ``type``, but has different options: + + - "absinterface" for abstract interfaces + - "bound" for type-bound procedures + - "common" for ``common`` blocks + - "constructor" for structure constructor procedures + - "final" for finalization procedures + - "function" + - "interface" + - "modproc" for module procedures in generic interfaces + - "subroutine" + - "type" + - "variable" + + None of these options are interchangeable. If you specify an option + that can not exist within ``component`` (for example, if + ``component`` is a module and ``item`` is “bound”) then a warning + message is issued and the link is not generated. + +For example, to link to a module called ``my_mod`` you could +use ``[[my_mod]]`` or ``[[my_mod(module)]]``, while if you wanted to +refer to a function called ``my_function`` in that module you could +use any of (from least to most specific): + +- ``[[my_function]]`` +- ``[[my_function(function)]]`` +- ``[[my_function(proc)]]`` +- ``[[my_mod:my_function]]`` +- ``[[my_mod(module):my_function]]`` +- ``[[my_mod:my_function(function)]]`` +- ``[[my_mod(module):my_function(function)]]`` If you have an overridden constructor a derived type, then it is strongly recommended that you specify ``item`` should you wish to link @@ -309,6 +339,14 @@ to either of them. Otherwise FORD will not know whether you are referring to the derived type itself or the interface for its constructor. +.. versionchanged:: 7.0.0 + Previously, links inside code blocks (with backticks) were + resolved, now they are left verbatim, as with all other + markup. That is, pre-v7, ```call [[my_subroutine]]``` would be + rendered as ``call my_subroutine`` with a link to + ``my_subroutine``, while now it will be left as: ``call + [[my_subroutine]]``. + .. _non-fortran-source-files: Non-Fortran Source Files diff --git a/ford/_markdown.py b/ford/_markdown.py index 2dbeabb6..30db7a3b 100644 --- a/ford/_markdown.py +++ b/ford/_markdown.py @@ -51,7 +51,6 @@ def __init__( aliases: Optional[Dict[str, str]] = None, project: Optional[Project] = None, ): - """make thing""" default_extensions: List[Union[str, Extension]] = [ "markdown_include.include", diff --git a/ford/fortran_project.py b/ford/fortran_project.py index bba05d65..7c735f73 100755 --- a/ford/fortran_project.py +++ b/ford/fortran_project.py @@ -61,6 +61,7 @@ LINK_TYPES = { "module": "modules", + "submodule": "submodules", "extmodule": "extModules", "type": "types", "exttype": "extTypes", diff --git a/test/test_project.py b/test/test_project.py index 5a3f6bcd..469df53d 100644 --- a/test/test_project.py +++ b/test/test_project.py @@ -1043,7 +1043,7 @@ def test_submodule_uses(copy_fortran_file): def test_make_links(copy_fortran_file): - links = "[[a]] [[b(type)]] [[b:c]] [[a:d]] [[b:e]] [[F(proc)]] [[A:G]] [[H]]" + links = "[[a]] [[b(type)]] [[b:c]] [[a:d]] [[b:e]] [[F(proc)]] [[A:G]] [[H]] [[I]]" data = f"""\ module a !! {links} @@ -1073,6 +1073,9 @@ def test_make_links(copy_fortran_file): program h !! {links} end program h + + submodule (a) i !! {links} + end submodule i """ settings = copy_fortran_file(data) project = create_project(settings) @@ -1088,6 +1091,7 @@ def test_make_links(copy_fortran_file): "f": "../proc/f.html", "g": "../module/a.html#variable-g", "h": "../program/h.html", + "i": "../module/i.html", } for item in chain( @@ -1106,7 +1110,7 @@ def test_make_links_with_entity_spec(copy_fortran_file): links = ( "[[a(module)]] [[b(type)]] [[b(type):c(variable)]] " "[[A(MODULE):D(SUBROUTINE)]] [[B(TYPE):E]] [[F(PROC)]] " - "[[A(module):G(variable)]] [[H(program)]]" + "[[A(module):G(variable)]] [[H(program)]] [[I(SUBMODULE)]]" ) data = f"""\ @@ -1137,6 +1141,9 @@ def test_make_links_with_entity_spec(copy_fortran_file): program h !! {links} end program h + + submodule (a) i !! {links} + end submodule i """ settings = copy_fortran_file(data) project = create_project(settings) @@ -1152,6 +1159,7 @@ def test_make_links_with_entity_spec(copy_fortran_file): "f": "../proc/f.html", "g": "../module/a.html#variable-g", "h": "../program/h.html", + "i": "../module/i.html", } for item in chain( @@ -1166,7 +1174,7 @@ def test_make_links_with_entity_spec(copy_fortran_file): assert link_locations == expected_links, (item, item.name) -def test_link_with_context(copy_fortran_file): +def test_make_links_with_context(copy_fortran_file): data = """\ module a !! [[g]] type b !! [[c]] [[e]] [[g]]