Skip to content

Combined emphasis and strong emphasis wrong output #979

Closed

Description

@paulmelis

Not sure ***word*** is actually supported, although it does seem to work in general. But with 3.2.2:

>>> markdown.markdown("""traced ***along*** bla **blocked** if other ***or***""")
'<p>traced <strong><em>along</em></strong> bla <strong>blocked*<em> if other </em></strong>or***</p>'

I.e. the strong emphasis on "blocked" is not ended, but emphasis started instead.

Activity

  1. paulmelis commented on Jun 13, 2020

    @paulmelis
    Author

    Similar case but here the combined emphasis later in the string causes the earlier strong emphasis to get output incorrectly:

    >>> markdown.markdown('on the **1-4 row** of the AP Combat Table ***and*** receive')
    '<p>on the <strong>1-4 row*<em> of the AP Combat Table </em></strong>and*** receive</p>'
    
  2. paulmelis commented on Jun 13, 2020

    @paulmelis
    Author

    Workaround by combining ** and _ works, I guess I'll use that:

    >>> markdown.markdown('on the **1-4 row** of the AP Combat Table **_and_** receive')
    '<p>on the <strong>1-4 row</strong> of the AP Combat Table <strong><em>and</em></strong> receive</p>'
    
  3. waylan commented on Jun 13, 2020

    @waylan
    Member

    @facelessuser I expect this was introduced in your refactor of inline parsing. Could you take a look at this?

  4. facelessuser commented on Jun 13, 2020

    @facelessuser
    Collaborator

    @waylan, I think it is triggered by the case **text*text***. I think we added logic for this case and allowed it to have the same "dumb" logic that the other patterns have. Even my variant in the BetterEm extension suffers from this unless "smart" logic is enabled:

    Basic logic:`

    >>> markdown.markdown("""traced ***along*** bla **blocked** if other ***or***""", extensions=["pymdownx.betterem"])
    '<p>traced <strong><em>along</em></strong> bla <strong>blocked** if other **<em>or</em></strong></p>'

    Smart logic:

    >>> markdown.markdown("""traced ***along*** bla **blocked** if other ***or***""", extensions=["pymdownx.betterem"], extension_configs={"pymdownx.betterem": {"smart_enable": "all"}})
    '<p>traced <strong><em>along</em></strong> bla <strong>blocked</strong> if other <strong><em>or</em></strong></p>'

    In short, the current recognition for **text*text*** doesn't pay attention so much to the word boundaries and white space, but maybe this particular case should be more intelligent and selective on what it recognizes. It may make sense to reduce the chance of this particular cases chance of matching with a little intelligence in regards to word boundaries and whitespace.

    I'll have to take a deeper look at exactly what causes this failure, but I suspect my initial gut feeling is most likely, and by tweaking this case to be more strict will prevent these problems.

  5. facelessuser commented on Jun 14, 2020

    @facelessuser
    Collaborator

    I'll look into this case when I get a chance. This matching case is clearly too greedy and should be limited.

  6. self-assigned this
    on Jun 14, 2020
  7. facelessuser commented on Jun 14, 2020

    @facelessuser
    Collaborator

    Doing some simple tests, I think the best approach is maybe to handle both **text*text*** and **text** at the same time. I'll probably adjust the pattern **text*text*** pattern to handle **text** in the same step, favoring **text** first. I think that'll basically fix things.

    In short, we don't want to run **text** by itself first, because then it'll make **text*text*** impossible to catch. But if we handle **text** and **text*text*** in the same step, we can detect both. I think we just had test cases that were too simple to catch issues as exposed in this issue.

  8. facelessuser commented on Jun 14, 2020

    @facelessuser
    Collaborator

    It's possible moving the pattern order is all that's required as I believe we now cycle through the patterns on each * detection with the new approach. Which is different than the legacy approach which would run one pattern on the whole paragraph before the next pattern. So, it's likely this will require no pattern changes, and simply an order change favoring **text** over **text*text***.

  9. facelessuser commented on Jun 14, 2020

    @facelessuser
    Collaborator

    In the end, I think I'll probably just go with this:

    STRONG_EM3_RE = r'(\*)\1(?!\1)([^*]+?)\1(?!\1)(.+?)\1{3}'

    This limits the **text*text*** case to not not allow any * to appear between the first section (**text*). This will prevent **text**text*** from matching, which is basically what is happening above. This simple restriction should make the above pattern more reliable, and prevent it from being too greedy. I'll run more tests and such this week to make sure there are no adverse side effects, but this seems like the best choice with the limited tests I've just run.

  10. facelessuser commented on Jun 20, 2020

    @facelessuser
    Collaborator

    I believe we have a fix in Pull #984.

  11. added a commit that references this issue on Jun 22, 2020
    dbb9b3d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugBug report.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions