Documentation++.

This commit is contained in:
Bodil Stokke 2018-11-17 20:38:07 +00:00
parent c0d9d679db
commit 276ba31432
6 changed files with 91 additions and 3 deletions

View File

@ -18,6 +18,93 @@ mod lexer;
mod map;
mod parser;
/// Construct a DOM tree.
///
/// # Syntax
///
/// This macro largely follows [JSX] syntax, but with some differences:
///
/// * Text nodes must be quoted, because there's only so much Rust's tokeniser
/// can handle outside string literals. So, instead of `<p>Hello</p>`, you
/// need to write `<p>"Hello"</p>`. (The parser will throw an error asking you
/// to do this if you forget.)
/// * Element attributes will accept simple Rust expressions, but the parser has
/// its limits, as it's not a full Rust parser. You can use literals,
/// variables, dotted properties and single function or method calls. If you
/// use something the parser isn't currently capable of handling, it will
/// complain. You can put braces or parentheses around the expression if the
/// parser doesn't understand it. You can use any Rust code inside a brace or
/// parenthesis block.
///
/// # Valid HTML5
///
/// The macro will only accept valid HTML5 tags, with no tags or attributes
/// marked experimental or obsolete. If it won't accept something you want it to
/// accept, we can discuss it over a pull request (experimental tags and
/// attributes, in particular, are mostly omitted just for brevity, and you're
/// welcome to implement them).
///
/// The structure validation is simplistic by necessity, as it defers to the
/// type system: a few elements will have one or more required children, and any
/// element which accepts children will have a restriction on the type of the
/// children, usually a broad group as defined by the HTML spec. Many elements
/// have restrictions on children of children, or require a particular ordering
/// of optional elements, which isn't currently validated.
///
/// # Attribute Values
///
/// Brace blocks in the attribute value position should return the expected type
/// for the attribute. The type checker will complain if you return an
/// unsupported type. You can also use literals or a few simple Rust expressions
/// as attribute values (see the Syntax section above).
///
/// The `html!` macro will add an `.into()` call to the value expression, so
/// that you can use any type that has an `Into<A>` trait defined for the actual
/// attribute type `A`.
///
/// As a special case, if you use a string literal, the macro will instead use
/// the `FromStr<A>` trait to try and parse the string literal into the expected
/// type. This is extremely useful for eg. CSS classes, letting you type
/// `class="css-class-1 css-class-2"` instead of going to the trouble of
/// constructing a `SpacedSet<Class>`. The big caveat for this: currently, the
/// macro is not able to validate the string at compile time, and the conversion
/// will panic at runtime if the string is invalid.
///
/// ## Example
///
/// ```no_compile
/// let classList: SpacedSet<Class> = ["foo", "bar", "baz"].into();
/// html!(
/// <div class="foo bar baz"></div> // parses a string literal
/// <div class=["foo", "bar", "baz"]></div> // uses From<[&str, &str, &str]>
/// <div class=classList></div> // uses a variable in scope
/// <div class={ // evaluates a code block
/// SpacedSet::from(["foo", "bar", "baz"])
/// }></div>
/// )
/// ```
///
/// # Generated Nodes
///
/// Brace blocks in the child node position are expected to return an
/// `IntoIterator` of `DOMTree`s. You can return single elements or text nodes,
/// as they both implement `IntoIterator` for themselves. The macro will consume
/// this iterator at runtime and insert the generated nodes as children in the
/// expected position.
///
/// ## Example
///
/// ```no_compile
/// html!(
/// <ul>
/// { (1..=5).map(|i| html!(
/// <li>{ text!("{}", i) }</li>
/// )) }
/// </ul>
/// )
/// ```
///
/// [JSX]: https://reactjs.org/docs/introducing-jsx.html
#[proc_macro]
pub fn html(input: TokenStream) -> TokenStream {
let stream = lexer::unroll_stream(input, false);
@ -31,6 +118,8 @@ pub fn html(input: TokenStream) -> TokenStream {
}
}
/// This macro is used by `typed_html` internally to generate types and
/// implementations for HTML elements.
#[proc_macro]
pub fn declare_elements(input: TokenStream) -> TokenStream {
let stream = lexer::keywordise(lexer::unroll_stream(input, true));

View File

@ -14,7 +14,6 @@ use htmlescape::encode_minimal;
///
/// ```
/// # #![feature(proc_macro_hygiene)]
/// # extern crate typed_html;
/// # use typed_html::html;
/// # use typed_html::dom::DOMTree;
/// # fn main() {

View File

@ -31,7 +31,6 @@ macro_rules! declare_events {
///
/// ```
/// # #![feature(proc_macro_hygiene)]
/// # extern crate typed_html;
/// # use typed_html::{html, for_events};
/// # use typed_html::dom::{DOMTree, VNode};
/// # fn main() {

View File

@ -11,6 +11,7 @@ extern crate stdweb;
extern crate strum;
extern crate typed_html_macros;
#[doc(inline)]
pub use typed_html_macros::html;
pub mod dom;

View File

@ -18,6 +18,7 @@ pub use http::Uri;
pub use language_tags::LanguageTag;
pub use mime::Mime;
// FIXME these all need validating types
pub type CharacterEncoding = String;
pub type Datetime = String;
pub type FeaturePolicy = String;

View File

@ -12,7 +12,6 @@ use std::str::FromStr;
/// # Examples
///
/// ```
/// # extern crate typed_html;
/// # use std::convert::From;
/// use typed_html::types::{Class, SpacedSet};
///