Skip to content

Commit

Permalink
Fix wrong refid in Doxygen's XML generator
Browse files Browse the repository at this point in the history
Given the following Doxygen input:

```
/**
 * This struct must be used with f()
 */
struct t {
  int x;
}

/**
 * @param tx A struct t pointer
 */
void f(struct t *tx) {
  (void)tx;
}
```

The `f()` in struct t's comment generates a <ref> element with `refid`
equal to `some_prefix_compoundid_anchorid`, wheres the `id` in the
refered element ends up with an `id` equal to `some_prefix_anchorid`.
The anchorid here is just the compoundid prefix by "_1", so the `refid`
actually has this information duplicated.

This is a band-aid solution that tries to detect the issue and remove
the offending part from the `refid`, so that resulting links work.

Signed-off-by: Fabio Utzig <fabio.utzig@nordicsemi.no>
  • Loading branch information
utzig committed Aug 18, 2020
1 parent 26cd84d commit cff4e4f
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions breathe/renderer/sphinxrenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,29 @@ def set_context(self, context: RenderContext) -> None:
if self.context.domain == '':
self.context.domain = self.get_domain()

# When Doxygen's XML generator finds a reference in a comment, it
# generates a new <ref> element where the refid gets both a compoundid
# and an anchorid, where: anchorid = "_1" + compoundid. The ids that are
# linked to, only get the anchorid (or "_1" + compoundid!). This function
# tries to patch the refid, if it matches the wrong generation, by
# removing the compoundid, so that those refs can be correctly resolved
# by Sphinx.
def _strip_doxygen_anchorid(self, refid: str) -> str:
if refid:
parts = refid.rsplit("_", 1)
if len(parts) == 2 and parts[1].startswith("1"):
anchorid = parts[1][1:]
if anchorid in parts[0]:
pos = parts[0].find(anchorid)
return parts[0][:pos] + parts[1]
return refid

def get_refid(self, refid: str) -> str:
if self.app.config.breathe_use_project_refids: # type: ignore
return "%s%s" % (self.project_info.name(), refid)
return "%s%s" % (self.project_info.name(),
self._strip_doxygen_anchorid(refid))
else:
return refid
return self._strip_doxygen_anchorid(refid)

def get_domain(self) -> str:
"""Returns the domain for the current node."""
Expand Down

0 comments on commit cff4e4f

Please sign in to comment.