Re: nested field lists in custom directives

David Goodger <[email protected]>
Newsgroups gmane.text.docutils.user
Message-ID <CABiJP=Jx5Bq3=ZygvRid1foWXqcoY+ry27Zn+Wuo+MnJZSY8MA@mail.gmail.com>
On Sun, Sep 24, 2017 at 5:39 PM, Robin Shannon <[email protected]> wrote:
> G'day,
>
> Firstly, thanks to everybody who has worked on ReST/docutils, you're
> awesome.
>
> I'm trying to create a custom directive for videos (my only output is html),
> and I would like to be able to include tracks (subtitle files) within the
> directive.
>
> For those unfamiliar with html5 video, the output looks something like this:
> <video autoplay>
> <source src="foo.ogg">
> <track kind="subtitles" src="foo.vtt" srclang="en">
> </video>
>
> What I'd like is a directive with nested field lists. eg:
> .. video:: sources
>     :autoplay: True
>     :track: :src: foo.vtt
>                :srclang: en
>                :kind: subtitles
>     :controls: false
>
> I saw nested lists like this somewhere in the sandbox (though now I can't
> find it again), but I think it was just a suggestion rather than an actually
> implemented directive. If this is possible, how would it work with
> option_spec in the directive definition? Alternatively is there a better way
> of solving this problem?

First, do you really need to implement a directive? You could just
embed the HTML in your reST source (``.. raw:: html``). It may be a
heck of a lot easier.

Next, do you really need the nesting? How about something like this::

 .. video:: sources
     :autoplay: True
     :src: foo.vtt
     :srclang: en
     :kind: subtitles
     :controls: false

The input does not have to match the output exactly, as long as it's
not ambiguous. If the three "nested" field names are unique, they can
simply be mapped to the required attributes and you don't need the
"track" field at all.

In general, try to avoid explicit boilerplate and complex data structures.

In your use case, do you want to allow multiple <track> elements
inside <video>? Multiple <source> elements? The HTML standard allows
multiples: videos in different formats, subtitles and captions in
different languages, etc. If the answer to either of these is "yes",
then you'll need something more robust.

The only real *options* you'd have in this directive are "autoplay"
and "controls". And since they are simply flags (boolean attributes),
just include one to indicate "on" or exclude it to indicate "off";
don't use "true" and "false" values. See the "contents" directive
attribute "local" for an example.

The "track"-related data aren't options, they're content. If you have
a track, you must include certain attributes for it to make sense.
Then you have "required options", which is a contradiction in terms.
Bad smell, don't do that. And you can have multiple tracks, but it
doesn't generally make sense to repeat options. If you can standardize
the exact attributes you'll need (i.e. no variation), you can
implement these as a bullet list (one item per track) with positional
parameters (kind, language, source)::

    * subtitles en foo.vtt

And even if there is some variation, you can add some punctuation to
make things clear, something like::

    * subtitles en foo.vtt "label text here" **default**

Or even::

    * **subtitles** en foo.vtt "label text here"

The emphasized "**subtitles**" could indicate "default".

For example, allowing for multiple sources in the directive arguments,

    .. video:: foo.mp4 foo.webm foo.ogg
       :autoplay:
       :controls:

       * subtitles en foo.vtt
       * subtitles fr foo-fr.vtt

David Goodger
<http://python.net/~goodger>

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.