Git Product home page Git Product logo

tyxml's Introduction

TyXML

TyXML is a library for building statically correct HTML5 and SVG documents:

open Tyxml
let to_ocaml = Html.(a ~a:[a_href "ocaml.org"] [txt "OCaml!"])

Tyxml can also be used with the standard HTML syntax, using the PPX:

open Tyxml
let%html to_ocaml = "<a href='ocaml.org'>OCaml!</a>"

Finally, TyXML can be used with Reason's JSX syntax:

open Tyxml;
let to_reason = <a href="reasonml.github.io/"> "Reason!" </a>

TyXML provides a set of combinators which use the OCaml type system to ensure the validity of the generated document. TyXML can be used on a wide variety of context, either to produce textual documents, to manipulate the DOM tree using Js_of_ocaml, build virtual DOM with virtual-dom, or for tierless web programming with Eliom.

The documentation can be consulted on the TyXML website. Examples are available in the examples directory.

Installation

TyXML is available in OPAM:

opam install tyxml

To install the PPX:

opam install tyxml-ppx

To install the JSX:

opam install tyxml-jsx

tyxml's People

Contributors

aantron avatar balat avatar benozol avatar chambart avatar drup avatar eyyub avatar florentbecker avatar ghuysmans avatar glondu avatar hhugo avatar hnrgrgr avatar ilankri avatar jorisgio avatar julow avatar khady avatar kit-ty-kate avatar krys27 avatar malthe avatar mbodin avatar mfp avatar nurpax avatar sagotch avatar shepard8 avatar slegrand45 avatar smorimoto avatar thizanne avatar ulrikstrid avatar vasilisp avatar vouillon avatar yakobowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tyxml's Issues

Templating and ppx for tyxml

There has been several request of a templating method in tyxml. Also, with the various other ppx coming, finally cleaning up the syntax extension question might be a good idea.

Here are my notes and ideas on how to do it:

  1. Having a decent html parsing library. Either we use something simple that only parses valid html, or something more complicated (see this discussion in particular). It doesn't have to be the first thing done.
  2. Create a systematic way to translate html documents into tyxml function. Currently, some functions in tyxml are not exactly the html element's name (because of syntactic restriction in html, or disambiguation, and so on). This would also be the occasion to normalize and rationalize tyxml's naming convention. @eyyub started such work in https://github.com/Eyyub/ppx_tyxml
  3. Write a ppx for a syntax extension and something that can take an html tree with holes and produce an ocaml function out of it. It will basically be the exact same thing anyway.

<:svg<>> quotation expander doesn't work.

module Svg = Svg.M;;
let _ = <:svg< <svg> </svg> >>;;
Error: Unbound type constructor Svg_types.svg_attrib
Did you mean svg_attr?

Looking though Svg_types there is indeed no type svg_attrib.

I am not sure the bug is in Svg_types (for consistency with Html_types) or the syntax extension. I made a minor fix in the later (xhtmlsyntax.ml, line 367) to read

  value make_attribs_type _loc tag =
    <:ctyp< Svg.attrib [< Svg_types.$lid:String.lowercase tag^"_attr"$] >>;

and we get svg output!

# let svg l = Svg.P.print_list ~output:print_string l;;

# module Svg = Svg.M;;

# let x = <:svg<
    <svg>
        <circle>
        </circle>
    </svg>
>>
;;

# svg [x];;
<svg>
        <circle>
        </circle>
    </svg>- : unit = ()

(apologies, I know I should do a pull request, but I am just learning this git malarkey).

Please: install the PPX by default for usability

TyXML should come ready with its own PPX. I shouldn't have to mind special instructions to get it. What is the penalty from installing it?

  • The PPX reduces the amount of up-front learning to use TyXML.
  • The PPX "knows" TyXML's irregularities, and replaces everything with familiar HTML and SVG syntax. Especially in the case of SVG, consider e.g.: #129 (comment). It takes many trips to the docs to figure combinators out for even relatively simple elements. The PPX simplifies this considerably, so it is not a second-class part of TyXML.
  • We know there at least some people excited about the PPX. This gives "some" idea that "people" think the PPX important for TyXML.

Given that, there shouldn't be an artificial stumbling block on the way to using it. This especially concerns OCaml/OPAM newbies, who may not see the message and may not be able to readily diagnose why TyXML is "not working."

Also, a user of TyXML shouldn't have to make markup into a root (explicitly chosen) package just to fully use TyXML. Indeed, there is no reason why a user of TyXML should be particularly aware of markup at all, any more than re or uutf.

