Skip to content

Commit

Permalink
Merge pull request #155 from aantron/proofreading
Browse files Browse the repository at this point in the history
Documentation nit list.
  • Loading branch information
Drup committed May 7, 2016
2 parents a58eb4f + fe52b69 commit cfdf452
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 26 deletions.
54 changes: 54 additions & 0 deletions Contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# How to contribute changes

Thanks for contributing!

Here is a set of guidelines for contributing new elements and attributes to TyXML.

## How to add new elements and attributes

There are several steps to add new elements and attributes.
First off, you need to equip yourself with both the specification ([HTML][]/[SVG][]) and Mozilla's developer manual ([HTML][MSDNHTML]/[SVG][MSDNSVG]).

1. Figure out the right name

A small tool is available in TyXML sources for this purpose.
For example for the `foo-bar` attribute:
```sh
% ./autoname.byte -a "foo-bar"
Original name: foo-bar
Ocaml name: a_foo_bar
Poly variant: `Foo_bar
```

2. Figure out the right types

Types go in
[`Html_types`](lib/html_types.mli)/[`Svg_types`](lib/svg_types.mli).

For elements, this can be delicate, and there is no universal recipe, except reading the specification carefully.
For attributes, this is usually quite easy:
- If the attribute is for the element `myelem`, you need to add the attribute's polymorphic variants to `Html_types.myelem_attrib`.
- If the attributes is for every element, add it to `Html_types.common`.
3. Add the element/attribute
The implementation goes in
[`Html_f`](lib/html_f.ml)/[`Svg_f`](lib/svg_f.ml)
and the signature in
[`Html_sigs`](lib/html_sigs.mli)/[`Svg_sigs`](lib/svg_sigs.mli).
4. (Optional) If the attribute value uses a new data type, you might need to introduce a new function in [`Html_f.Wrapped_functions`](lib/html_f.ml) and a new value parser for the PPX in [`Ppx_attribute_value`](ppx/ppx_attribute_value.mli).
5. Document your change
- Link to the paragraph in the specification ([HTML][]/[SVG][]) in your commit message.
- Link to Mozilla's reference ([HTML][MSDNHTML]/[SVG][MSDNSVG]) in the `.mli`.
- Add your change to the [change log](CHANGES).

6. Test your change
- Regular tests go in [`test/test_html.ml`](test/test_html.ml).
- Ppx tests go in [`test/test_ppx.ml`](test/test_html.ml).

[HTML]: https://www.w3.org/TR/html5/
[SVG]: https://www.w3.org/TR/SVG11/
[MSDNHTML]: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference
[MSDNSVG]: https://developer.mozilla.org/en-US/docs/Web/SVG
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ open Tyxml
let to_ocaml = Html.(a ~a:[a_href "ocaml.org"] [pcdata "OCaml!"])
```

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

```ocaml
open Tyxml
Expand All @@ -32,7 +32,7 @@ TyXML is available in [OPAM](https://opam.ocaml.org/):
opam install tyxml
```

To install the ppx:
To install the PPX:
```sh
opam install tyxml_ppx
```
46 changes: 23 additions & 23 deletions doc/manual-wiki/intro.wiki
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= TyXML =

Tyxml is a library to build statically correct HTML and SVG documents.
Tyxml is a library for building statically correct HTML and SVG documents.

<<code language="ocaml"|
open Tyxml
Expand All @@ -15,20 +15,20 @@ To use TyXML in standalone manner, simply install the ##tyxml## OPAM package, li

=== Use with another library ===

TyXML combinators can be used in conjunction with other libraries, please consult the relevant document. For example, for
TyXML combinators can be used in conjunction with other libraries. Please consult the relevant document. For example,
<<a_manual project="eliom" chapter="clientserver-html"|Eliom>>
and
<<a_api project="js_of_ocaml" text="Js_of_ocaml"|module Tyxml_js>>.

=== Use with the ppx ===
=== Use with the PPX ===

Tyxml can also be used with the standard HTML syntax, using <<a_manual chapter="ppx"|the ppx syntax extension>>:
TyXML can also be used with the standard HTML syntax, using <<a_manual chapter="ppx"|the PPX syntax extension>>:
<<code language="ocaml"|
open Tyxml
let%html to_ocaml = "<a href='ocaml.org'>OCaml!</a>"
>>

This syntax is available both while using tyxml standalone, or with another library. In order to do so, install the ##tyxml_ppx## OPAM package and link the ##tyxml.ppx## ocamlfind library.
This syntax is available both while using TyXML standalone, or with another library. In order to do so, install the ##tyxml_ppx## OPAM package and link the ##tyxml.ppx## ##ocamlfind## library.

==@@id="creation"@@ Creating documents with TyXML ==

Expand All @@ -37,12 +37,12 @@ For standalone use, examples are available in the [[https://github.com/ocsigen/t

The documentation for TyXML combinators is provided in <<a_api|module Html_sigs.T>> and <<a_api|module Svg_sigs.T>> and is common to all instances of {{{Html}}} and {{{Svg}}}.

The first thing to understand about TyXML is that for most intents and purposes, it is exactly like HTML. As such, the [[https://developer.mozilla.org/en-US/docs/Web/HTML/Element|HTML reference]] is still very useful. For each HTML elements or attributes, there is a combinator implementing it. The main differences are that you can use OCaml to manipulate the elements and that invalid HTML produces a type error.
The first thing to understand about TyXML is that for most intents and purposes, it is exactly like HTML. As such, the [[https://developer.mozilla.org/en-US/docs/Web/HTML/Element|HTML reference]] is still very useful. For each HTML element or attribute, there is a combinator implementing it. The main differences are that you can use OCaml to manipulate the elements and that invalid markup produces a type error.

In this tutorial, we will build the [[https://github.com/ocsigen/tyxml/tree/master/examples/mini_website|Mini website]].
If you prefer the native HTML syntax, you can also use the <<a_manual chapter="ppx"|ppx syntax extension>> and consult the [[https://github.com/ocsigen/tyxml/tree/master/examples/mini_website_ppx|ppx mini website]].
If you prefer the native HTML syntax, you can also use the <<a_manual chapter="ppx"|PPX syntax extension>> and consult the [[https://github.com/ocsigen/tyxml/tree/master/examples/mini_website_ppx|PPX mini website]].

Let us start by building the content of our website. For text, we use the {{{pcdata}}} constructor. In traditional Web fashion, we put everything in a ##div##.
Let us start by building the content of our website. For text, we use the {{{pcdata}}} combinator. In traditional Web fashion, we put everything in a ##div##.
<<code language="ocaml"|
let mycontent =
div [
Expand All @@ -51,7 +51,7 @@ let mycontent =
>>

The variable ##mycontent## is of type {{{[> `Div] Html.elt}}}.
As we can see, the fact that this is a ##div## is reflected in the type. HTML elements are of type <<a_api text="elt"|type Html_sigs.T.elt>> and have a combinator of the same name, except when it's a reserved keyword (such as {{{object_}}}).
As we can see, the fact that this is a ##div## is reflected in the type. HTML elements are of type <<a_api text="elt"|type Html_sigs.T.elt>> and have a combinator of the same name, except when it's a reserved OCaml keyword (such as {{{object_}}}).

Our content is fabulous, but for the sake of CSS styling (and still in true Web fashion) we want to add a ##class## to it.
<<code language="ocaml"|
Expand All @@ -61,7 +61,7 @@ let mycontent =
]
>>

The <<a_api text="a_class"|val Html_sigs.T.a_class>> creates a new ##class## attribute of type {{{[> `Class] attrib}}}. Similarly to elements, the kind of attribute is reflect in the <<a_api text="attrib"|type Html_sigs.T.attrib>> type.
The <<a_api text="a_class"|val Html_sigs.T.a_class>> creates a new ##class## attribute of type {{{[> `Class] attrib}}}. Similarly to elements, the kind of attribute is reflected in the <<a_api text="attrib"|type Html_sigs.T.attrib>> type.
We use the optional argument {{{~a}}} to pass the list of attributes. This optional argument is available on all element combinators.

In order to add a title to our fabulous content, we use the <<a_api text="h1"|val Html_sigs.T.a>> combinator.
Expand All @@ -73,21 +73,21 @@ let mycontent =
]
>>

Naturally, {{{div}}} accepts several children. In TyXML vocabulary, this is a <<a_api text="star"|type Html_sigs.T.star>> constructor.
Naturally, {{{div}}} accepts several children. In TyXML vocabulary, this is a <<a_api text="star"|type Html_sigs.T.star>> combinator.
There are also
<<a_api text="unary"|type Html_sigs.T.unary>> and
<<a_api text="nullary"|type Html_sigs.T.nullary>> constructors,
which accepts respectively one and zero child.
<<a_api text="nullary"|type Html_sigs.T.nullary>> combinators,
which accept, respectively, one child and zero children.

<<a_api text="title"|val Html_sigs.T.title>> is an example of {{{unary}}}
<<a_api text="title"|val Html_sigs.T.title>> is an example of a {{{unary}}}
combinator.
<<code language="ocaml"|
let mytitle = title (pcdata "A Fabulous Web Page")
>>

====@@id="type-errors"@@ Interlude about type errors ====

However, what would happen if we were to try to put **bold** text in our title? This is not compliant! Let's try it.
However, what would happen if we were to try to put **bold** text in our title? This is not specification-compliant! Let's try it.
<<code language="ocaml"|
let mytitle = title (b [pcdata "A Bold Web Page"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -98,23 +98,23 @@ Error: This expression has type ([> Html_types.b ] as 'a) elt
The second variant type does not allow tag(s) `B
>>

As expected, this code does not typecheck!
The typechecker is unfortunately a bit unclear about the source of the error.
As expected, this code does not type-check!
The type checker is unfortunately a bit unclear about the source of the error.

It tells us that the given expression has type {{{[> b] elt}}}
(indeed, it is produced by a {{{b}}} constructor)
(indeed, it is produced by a {{{b}}} combinator)
but an expression is expected of type {{{[< title_content_fun] elt}}}
(which means that is is used as content for a {{{title}}} element).
It then tells us that, since {{{[> b] = [> `B]}}} and
{{{[< title_content_fun] = [< `PCDATA ]}}},
{{{`B}}} is not allowed inside a {{{title}}}.

In order to get reasonable type errors with TyXML, The ##-short-paths## options should always be used.
In order to get reasonable type errors with TyXML, The ##-short-paths## option should always be used when invoking OCaml.

====@@id="finishing"@@ Finishing up the webpage ====

To finish our webpage, we use the <<a_api text="body"|val Html_sigs.T.body>>, <<a_api text="head"|val Html_sigs.T.head>> and <<a_api text="html"|val Html_sigs.T.html>>.
The last two combinators have special types due to their specific constraints: <<a_api text="head"|val Html_sigs.T.head>> only accepts one ##title## children and <<a_api text="html"|val Html_sigs.T.html>> only accepts two children: ##head## and ##body##.
To finish our webpage, we use <<a_api text="body"|val Html_sigs.T.body>>, <<a_api text="head"|val Html_sigs.T.head>> and <<a_api text="html"|val Html_sigs.T.html>>.
The last two combinators have special types due to their specific constraints: <<a_api text="head"|val Html_sigs.T.head>> requires only one ##title## child, and <<a_api text="html"|val Html_sigs.T.html>> requires exactly two children: ##head## and ##body##.

<<code language="ocaml"|
let mypage =
Expand All @@ -135,11 +135,11 @@ let () =
close_out file
>>

Well done, you know have a very minimal (but fabulous) website! The implementation can be found [[https://github.com/ocsigen/tyxml/tree/master/examples/mini_website|here]].
Well done, you know have a very minimal (but fabulous) website! Once again, the implementation can be found [[https://github.com/ocsigen/tyxml/tree/master/examples/mini_website|here]].

Other examples are available in the [[https://github.com/ocsigen/tyxml/tree/master/examples/|examples]] directory.

==@@id="custom"@@ Using your own underlying implementation ==

You can use TyXML with any underlying implementation. In order to do so, we provide a set of functors.
You can use TyXML with any underlying implementation. In order to do so, TyXML provides a set of functors.
Please consult <<a_manual chapter="functors"|the relevant manual>>.
4 changes: 3 additions & 1 deletion tools/autoname.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ let arg = ref false

let answer_elem ~attrib s =
Printf.printf
"%s\t%s\t%s\n%!"
"Original name: \t%s\n\
Ocaml name: \t%s\n\
Poly variant: \t%s\n"
s
(if attrib then Tyxml_name.attrib s else Tyxml_name.ident s)
(Tyxml_name.polyvar s)
Expand Down

0 comments on commit cfdf452

Please sign in to comment.