{"action":"created","issue":{"url":"https://api.github.com/repos/ocsigen/tyxml/issues/89","repository_url":"https://api.github.com/repos/ocsigen/tyxml","labels_url":"https://api.github.com/repos/ocsigen/tyxml/issues/89/labels{/name}","comments_url":"https://api.github.com/repos/ocsigen/tyxml/issues/89/comments","events_url":"https://api.github.com/repos/ocsigen/tyxml/issues/89/events","html_url":"https://github.com/ocsigen/tyxml/pull/89","id":136791710,"number":89,"title":"Add ppx.","user":{"login":"aantron","id":12073668,"avatar_url":"https://avatars.githubusercontent.com/u/12073668?v=3","gravatar_id":"","url":"https://api.github.com/users/aantron","html_url":"https://github.com/aantron","followers_url":"https://api.github.com/users/aantron/followers","following_url":"https://api.github.com/users/aantron/following{/other_user}","gists_url":"https://api.github.com/users/aantron/gists{/gist_id}","starred_url":"https://api.github.com/users/aantron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aantron/subscriptions","organizations_url":"https://api.github.com/users/aantron/orgs","repos_url":"https://api.github.com/users/aantron/repos","events_url":"https://api.github.com/users/aantron/events{/privacy}","received_events_url":"https://api.github.com/users/aantron/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/ocsigen/tyxml/milestones/1","html_url":"https://github.com/ocsigen/tyxml/milestones/4.0","labels_url":"https://api.github.com/repos/ocsigen/tyxml/milestones/1/labels","id":725713,"number":1,"title":"4.0","description":"Next major version, for all the breaking changes.","creator":{"login":"Drup","id":801124,"avatar_url":"https://avatars.githubusercontent.com/u/801124?v=3","gravatar_id":"","url":"https://api.github.com/users/Drup","html_url":"https://github.com/Drup","followers_url":"https://api.github.com/users/Drup/followers","following_url":"https://api.github.com/users/Drup/following{/other_user}","gists_url":"https://api.github.com/users/Drup/gists{/gist_id}","starred_url":"https://api.github.com/users/Drup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Drup/subscriptions","organizations_url":"https://api.github.com/users/Drup/orgs","repos_url":"https://api.github.com/users/Drup/repos","events_url":"https://api.github.com/users/Drup/events{/privacy}","received_events_url":"https://api.github.com/users/Drup/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":8,"state":"open","created_at":"2014-07-19T00:58:13Z","updated_at":"2016-04-01T22:53:22Z","due_on":null,"closed_at":null},"comments":28,"created_at":"2016-02-26T19:32:51Z","updated_at":"2016-04-01T22:54:53Z","closed_at":"2016-04-01T22:53:22Z","pull_request":{"url":"https://api.github.com/repos/ocsigen/tyxml/pulls/89","html_url":"https://github.com/ocsigen/tyxml/pull/89","diff_url":"https://github.com/ocsigen/tyxml/pull/89.diff","patch_url":"https://github.com/ocsigen/tyxml/pull/89.patch"},"body":"This is a preliminary (but working) implementation of a PPX rewriter for TyXML, based on the HTML5 parser in [Markup.ml][markup]. Here are usage examples, paired with the dumped TyXML expressions that are generated:\r\n\r\n[markup]: https://github.com/aantron/markup.ml\r\n\r\n#### Basic\r\n\r\n```ocaml\r\nlet Html5 = Html5.M\r\nlet _ = [%tyxml \"<img src='foo' alt='bar' id='baz'>\"]\r\n```\r\n\r\n```ocaml\r\nlet _ =\r\n  [Html5.img ~src:(Html5.Xml.W.return \"foo\") ~alt:(Html5.Xml.W.return \"bar\")\r\n     ~a:[Html5.a_id (Html5.Xml.W.return \"baz\")] ()]\r\n```\r\n\r\n#### Antiquotation\r\n\r\n```ocaml\r\nlet Html5 = Html5.M\r\nlet _ = [%tyxml \"<p>foo<em>bar</em></p><p>\" (pcdata \"bar\") \"</p>\"]\r\n```\r\n\r\n```ocaml\r\nlet _ =\r\n  [Html5.p\r\n     (Html5.Xml.W.cons (Html5.pcdata \"foo\")\r\n        (Html5.Xml.W.cons\r\n           (Html5.em\r\n              (Html5.Xml.W.cons (Html5.pcdata \"bar\") (Html5.Xml.W.nil ())))\r\n           (Html5.Xml.W.nil ())));\r\n  Html5.p (Html5.Xml.W.cons (Html5.pcdata \"bar\") (Html5.Xml.W.nil ()))]\r\n```\r\n\r\n#### SVG\r\n\r\n```ocaml\r\nlet Html5 = Html5.M\r\nlet Svg = Svg.M\r\nlet _ = [%tyxml \"<p><svg><g id='foo'/></svg></p>\"]\r\n```\r\n\r\n```ocaml\r\nlet _ =\r\n  [Html5.p\r\n     (Html5.Xml.W.cons\r\n        (Html5.svg\r\n           (Svg.Xml.W.cons\r\n              (Svg.g ~a:[Svg.a_id (Svg.Xml.W.return \"foo\")]\r\n                 (Svg.Xml.W.nil ())) (Svg.Xml.W.nil ())))\r\n        (Html5.Xml.W.nil ()))]\r\n```\r\n\r\nErrors have location information, although without https://github.com/aantron/markup.ml/issues/6, these are points instead of ranges, and, for errors inside a tag, the location reported is the start of the tag:\r\n\r\n```ocaml\r\nlet _ = [%tyxml \"<ul><ul></ul></ul>\"]\r\n```\r\n```\r\nFile \"test.ml\", line 1, characters 18-18:\r\nError: This expression has type\r\n         ([> Html5_types.ul ] as 'a) Html5.elt Html5.Xml.W.tlist =\r\n           'a Html5.elt list\r\n       but an expression was expected of type\r\n         ([< Html5_types.ul_content_fun ] as 'b) Html5.elt Html5.list_wrap =\r\n           'b Html5.elt list\r\n       Type 'a Html5.elt = 'a Html5.M.elt is not compatible with type\r\n         'b Html5.elt = 'b Html5.M.elt \r\n       Type 'a = [> `Ul ] is not compatible with type\r\n         'b = [< `Li of Html5_types.li_attrib ] \r\n       The second variant type does not allow tag(s) `Ul\r\n```\r\n\r\nThis would resolve #68. I will amend the commit to say \"Closes #68\" before this is merged into master, when review is done.\r\n\r\nThis makes TyXML depend on Markup.ml. However, projects using TyXML would not pull in Markup.ml as a run-time dependency, because it is used only in TyXML's PPX.\r\n\r\n### How it works and reading order\r\n\r\nThe PPX itself does a pretty straightforward translation of a Markup.ml signal stream into a TyXML expression tree. However, since different TyXML elements and attributes have different signatures, some type information is needed for the PPX to be able to assemble the TyXML tree correctly. This type information is generated by a second PPX rewriter called `ppx_reflect`, which is a build tool that runs on `html5_sigs.mli`, `svg_sigs.mli`, and `html5_types.mli`.\r\n\r\nFor a bottom-up review, you can look at the files in order: `ppx_common.mli`, `ppx_attribute_value.mli`, `ppx_element_content.mli`, `ppx_sigs_reflected.mli`, `ppx_reflect.ml`, `ppx_namespace.mli`, `ppx_attribute.mli`, `ppx_element.mli`, `ppx_tyxml.ml`.\r\n\r\n### Notes\r\n\r\n- There is an ambiguity in interpeting newlines: was the newline inserted by the user using `\\n`, or by creating a new line in the file? This affects how source location information is reported. I chose to always assume the latter, because it seems that people would want to have a multiline template more than inserting pointless `\\n` escapes into markup meant for TyXML trees – unless, perhaps, they are creating `<pre>` elements.\r\n\r\n### Issues\r\n\r\n*(Edited to reflect status)*\r\n\r\n- [ ] Support for date format in `<input>` `min`, `max`. Is there a good library for parsing this?\r\n- [ ] User-facing documentation. Considering saving this for another PR.\r\n- [ ] Make strict parsing optional.\r\n- [ ] Support for namespaced attributes like `xmlns`, `xml:space`, etc.\r\n- [ ] Proper OASIS packaging: a Findlib package which provides an executable but no library. For now, I created a library package that has no visible modules.\r\n- [ ] Don't assume Ocaml ≥ 4.02. Did the OASIS flag eliminate this concern?\r\n- [x] Generalize antiquotations. They are currently only supported as the entire content of an element. It should be possible to fix this after dealing with https://github.com/aantron/markup.ml/issues/6. That should allow antiquotations in attributes and interspersed in content. We should probably leave this for a future PR.\r\n- [x] Switch to re completely.\r\n- [ ] Break up `Ppx_attributes.parse` and `Ppx_tyxml.markup_expr`.\r\n- [x] Change strategy for merging antiquotations with parser output (explained\r\nin a comment in the code).\r\n- [x] Consider changing the quotation name.\r\n- [x] Consider allowing specification of the module name used for qualifying combinators. I assumed that the HTML5 module in scope will be called `Html5`, and similarly there will be a module `Svg`. This is in line with what `pa_tyxml` expects. However, these obviously shadow the real `Html5` and `Svg`.\r\n- [ ] Deal with string delimiter representation in 4.03.\r\n- [ ] Ensure 4.03 compatibility.\r\n- [x] Fix labeled argument filter (see comments below).\r\n- [ ] Module-qualify top-level calls to `pcdata` and other combinators.\r\n- [x] Whether the quotation is HTML or SVG is determined automatically from the elements inside, but this does not work for `a`, because there are `a` elements in both HTML and SVG. Deal with this.\r\n- [ ] Document clearly how locations are adjusted before being reported to users in errors.\r\n- [x] Annotate `a_fs_rows` and `a_fs_cols`.\r\n\r\nAlso, as we have agreed, the PPX would benefit from having a test suite (as would the rest of TyXML)."},"comment":{"url":"https://api.github.com/repos/ocsigen/tyxml/issues/comments/204598637","html_url":"https://github.com/ocsigen/tyxml/pull/89#issuecomment-204598637","issue_url":"https://api.github.com/repos/ocsigen/tyxml/issues/89","id":204598637,"user":{"login":"aantron","id":12073668,"avatar_url":"https://avatars.githubusercontent.com/u/12073668?v=3","gravatar_id":"","url":"https://api.github.com/users/aantron","html_url":"https://github.com/aantron","followers_url":"https://api.github.com/users/aantron/followers","following_url":"https://api.github.com/users/aantron/following{/other_user}","gists_url":"https://api.github.com/users/aantron/gists{/gist_id}","starred_url":"https://api.github.com/users/aantron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aantron/subscriptions","organizations_url":"https://api.github.com/users/aantron/orgs","repos_url":"https://api.github.com/users/aantron/repos","events_url":"https://api.github.com/users/aantron/events{/privacy}","received_events_url":"https://api.github.com/users/aantron/received_events","type":"User","site_admin":false},"created_at":"2016-04-01T22:54:53Z","updated_at":"2016-04-01T22:54:53Z","body":"🎉\r\n\r\nAgreed. The PR was getting quite monstrous."}}