Coding style

Following ocsigen/ocsigenserver#17, I pushed the same file as in ocsigenserver (see 5206f7e).
We will need to wait that every pull-request is merged, as whitespace commits are not very nice from a merge point of view.

Tyxml does not compile ?

Tyxml does not compile on my machine (debian wheezy), but the error log is not very useful.

ERROR [while upgrading to tyxml.9999]
opam-version 1.1.0 (db8768f5cab350ba6eed02e908422e57b4e30698)
os linux
command make
path /home/nox/.opam/system/build/tyxml.9999
compiler system (3.12.1)
exit-code 2
env-file /home/nox/.opam/system/build/tyxml.9999/tyxml-8862-335865.env
stdout-file /home/nox/.opam/system/build/tyxml.9999/tyxml-8862-335865.out
stderr-file /home/nox/.opam/system/build/tyxml.9999/tyxml-8862-335865.err
stdout
...[truncated]
ocamlfind ocamlc -package camlp4 -pp "camlp4rf -loc loc" -c simplexmlparser.ml
ocamlfind ocamlopt -package camlp4 -pp "camlp4of -loc loc" -c xmllexer.ml
ocamlfind ocamlopt -package camlp4 -pp "camlp4rf -loc loc" -c simplexmlparser.ml
ocamlfind ocamlopt -package camlp4 -shared -linkall -o xmllexer.cmxs xmllexer.cmx
ocamlfind ocamlopt -package camlp4 -shared -linkall -o simplexmlparser.cmxs simplexmlparser.cmx
make[1]: Leaving directory /home/nox/.opam/system/build/tyxml.9999/syntax' make -C lib byte opt make[1]: Entering directory/home/nox/.opam/system/build/tyxml.9999/lib'
ocamlfind ocamlc -annot -bin-annot -c xml_sigs.mli
make[1]: Leaving directory `/home/nox/.opam/system/build/tyxml.9999/lib'
stderr
...[truncated]
-use-prims (undocumented)
-dparsetree (undocumented)
-drawlambda (undocumented)
-dlambda (undocumented)
-dinstr (undocumented)

  • Treat as a file name (even if it starts with `-')
    -help Display this list of options
    --help Display this list of options
    make[1]: *** [xml_sigs.cmi] Error 2
    make: *** [all] Error 2

Installing tyxml with opam

I can't install tyxml with opam, whatever the version is ( 2.0, 3.0.0, and dev version from https://github.com/ocsigen/opam-ocsigen ).
Here is the errors for tyxml.9999 :

===== ERROR while installing tyxml.9999 =====
# opam-version 1.1.1
# os           linux
# command      make
# path         /home/me/.opam/system/build/tyxml.9999
# compiler     system (4.01.0)
# exit-code    2
# env-file     /home/me/.opam/system/build/tyxml.9999/tyxml-2408-ad8886.env
# stdout-file  /home/me/.opam/system/build/tyxml.9999/tyxml-2408-ad8886.out
# stderr-file  /home/me/.opam/system/build/tyxml.9999/tyxml-2408-ad8886.err
### stdout ###
# ...[truncated]
# /usr/bin/ocamllex -q syntax/xmllexer.mll
# /home/me/.opam/system/bin/ocamlfind ocamldep -package camlp4 -package camlp4.lib -modules syntax/xmllexer.ml > syntax/xmllexer.ml.depends
# /home/me/.opam/system/bin/ocamlfind ocamldep -package camlp4 -package camlp4.lib -pp camlp4rf -modules syntax/basic_types.ml > syntax/basic_types.ml.depends
# + /home/me/.opam/system/bin/ocamlfind ocamldep -package camlp4 -package camlp4.lib -pp camlp4rf -modules syntax/basic_types.ml > syntax/basic_types.ml.depends
# sh: 1: camlp4rf: not found
# Preprocessing error on file syntax/basic_types.ml
# Error while running external preprocessor
# Command line: camlp4rf 'syntax/basic_types.ml' > /tmp/ocamlppde05e1
# 
# Command exited with code 2.
### stderr ###
# ocamlfind: Package `wikidoc' not found
# E: Failure("Command ''/usr/bin/ocamlbuild' lib/tyxml.cma lib/tyxml.cmxa lib/tyxml.a lib/tyxml.cmxs lib/tyxml_f.cma lib/tyxml_f.cmxa lib/tyxml_f.a lib/tyxml_f.cmxs syntax/pa_tyxml.cma syntax/pa_tyxml.cmxa syntax/pa_tyxml.a syntax/pa_tyxml.cmxs syntax/tymlx_p.cma syntax/tymlx_p.cmxa syntax/tymlx_p.a syntax/tymlx_p.cmxs -tag debug' terminated with error code 10")
# make: *** [build] Erreur 1

