Version 0.19 of the spec has been released.
Changelog here: http://spec.commonmark.org/changelog.txt
I found the changes to open/close emphasis for underscore easy to implement based on my existing code written against 0.18, but I think the way they’re defined in the spec language may be overly complicated. If you simplify the boolean expressions, you get:
asterisk_opens = !space_after && (!punct_after || space_before || punct_before)
asterisk_closes = !space_before && (!punct_before || space_after || punct_after)
underscore_opens = !space_after && (!punct_after || space_before)
underscore_closes = !space_before && (!punct_before || space_after)
Looking at it this way, the predicates for whether _
can open or close are actually simpler than those for *
. Defining the former in terms of the latter is potentially confusing; I certainly didn’t have intuition about when they would actually trigger just from reading the spec. So I’m wondering whether the presentation of this logic could be simplified.
Very minor nit: in the autolink section, the qualifier "absolute URI not containing <
" is redundant because the definition of absolute URI excludes <
among other things.
+++ raph [May 01 15 17:13 ]:
I found the changes to open/close emphasis for underscore easy to implement based on my existing code written against 0.18, but I think the way they’re defined in the spec language may be overly complicated. If you simplify the boolean expressions, you get:
asterisk_opens = !space_after && (!punct_after || space_before || punct_before)
asterisk_closes = !space_before && (!punct_before || space_after || punct_after)
underscore_opens = !space_after && (!punct_after || space_before)
underscore_closes = !space_before && (!punct_before || space_after)
This can’t be right. Consider
!_!_!
. This comes
out with emphasis, even though the first underscore does not satisfy your
underscore_opens
condition.
The underscore satisfies the spec’s condition for opening emphasis,
because (a) it’s part of a left-flanking delimiter run, and (b) although
it’s also part of a right-flanking delimiter run, this is preceded by
punctuation.
So I think something must have gone wrong in your simplifications.
Apologies, I did get it wrong (my paper notes were right, I made an error when typing). What I have is:
underscore_opens = !space_after && (punct_before || space_before)
underscore_closes = !space_before && (punct_after || space_after)
This time I’m fairly sure I got it right; certainly it now works for the case you gave.