Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only Directive does not order text as expected #1488

Closed
shimizukawa opened this issue Jan 3, 2015 · 9 comments
Closed

Only Directive does not order text as expected #1488

shimizukawa opened this issue Jan 3, 2015 · 9 comments

Comments

@shimizukawa
Copy link
Member

Learning reST to write user manuals. (Hardware products.) Devices can have one of three network connections so the format of one file is:

Standard text
.. only:: test1
   text
.. only:: test2
   text
.. only:: test1 or test2
   text
.. only test3
   text

If the headings in the 'test1 or test2' section does not match the headings of 'test1' or 'test2' section, the 'test1 or test2' section appears before the 'test1' or 'test2' sections.
Attached are two ZIP files of the resulting html files. The test1, test2, and test3 tags are defined in the associated conf.py files.


@shimizukawa
Copy link
Member Author

From David Nichols on 2014-06-11 20:14:52+00:00

Created on XP SP3, Python 2.6.

@shimizukawa
Copy link
Member Author

From Takayuki Shimizukawa on 2014-06-11 22:52:06+00:00

In short, it might a limitation of the only directive.

All section definitions under the only directive make unexpected behavior. I think we should avoid to contain any section header in the only directive.

@shimizukawa
Copy link
Member Author

From Takayuki Shimizukawa on 2014-06-11 22:54:41+00:00

Technically, doctree (intermediate data) keeps that node with wrong order. I think it's a limitation and is difficult to solve (not verified yet).

@shimizukawa
Copy link
Member Author

From David Nichols on 2014-06-12 12:11:18+00:00

If the "test1 or test2" section contains only body text or a .. figure:: directive (which is how I initially found it), the order is still incorrect. The section is placed before the "test1" and/or "test2" sections.

Not being able to use section header in an only directive is a deal breaker for me.

@shimizukawa
Copy link
Member Author

From David Nichols on 2014-06-23 12:59:10+00:00

But isn't the doctree created by Sphinx? The node order is in fact wrong, which leads me to suspect Sphinx. The translators from doctree to whatever work correctly.

The Only class in sphinx is defined in sphinx\directives\only.py, starting on line 324. The comment starting on line 340 states: "# Same as util.nested_parse_with_titles but try to handle nested sections which should be raised higher up the doctree." I haven't been able to figure out why the nested sections should be raised, or how it's done, but I suspect that the problem lies there.
.

@shimizukawa
Copy link
Member Author

From Takayuki Shimizukawa on 2014-06-26 16:05:35+00:00

I'll try to describe what happen.

First case.

=============
1: Section 1
=============

------------------------
1.1: Subsection
------------------------

.. compound::

   =============
   2: Section 2
   =============

As docutils definition, compound directive block is a child of 1.1: Subsection. Definitely, all content block in a directive become children of the directive, then 2: Section 2 is a child of compound directive. It can be represented as:

<section names="1: Section 1">
    <section names="1.1: Subsection">
        <compound>
            <section names="2: Section 2">

(In fact, it's not true; docutils avoid unexpected section in any directive content.)

If we try to apply a same structure to only directive:

=============
1: Section 1
=============

------------------------
1.1: Subsection
------------------------

.. only:: (flag2)

   =============
   2: Section 2
   =============

It can be represented as:

<section names="1: Section 1">
    <section names="1.1: Subsection">
        <only expr="(flag2)">
            <section names="2: Section 2">

However, 2: Section 2 and 1: Section 1 are same level section header. Therefore, only directive implementation try to handle nested 2: Section 2 section which should be raised higher up the doctree. As a conclusion, the doctree will be structured as:

<section names="1: Section 1">
    <section names="1.1: Subsection">
<only expr="(flag2)">
    <section names="2: Section 2">

In this case, if flag2 is not true, sphinx simply remove only node and whole children.
If flag2 is true, sphinx will replace children of only node with only node itself in output stage.

def process_only_nodes(self, doctree, builder, fromdocname=None):

Finally, we will get:

<section names="1: Section 1">
    <section names="1.1: Subsection">
<section names="2: Section 2">

Next case.

=============
1: Section 1
=============

------------------------
1.1: Subsection
------------------------

.. only:: (flag2)

   =============
   2: Section 2
   =============

.. only:: (flag21)

   ----------------------------
   2.1: Subsection 2
   ----------------------------

Current only directive implementation translates it into:

<section names="1: Section 1">
    <section names="1.1: Subsection">
    <only expr="(flag21)">
        <section names="2.1: Subsection 2">
<only expr="(flag2)">
    <section names="2: Section 2">

Why 2.1: Subsection 2 and its parent only node does not raised to top level? Because 2.1: Subsection 2 and 1.1: Subsection are same section level (recognized by header marker). It's a reason of your question.

How do you think? I think the spec is reasonable (but hard to understand).

@shimizukawa
Copy link
Member Author

From Takayuki Shimizukawa on 2014-07-05 03:01:34+00:00

Please take a look that refs and let us know your opinion if you have a chance.

@shimizukawa
Copy link
Member Author

From Deniz Bahadir on 2014-11-07 11:28:49+00:00

I did not understand what the blog-entry is talking about. (Probably, the automated translation is not very accurate.)

However, I think the following test-case is even simpler to demonstrate the problem:

#!reST

###########################################
Sphinx - wrong heading location with 'only'
###########################################


Section 1
=========

.. only:: tag or not tag

   Subsection 1.1
   --------------

This sentence should be shown in **Subsection 1.1** and it is. 


Section 2
=========

.. only:: tag or not tag

   Section 3
   =========

This sentence should be shown in **Section 3** but it is not and instead shown in **Section 2**.

Is there really nothing which can be done to solve the problem? Then it sounds to me, as if Sphinx needs some kind of pre-processor (similar to the C/C++ pre-processor) which just removes inactive only-sections from the source-file before handing it over to sphinx-parser.

@shimizukawa
Copy link
Member Author

From Takayuki Shimizukawa on 2014-11-08 07:34:43+00:00

I think there is no way to solve the problem with using current only directive implementation. Also I have no idea to fix only directive behavior for this problem completely.

Speaking about your last case, I think it is possible to fix, but it seems hard.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant