Re: Inline, verbatim anchors?

Matthew Woehlke <[email protected]> Mon, 28 Oct 2019 17:15:02 -0400
Newsgroups gmane.text.docutils.user
Message-ID <[email protected]>
On 28/10/2019 16.56, Matthew Woehlke wrote:
> On 2019-10-08, Guenter Milde via Docutils-users wrote:
>> Unfortunately, inline markup nesting is not supported.
>> This is a long standing feature request.
>> http://docutils.sourceforge.net/docs/dev/todo.html#nested-inline-markup
> 
> BTW, I wonder why nested markup is such an issue? I've implemented that
> before for my own custom extensions, and it wasn't hard. (IIRC,
> something mutter something about creating an extra paragraph node, but I
> think I solved that by stripping out the interior node from
> nested_parse. At least, I had something that was working for my use
> case, and I don't think it would have worked with an extra paragraph
> node, which suggests I was able to deal with it somehow.)

Okay, I'm *not* using nested_parse. Here is my code (note: old, may not
work with latest version):


  def make_parsed_text_role(class_names=[], node_class=nodes.inline):
      def parsed_text_role(name, rawtext, text, lineno, inliner,
                           options={}, content=[]):
        # Prepare context for nested parsing
        memo = Struct(document=inliner.document,
                      reporter=inliner.reporter,
                      language=inliner.language)

        # Create parent node
        options['classes'] = class_names
        parent = node_class(rawtext, '', **options)

        # Parse role text for markup and add to parent
        processed, messages = inliner.parse(text, lineno, memo, parent)
        parent += processed

        # Return parent node, and any messages from nested parsing
        return [parent], messages

      return parsed_text_role

As you'll note, this isn't a role in and of itself; it is actually a
function to *create* a role. My project creates a bunch of these with
different 'stock' classes; for example:

  app.add_role('t', make_parsed_text_role(class_names=['title-drop']))
  app.add_role('i', make_parsed_text_role(node_class=nodes.emphasis))

...which lets you write stuff like:

  I read :t:`The *Very* Long Evening` last night.

OTOH I don't think this supports nested *roles*, and we won't even talk
about backwards compatibility, but for my purposes, using emphasis and
substitutions inside of interpreted text was sufficient.

-- 
Matthew