'opam install eliom' failed.

Spaces/newline inside html causes ppx failure

@aantron As discussed. Do you have an angle on this one ? I have really no idea how to solve itL Should it be solved in tyxml or markup ?

This is the last thing that is really blocking for the release, Locations can benefit from later improvements.

The functor version is currently broken

I get this error:

Error: Error while linking /home/jerome/.opam/4.02.3/lib/tyxml/tyxml_f.cma(Html5_f):
Reference to undefined global `Xml'

I believe this is because we now to refer to Xml.string_of_uri in module Wrapped_functions in html5_f.ml.

I don't know how to fix that.

support for dtd parsing (depend/merge with xmllight?)

facts

so It might be a good idea to

  • depend on xmllight
  • push tyxml-xml-feature-only to xmllight.

I guess the major improvement/feature in tyxml is the $ syntax.

PS : It is impossible to use both Tyxml and Xmllight at the same time due to name collision (ie: module Xml). we had to forked and pack xmllight as a workarround (https://github.com/besport/xml-light)

Composability issues with the ppx

Here is an example of something that doesn't work:

let mytitle = [%html5 "<title>A Fabulous Web Page</title>" ]

let mypage = [%html5
  "<html>
    <head>"mytitle"</head>
    <body></body>"
]

Error message by markup: "head element must have exactly one title child element".

I don't know how solvable it is. It sounds tricky.

Consider removing the "5" from "Html5"

Against using "HTML5" in the API:

  • If a new major version of the HTML spec comes out (HTML6?), Html5 and [%html5] will look dated, but they will have to be kept for compatibility.
  • W3C calls the language "HTML." "HTML5" is just part of the title of the current spec (and, IIRC, an abbreviation for it).
  • The WhatWG Living Standard doesn't have a concept of HTML5 (IIRC).
  • TyXML trees can be serialized to syntax other than HTML5, such as (non-polyglot) XHTML.

One point in favor might be that a future revision of HTML might not be backwards-compatible with HTML5 and earlier versions. However, W3C hasn't made a serious breaking change to date, except for deprecating features. Those can be handled with deprecation annotations. Indeed, XHTML apparently did not catch on due to breaking changes, so W3C and WhatWG are likely to avoid them in the future.

HTML5 should, of course, be used in documentation and announcements, as long as it is the most recent major version of HTML :)

Compatibility for existing code using module Html5 can be accomplished by making the Html5* modules include the corresponding Html* modules. Perhaps TyXML can silently stop mentioning the Html5* modules in the documentation. I haven't tested it, but I wonder if [@@@ocaml.deprecated] works at the module level?

New code should probably just use "HTML", e.g. [%html] for the PPX.

4.0 Release list

This is a TODO list to keep track of things.

General:

  • Merge #95
  • Fix ocsigen/eliom#275
  • Make sure things are not completely broken
  • Implement template generation and provide ocamlbuild rules.
  • Ensure compat with 4.03

Doc

  • Make a simple example of functor application (maybe simply redirect to implem/ ?). Improve the relevant documentation.
  • Document the ppx, both standalone and inside the new tutorial.
  • Add ppx examples equivalent to the non-ppx examples.
  • Add a Contributing.md detailing how to add an attribute/element.

fix github repo description

It should be "OCaml library to build valid HTML5 and SVG trees." The O and C should be capitalized in OCaml and trees should be plural.

Tyxml does not compile on debian with kernel 3.2 ?

Hello,

I have a problem, tyxml.9999 does not compile on one of my machine on Debian jessie. I use ocaml 4.00.1
I tried with ocaml 4.01.0, it does not compile either.
I tried with ocaml 3.12.1, it works, but I need it on 4.00.1 to use dev version for the others ocsigen project.

I tried to install it with opam lot of time on new "clean" machine without success.
I also checked if it works by cloning the git repo, but it isn't.

This is the return of uname -a, if it might help you.
Linux pumgrana 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux

The opam list return
Installed packages for 4.00.1:
base-bigarray base Bigarray library distributed with the OCaml compiler
base-threads base Threads library distributed with the OCaml compiler
base-unix base Unix library distributed with the OCaml compiler
biniou 1.0.6 Binary data format designed for speed, safety, ease of use and backward compatibility as protocols evolve
calendar 2.03.2 Library for handling dates and times in your program
conf-libpcre 1 Virtual package relying on a libpcre system installation.
cppo 0.9.3 Equivalent of the C preprocessor for OCaml programs
cryptokit 1.9 Cryptographic primitives library.
dbm 1.0 Binding to the NDBM/GDBM Unix "databases"
deriving 9999 Extension to OCaml for deriving functions from type declarations
easy-format 1.0.1 High-level and functional interface to the Format module of the OCaml standard library
js_of_ocaml 9999 Compiler from OCaml bytecode to Javascript
lwt 2.4.4 A cooperative threads library for OCaml
menhir 20130912 LR(1) parser generator
ocamlfind 1.4.0 A library manager for OCaml
ocamlnet 3.7.3 Internet protocols (http, cgi, email etc.) and helper data structures (mail messages, character sets, etc.)
optcomp 1.5 Optional compilation with cpp-like directives
pcre-ocaml 7.0.2 Interface to the PCRE (Perl-compatibility regular expressions) library
react 0.9.4 Module for functional reactive programming (FRP)
ssl 0.4.6 Bindings for the libssl
yojson 1.1.6 Yojson is an optimized parsing and printing library for the JSON format

This is the error what I get:
opam-version 1.1.1 (846c72bb3e75a169100319a6af15b3b7b3b833df) os linux command make path /home/exploit/.opam/4.00.1/build/tyxml.9999 compiler 4.00.1 exit-code 2 env-file /home/exploit/.opam/4.00.1/build/tyxml.9999/tyxml-30687-c61e7b.env stdout-file /home/exploit/.opam/4.00.1/build/tyxml.9999/tyxml-30687-c61e7b.out stderr-file /home/exploit/.opam/4.00.1/build/tyxml.9999/tyxml-30687-c61e7b.err --- stdout --- ...[truncated] ocamlfind ocamlc -annot -bin-annot -c xhtml.mli ocamlfind ocamlc -annot -bin-annot -c xhtml.ml ocamlfind ocamlc -annot -bin-annot -c svg.mli ocamlfind ocamlc -annot -bin-annot -c svg.ml ocamlfind ocamlc -annot -bin-annot -c html5.mli ocamlfind ocamlc -annot -bin-annot -c html5.ml ocamlfind ocamlc -annot -bin-annot -a xml_iter.cmo xml_print.cmo xhtml_f.cmo svg_f.cmo html5_f.cmo xml.cmo xhtml.cmo svg.cmo html5.cmo -o tyxml.cma ocamlfind ocamlc -annot -bin-annot -a xml_iter.cmo xml_print.cmo xhtml_f.cmo svg_f.cmo html5_f.cmo -o tyxml_f.cma ocamlducefind ocamlc -thread -c xml_sigs_duce.mli make[1]: Leaving directory /home/exploit/.opam/4.00.1/build/tyxml.9999/lib'
--- stderr ---
File "xml_sigs_duce.mli", line 1, characters 0-1:
Error: xml_sigs.cmi
is not a compiled interface
make[1]: *** [xml_sigs_duce.cmi] Error 2
make: *** [all] Error 2`

Have you any idea where it might come from ?

Thank you in advance,
Arnaud

IDEs and the ppx

Editing html with the ppx is ... a bit annoying.

  • You don't get any fancy html handling/coloring. It would be nice to have something for that.
    • Emacs: I know it's possible to do some fancy submodes but I don't know how to do it (and how easy it would be to distribute). cc @gsg @Chris00 ?
    • Vim : I'm not even sure who to call. @rgrinberg ?
    • Others : ???
  • Indentation by ocp-indent is terrible. @AltGr, can we do something about it ?

(See here for what the syntax looks like)

pa_tyxml, compilation with ocamlfind/ocamlbuild

> ocamlbuild -use-ocamlfind iocaml_lib.cma -classic-display

ocamlfind ocamldep -syntax camlp4o -package tyxml -package tyxml.syntax -package iocaml -modules iocaml_image.mli > iocaml_image.mli.depends

ocamlfind: Using -syntax, but no package is selected specifying a preprocessor as required for -syntax
Command exited with code 2.

Modifying the META file to include the line:

package "syntax" {
...
requires = "camlp4"
...
}

allows it to compile.

Can't build on raspbian

Hi,

trying to install eliom I get an error like below. (More text after the log output)

root@raspberrypi:~# opam install tyxml
The following actions will be performed:
 - install tyxml.9999
1 to install | 0 to reinstall | 0 to upgrade | 0 to downgrade | 0 to remove

=-=-= Installing tyxml.9999 =-=-=
tyxml.9999 Fetching https://github.com/ocsigen/tyxml.git
Building tyxml.9999:
  make
  make install
[ERROR] The compilation of tyxml.9999 failed.
Removing tyxml.9999.
  ocamlfind remove tyxml


===== ERROR while installing tyxml.9999 =====
# opam-version 1.1.0
# os           linux
# command      make
# path         /root/.opam/system/build/tyxml.9999
# compiler     system (4.01.0)
# exit-code    2
# env-file     /root/.opam/system/build/tyxml.9999/tyxml-22089-ad8886.env
# stdout-file  /root/.opam/system/build/tyxml.9999/tyxml-22089-ad8886.out
# stderr-file  /root/.opam/system/build/tyxml.9999/tyxml-22089-ad8886.err
### stdout ###
# ...[truncated]
# ocamlfind ocamlc -annot -bin-annot    -c xhtml.mli
# ocamlfind ocamlc -annot -bin-annot    -c xhtml.ml
# ocamlfind ocamlc -annot -bin-annot    -c svg.mli
# ocamlfind ocamlc -annot -bin-annot    -c svg.ml
# ocamlfind ocamlc -annot -bin-annot    -c html5.mli
# ocamlfind ocamlc -annot -bin-annot    -c html5.ml
# ocamlfind ocamlc -annot -bin-annot   -a xml_iter.cmo xml_print.cmo xhtml_f.cmo svg_f.cmo html5_f.cmo xml.cmo xhtml.cmo svg.cmo html5.cmo -o tyxml.cma
# ocamlfind ocamlc -annot -bin-annot   -a xml_iter.cmo xml_print.cmo xhtml_f.cmo svg_f.cmo html5_f.cmo -o tyxml_f.cma
# ocamlducefind ocamlc  -thread  -c xml_sigs_duce.mli
# make[1]: Leaving directory `/root/.opam/system/build/tyxml.9999/lib'
### stderr ###
# Fatal error: cannot load shared library dllnums
# Reason: /usr/local/lib/ocaml/stublibs/dllnums.so: undefined symbol: caml_hash_mix_uint32
# make[1]: *** [xml_sigs_duce.cmi] Fel 2
# make: *** [all] Fel 2

'opam install tyxml' failed.

Comparing another report it was suggested that remove cduce would help a similar problem. cduce was not installed when trying to install tyxml.
Running opam install cduce followed by opam install tyxml gives the same error.

/Jörgen

Boolean attributes and Html5.R

The parameter of boolean attributes like a_readonly and a_disabled are singular types. A consequence of this is that reactive wrapping of these in Eliom_content does not provide the desired functionality. Since these attribute really needs to be omitted to represent false, I suggest adding a special case `Absent or similar to boolean attributes to that effect.

(It would be more convenient if the parameter was a real bool, but this can be implemented on top of the HTML5-faithful variants as e.g. let b_readonly e = if e then ReadOnly else Absent).)

Ppx ideas

I'm not sure those are good ideas, but we can at least think about them. :)

  • Allow to write
    [%html "<foo>" bar ; baz "</foo>"]
    instead of
    [%html "<foo>" [bar ; baz] "</foo>"]
    It's probably far too clever and irregular for its own good.
  • Allow slicing directly inside the text with some %bar syntax.
    [%html "<foo>%bar</foo>"]
    instead of
    [%html "<foo>"bar"</foo>"]
    Would be convenient to avoid constant quoting-unquoting.

using img tag in syntax extension?

If I have img tag in html syntaxt extension based on HTML5.F I cannot use src or alt attributes:

let module Html5 = Eliom_content.Html5.F in
 <:html5list<
<img class="hexa big" alt="hexagram" src="http://example.com" />
>>

Does not compile:

Error: This expression cannot be coerced to type
         ([< Html5_types.img_attrib ] as 'a) Html5.attrib list;
       it has type ([> `Alt | `Class | `Src ] as 'b) Html5.attrib list
       but is here used with type 'a Html5.attrib list
       Type 'b Html5.attrib = 'b Eliom_content.Html5.attrib
       is not compatible with type
         'a Html5.attrib = 'a Eliom_content.Html5.attrib 
       Type 'b is not compatible with type
         'a =
           [< `Accesskey
            | `Class
            | `Contenteditable
            | `Contextmenu
            | `Dir
            | `Draggable
            | `Height
            | `Hidden
            | `Id
            | `Ismap
            | `OnAbort
            | `OnBlur
            | `OnCanPlay
            | `OnCanPlayThrough
            | `OnChange
            | `OnClick
            | `OnContextMenu
            | `OnDblClick
            | `OnDrag
            | `OnDragEnd
            | `OnDragEnter
            | `OnDragLeave
            | `OnDragOver
            | `OnDragStart
            | `OnDrop
            | `OnDurationChange
            | `OnEmptied
            | `OnEnded
            | `OnError
            | `OnFocus
            | `OnFormChange
            | `OnFormInput
            | `OnInput
            | `OnInvalid
            | `OnKeyDown
            | `OnKeyPress
            | `OnKeyUp
            | `OnLoad
            | `OnLoadStart
            | `OnLoadedData
            | `OnLoadedMetaData
            | `OnMouseDown
            | `OnMouseMove
            | `OnMouseOut
            | `OnMouseOver
            | `OnMouseUp
            | `OnMouseWheel
            | `OnPause
            | `OnPlay
            | `OnPlaying
            | `OnProgress
            | `OnRateChange
            | `OnReadyStateChange
            | `OnScroll
            | `OnSeeked
            | `OnSeeking
            | `OnSelect
            | `OnShow
            | `OnStalled
            | `OnSubmit
            | `OnSuspend
            | `OnTimeUpdate
            | `OnVolumeChange
            | `OnWaiting
            | `Spellcheck
            | `Style_Attr
            | `Tabindex
            | `Title
            | `User_data
            | `Width
            | `XML_lang
            | `XMLns ] 
       The second variant type does not allow tag(s) `Alt, `Src

Am I missing something ot is it a bug?

Comments, RAWTEXT, script data, etc., should not be escaped

See the specification for serialization.

However, this program

open Html5.M
open Html5.P

let () =
  print_list print_string
    [tot (Xml.comment "foo&");
     script (pcdata "foo&");
     style [pcdata "foo&"]]

produces this output:

<!--foo&amp;--><script>foo&amp;</script><style>foo&amp;</style>

In particular, this seems to prevent comments such as:

<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->

being generated by expressions such as

tot (Xml.comment "[if IE 8]> <html class=\"no-js lt-ie9\" lang=\"en\"> <![endif]")

(credit to @sgrove for a query).

In the case of comments, if the user includes --> as text, we obviously have a problem if we "fix" this issue. Perhaps we can escape only those. Similarly, in RAWTEXT of a style tag, we may have to handle </style>.

Rather than fixing this immediately in TyXML, I propose that before TyXML 4.0,

  • I split up Markup.ml into subpackages, or aliased modules, one of which will include the HTML writer, but exclude any other writers or parsers,
  • I add a polyglot output mode to Markup.ml,
  • Markup.ml (IIRC) already properly doesn't escape the above fragments, but we decide what to do about --> in comments, etc., and do it, or support doing it, in Markup.ml,
  • we use Markup.ml's HTML writer to do the HTML writing.

This will leave us with only one place at which to maintain conformance with HTML5 and XHTML. It will add Markup.ml as a run-time dependency to projects using TyXML (as opposed to only build-time with the PPX). The split of Markup.ml into packages or aliased submodules should prevent the linking of unnecessary code into users' programs, such as the enormous HTML5 parser.

wiki content rendering error

In functors.wiki, the line:

The ##W## module in <<a_api | module Xml_sigs.T>> allows

renders on the website with an error:

The W module in Error a_api: invalid contents allows

Inadequate translation of figure and figcaption tags

A figure with caption can be built as in the following example:

let fig =
  figure
    ~figcaption:(figcaption [ pcdata "Legend" ])
    [ img [ ... ] ]

The trouble is that the generated html looks like

<figure>
  <figcaption>Legend</figcaption>
  <img>...</img>
</figure>

which places the legend at the top of the figure, while most often a legend should be at the foot of the figure.

The definition of figure in Html5 could be changed either to reflect the most frequent use case:

let figure ?figcaption ?a elts =
      Xml.node ?a "figure" (elts @ (list_of_option figcaption))

either to let the choice to the user:

