jgm / djot.js

JavaScript implementation of djot
MIT License
141 stars 15 forks source link

Characters disappear if url/label contains valid attributes. #46

Closed hellux closed 10 months ago

hellux commented 1 year ago
[text]({a=b})

yields

doc
  para
    link destination="{ab}"
      str text="text"

instead of

doc
  para
    link destination="{a=b}"
      str text="text"
jgm commented 1 year ago

Can see same thing with

[hi]({#ab})

[hi]({.ab})
jgm commented 1 year ago

When we match a destination, we (inlines.ts l. 440)

        // convert all matches inside destination to str

The problem is that the attribute parser gives us events for key and value, but not for the =; similarly for the identifier or class, but not the markers # or .. Interior whitespace is also not given an event, so it too will be lost:

% ./djot          
[hi]({a=b c=d})
<p><a href="{abcd}">hi</a></p>

Probably the best fix is to use a different strategy for matching destinations. You might ask, why not just use the position after the ( as the start of the destination and the position before the ) as the end? Because the destination might be broken up by newlines and thus might not occupy a contiguous segment of the input text.

jgm commented 11 months ago

One idea for fixing this would be to have the events parser create multiple +destination/-destination pairs when the URL is split over lines. parse.ts could then look for multiple destinations and concatenate them. If we were sure that each +destination/-destination pair was on a single line, we could just take all the text between the start and the end.

jgm commented 10 months ago

Reopening; I had to revert the fix because it was buggy. See #64.

jgm commented 10 months ago

I think the problem is with strMatches in inlines.ts.

jgm commented 10 months ago

Similar issue: [link]({.class})

jgm commented 10 months ago

The function converts all matches to str, but some of the characters, like ., don't generate match events, so they are lost.