-
Notifications
You must be signed in to change notification settings - Fork 67
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
[API change] Modify Attr, add it to relevant types #79
base: master
Are you sure you want to change the base?
Conversation
I think I would adapt I'm also interested in the |
Is there a reason why this cannot just be: type Attr = Map Text Text i.e., why not put both |
Both are used pretty frequently in |
5c3e093
to
546af89
Compare
If we're making a large scale change of this type, it might be worth considering a different alternative (though this would be an even more radical change). Something like: data Block = Block Attr BlockT
data BlockT = Header Int [Inline] | Para [Inline] | ...
data Inline = Inline Attr InlineT
data InlineT = Str Text | Emph [Inline] | ... This gives attributes to everything in a uniform way. Granted, it would be a much more painful change to make to the code base, though maybe PatternSynonyms could make it less painful. Hence, probably not worth considering at the time. But I thought it should be mentioned. |
That was my thinking as well. I should mention that in the |
On that subject, the new (Attr i1 c1 k1) <> (Attr i2 c2 k2) = Attr i' (c1 <> c2) (k1 <> k2)
where
i' = if Text.null i1 then i2 else i1 be appropriate? The left/right priorities for the components could be different. |
I should also say that factoring out the |
General note: Thanks for all of these concrete proposals for pandoc-types. Because of other things lined up, it may be a few weeks before I can really think seriously about them. On Attr: were you saying that you'd prefer the approach I sketched of separating out the Attr from the base block types? On Semigroup: the instance you propose seems as good as any. On Semigroup for Inlines: I would think that a good general principle would be that adjacent elements of the same type can merge if they have identical Attr. That would be more generous than "if they have null Attr." Is there something to be said against it? On the Attr type: there is a drawback to using Map. (I don't know if this was discussed before.) The drawback is that you don't get deterministic output with Show (or with ToJSON, etc.). This could perhaps be dealt with by defining Show explicitly (similarly ToJSON, etc.). But my reason for using a list originally was to allow order information to be preserved deterministically. I'm not sure what to think about this. In many ways Map is more correct (disallowing multiple attributes with the same key) as well as more performant. |
You're welcome. I'll still be free for a while to adapt I think I like separating out attributes. That's a common approach for compilers that need to annotate every node of their AST with additional information, and a uniform treatment of attributes would be nice. Downsides (maybe small) that I can think of, other than it being a larger change: pattern matches will get a little more complex, at least in the short term, everything becoming Another design is this: data WithAttr a = WithAttr Attr a
type Block = WithAttr BlockT
type Inline = WithAttr InlineT for uniformity, but I'm not sure if it makes too much difference. Having separate types for other attribute-carrying elements (like I can't think of any objections to that method of combining I think the output of Show for I can't really comment on the need to preserve key ordering or duplicate keys. I don't think that |
Maybe the downsides for factoring out {"t":"BlockTConstructor","a":"attributes","c":"content"} and the lua output might be similarly adjustable. That might be an improvement. |
Different general note: I've started work on ast-migrator. The goal is to convert from one AST version to another. That should give us more room to do drastic changes without impacting library (and filter) users too much. Maybe it's enough to prevent a Python 2/3 kind of situation. I'll move the project to the pandoc organization if it is deemed useful. |
I'm convinced that we can handle the switch to a Map rather than a list. It's definitely true that going general with the Attr would be much more of a pain in the short term, since the code modifications required are much more intrusive. That may argue for a more gradual approach, even if it's less elegant. |
The new Attr type, in addition to being a data type, changes the key-value pairs representation to a Map. An Attr component has been added to every relevant branch of Inline and Block. It has also been added to Caption. New Attr conversion functions have been added to Definition, and new builders for the types that received an Attr component have been added to Builder. The representation of Attr in JSON is different: the key-value pairs are now an object. Additionally, the t_table test was a bit too large to inspect for correctness directly. It has been simplified, and new tests for the top-level components of Table have been added.
The semigroup operation is left-biased for identifiers and attributes, and concatenates the classes.
The semigroup instance for Inlines will now fuse together appropriate inline elements when they have equal attributes, not just null attributes.
d7322bb
to
6a00685
Compare
An alternative to using a Map could be to have something like Swift's Ordered Dictionary. The datatype combines an array with a map. My understanding is that JavaScript's Map does something similar. |
Something like |
I checked the Swift implementation, it is basically data OrderedDictionary k v = OrderedDictionary
{ orderedKeys :: Vector k
, keysToValues :: Map k v
} Which seems like overkill here. |
|
That does fit, but it's always a liability to take on an additional library dependency. One more thing to break if upstream maintainers don't keep it up to date. |
Resolves jgm/pandoc#684 in this library. The new
Attr
type isas I mentioned in that issue. Everything that could reasonably have an
Attr
has one now.I haven't added
for the lists yet, but I can do that if it's reasonable.