val figure : 
  ?figcaption:[`top of [< `Figcaption ] elt | `bottom of [< `Figcaption ] elt] ->
  ([< Html5_types.common ], [< Html5_types.flow5 ], [> `Figure ])
  star

Missing constructors for text attributes

I'm not sure if this qualifies as a known issue, unknown issue, or just something I'm missing: in the type defining the valid attributes for the SVG text element, one can find the variants TextLength | Text_Anchor | Text_Decoration | Text_Rendering. Besides the lack of uniformity (CamelCase vs Snake_Case), note that Svg_sigs.T declares the constructor function a_textlength for the first variant, but not for the others.

I can submit a pull request if you want. It seems fairly straightforward to fix anyway.

Add a mini-template syntax

Some users wants a template syntax, but IMHO it's not what we want. Instead, we can have (yet) another syntax extension for making the html result more readable.

Here is my proposal for this syntax:

let s = pcdata in
let delete = a ~service:Services.delete_feed [s "delete"] () in
let edit = a ~service:Services.edit_feed [s "edit"] () in
TMPL(s) "($delete | $edit)"

This syntax is PGOCaml-like so it should be doable and it's definitively more readable than (the code produced):

[s "("; delete; s " | "; edit; s ")"]

So this extension is more or less a format-like syntax that produce an html elements list.
The parameter of TMPL is the function used for insert strings (in most cases, it's pcdata).

EDIT:
The good idea submitted by @Drup is instead of having a string in parameter, allowing to have a filename like this:

TMPL_FILE(s) "templates/view.tmpl"

With the content of templates/view.tmpl like:

($delete | $edit)

IMHO, we should allow both.

Consistent naming scheme for html and svg elements.

Consistency is not W3C's strong point, but it's made worse in tyxml. The main pain point is dashes, since they are not valid in ocaml's identifiers.

So a more formal version of what we are currently loosely applying:

  • We always keep the name in the specification if it's a valid ocaml identifier, be it snake_case, nocase, CamlCase or whatever, even if it's internally inconsistent (I'm looking at you, fontFace)

  • Dashes are transformed in underscores systematically.

  • Underscores are kept.

  • Any other characters that could ever appear are transformed in an underscore too. I don't think I ever saw one, but better be sure.

  • In case of conflict between attributes of incompatible types. We put the element that it's disambiguated for between underscores, after the a.

    Example: the attribute max for input is transformed in a_input_max.

  • Specific transformation rules:

    • When transforming to an element, the first letter become a lowercase.
    • When transforming to a polymorphic variant, the first letter is capitalized. This is not mandatory (since polymorphic variant can start with a lowercase), but it's acceptable and is already applied almost consistently, so better keep it.
    • When transforming to an attribute, no letter is changed (it's ok, it starts with a_).

These should also keep the breaking rather minimal. Remarks ?
cc @dsheets since you might have an opinion. :)

Merge classes when several class attributes given

I think it would be interesting to be able to put several class attributes.

let popup ?(a = []) content =
  let box = D.div ~a:(a_class ["popup"]::a) content in
  ...

Here my function creates a widget popup.
All popups have class "popup".
But I'd like to make possible for user to customize the widget by adding any attribute he wants.

With the current version of tyxml, the code below does not work if a contains a class ...

link to _sigs modules in index

The indexdoc file doesn't link to Xml_sigs, Html5_sigs, and Svg_sigs. That would help, just so their existence is more readily obvious and you can get to them faster once you know they exist.

Right now you only find links to them if you investigate the docs for the functorial interface. Docs for the default interface only have things like Html5_sigs.Make(Xml)(Svg.M).T, but none of that is hyperlinked to the actual Html5_sigs.T signature you care about. You can click Html5_sigs.Make, so you do eventually get there, but a lot of links had to be traversed by then.

opam installation broken on FreeBSD

Hi,

Tested with tyxml.3.3.0 opam package on FreeBSD:

Building uutf.0.9.3:
./pkg/pkg-git
./pkg/build true
Installing uutf.0.9.3.
Building tyxml.3.3.0:
./configure --enable-syntax --prefix /sequoia/.opam/4.02.1
gmake
gmake install
[ERROR] The compilation of tyxml.3.3.0 failed.
Removing tyxml.3.3.0.
ocamlfind remove tyxml

#=== ERROR while installing tyxml.3.3.0 =======================================#

opam-version 1.2.0

os freebsd

command ./configure --enable-syntax --prefix /sequoia/.opam/4.02.1

path /sequoia/.opam/4.02.1/build/tyxml.3.3.0

compiler 4.02.1

exit-code 2

env-file /sequoia/.opam/4.02.1/build/tyxml.3.3.0/tyxml-65153-ffb3fd.env

stdout-file /sequoia/.opam/4.02.1/build/tyxml.3.3.0/tyxml-65153-ffb3fd.out

stderr-file /sequoia/.opam/4.02.1/build/tyxml.3.3.0/tyxml-65153-ffb3fd.err

stderr

make: don't know how to make ./setup.exe. Stop

=-=- Error report -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
These actions have been completed successfully

  • install uutf.0.9.3

The following failed

  • install tyxml.3.3.0

suggestions that break backwards compatibility

Due to #95, I get the impression big changes are feasible. I'd like to suggest a few:

  • Put all modules under a Tyxml namespace, and provide a Tyxml.Std module as the entry point to the API.
  • Rename T module types to S. This is the norm.
  • The term "wrap" isn't informative. If it is a monad, why not call it that. Thus some type names and module names could be changed.

@Drup Thank you for all your hard work! I especially respect your update to intro.wiki, which was terribly insufficient before.

Xml parser sucks sometimes

 # Simplexmlparser.xmlparser_string "<id><![CDATA[109753]]></id>";;
 Exception:
 Simplexmlparser.Xml_parser_error("Ident Expected (File \"ghost-location\", line 1, characters 3-6)").

Covariance issues with wrapping

While working with the ppx, I noticed something ... strange.

# let x = Html5.Xml.W.nil () ;;
val x : '_a list = []  
# let x : _ list = Html5.Xml.W.nil () ;;
val x : 'a list = []  

Apparently, the functor stack hides the covariance, since Xml_wrap.S.tlist is not marked covariant.
@vasilisp Do you think we could turn it covariant ? Are all the wrapper we have covariants ? Given the heavy use of subtyping, It would seems natural to enforce that.

Provide a translation module between html and js attributes

Currently, this translation module is hardcoded in js_of_ocaml and is quite partial (according to @hhugo). Given the new reflect mechanism we have in tyxml, it seems like it would be either to maintain inside tyxml directly.

I would tend to propose the following:

  • Add [@reflect.js "foo"] annotations.
  • Use a reflect-like mecanism to provide bi-directional dictionnaires.
  • Allow either the html or the js attributes for the ppx.

Figure out a way to export to lambdasoup

Currently, Xml_iter is very crude and not very used. I would like to both improve the functionality and deprecate the current interface.

We can do that by providing a way to export to lambdasoup. I would prefer to do it while not actually depending on lambdasoup, so some structural thing would be nice.
This would also potentially provide us with a good streaming printer, when one is added to lambdasoup.

Too much allocation when validating UTF-8 strings

Uutf.decoder and Uutf.encoder each allocate a large buffer (64 KiB) each time they are called.
So, we can't use these functions in Xml_print.Utf8.normalize_html and Xml_print.Utf8.normalize_from. Indeed, the first function is called a large number of times on each page. Instead, we should use the functions in Uutf.String and Uutf.Buffer.

There should also be a fast path for when the input string can clearly be returned unchanged: no character that needs to be escaped, and only ASCII characters.

Thanks to @hnrgrgr for finding this out (ocsigen/ocsigenserver#47) !

Simple svg circle

I would be very grateful if someone could quickly look at my attempt to draw a circle - I've tried quite a few permutations with little success:

let start (igor:#Dom.node Js.t) =
  Lwt.catch
    (fun () ->
      let open Tyxml_js.Svg in
      let my_circle = circle ~a:[a_cx "50" ; a_cy "50" ; a_r "40" ; a_stroke "green" ; a_stroke_width "4" ; a_fill "yellow"] in
      let my_svg =  svg ~a:[a_width "100" ; a_height "100"] in
      Dom.appendChild igor (Tyxml_js.To_dom.of_node my_svg);
      return ()
    )
    (fun ex ->
      raise ex
    )

let () =
  match Dom_html.tagged (Dom_html.getElementById "de_main") with
  | Dom_html.Div d -> Lwt_js_events.async (fun () -> start d)
  | _ -> failwith "Bad tree element"

with the error referring to let my_circle ....

Error: This expression has type string but an expression was expected of type
         Svg_types.Unit.length Tyxml_js.Svg.wrap =
           float *
           [ `Cm | `Em | `Ex | `In | `Mm | `Pc | `Percent | `Pt | `Px ]
           option

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.