Hi,

For my project I'm using Sphinx with a custom domain and I've managed to 
create custom ObjectDescription objects, e.g.:

.. mydomain:someobjtype:: MyInstance
   :myoption: My option text

   Some body text, with standard- or other domain references, such as :ref:
`mysection`.

Also, I've managed to create a custom XRefRole subclass, so that I can 
control how references are created. Very cool so far.

Now, what I'd like to do, is to "re-render" some of those objects on other 
pages. Use case examples:

   - I have a reference documentation section where I have the extensive 
   list of all objects documented, but also some "Getting Started" documents 
   where I not only want to reference a few of them, but also literally 
   re-include / repeat / re-render them for convenience of the reader. With 
   regular cross-references the reader having to navigate away from the page 
   for very small object definitions hurts the experience a lot, imo.
   - Repeatedly small object references, which should be inlined for 
   readability. E.g.:
   .. mydomain:enum:: Color
      :value red: Red is the color for...
      :value green: Green is used for ...
   
   .. mydomain:class:: Light
      :param: color
      :type: :mydomain:enum:`Color`
   Then this should render the parameter description with a reference to 
   the Enum object, but also render: "valid options are: red, green".
   

If I understand the internals of Sphinx correctly, the logic boils down to 
this (please tell me if I am misunderstanding something):

   - ObjectDescriptions objects will create the content nodes.
   - The XRefRole allows to create cross-references to the content nodes 
   via the Domain.
   - A Transformer traverses the document node tree twice (?) to be able to 
   resolve a <-> b references, assuming that none of them will be of type 
   pending_xref after the second run.
   - The Transformer (ReferencesResolver) provides a deepcopy of the branch 
   of nodes to resolve_xref(), for each domain.
   (This is blocking me from hacking further by going "out of scope" and 
   simply connect to the nodes in the document where it was rendered and where 
   the Transformer will call resolve_xref() on again later.)
   - A Writer doesn't deal with stuff like references, but simply renders 
   the nodes.
   

Here's what I've tried so far:

   1. Exploit the cross-reference logic; In the domain's resolve_xref() 
   function, where you would normally call return 
   sphinx.util.nodes.make_refnode([...]), I am returning a full tree of nodes 
   again. Together with some other hacks, I am able to access those nodes 
   which then re-renders the same object on reference. (E.g. inline ref like 
   :mydomain:someobjtype:`MyInstance`.)
   However, the problem I'm facing is that this fails in case other 
   references are part of this tree of nodes, such as the reference to 
   'mysection' in the example above. This is because they are of the type 
   pending_xref in my tree, they are not resolved anymore later, and the 
   writer can't render them, raising an exception. I can solve the problem 
   only for references within my own domain with a recursive resolve_xref(). 
   It seems the caller of resolve_xref(), ReferencesResolver, is simply not 
   prepared for new references being returned, but really assumes a simple 
   link.
   2. Document all objects in separate files, then using the RST include 
   directive to render them on all places that I need. Apart from this being 
   cumbersome, this is not working well enough for me.
      - it will generate identical object descriptions, all being indexed, 
      emitting a warning that I should put :noindex: on all-but-one. True, but 
      since this is an RST-level literal include I can't adjust where noindex 
      flags are added.
      - the path to the file to include is relative to the current 
      document, making it hard to move content around. The cross-reference hack 
      above does this much better.
   3. Looking at the Writer level to render output another time. It seems 
   that I would break stuff as it's not page-aware any longer, such as 
   breaking relative links.

I'm currently looking into proceeding with the first option, and adding a 
custom Transformer as well, but wanted to ask around here for 
ideas/suggestions on a broader level, because this all feels like a huge 
hack to something that seems so simple. Yet, I don't see any projects 
online who are trying to tackle this on a Sphinx-level (I only see 'smart' 
RST generators for custom purposes).

Any suggestions are pretty much welcome. Thanks!

Gert

-- 
You received this message because you are subscribed to the Google Groups 
"sphinx-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sphinx-users.
For more options, visit https://groups.google.com/d/optout.

Reply via email to