hexp 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/SPEC.md DELETED
@@ -1,53 +0,0 @@
1
- # HTML Expressions (hexp) Specification
2
-
3
- HTML Expressions, hexps for short, are a subset of s-expressions. They provide a convention for working with HTML data in applications in a structured fashion.
4
-
5
- Most languages contain a DOM implementation to work with HTML/XML documents, fragments and nodes. However, generating HTML through the DOM API is verbose and tedious. A hexp implementation SHOULD implement conversions from and to DOM documents. A hexp implementation SHOULD NOT convert directly from or to HTML.
6
-
7
- A hexp implementation MUST implement hexp normalization. Several shorthands are provided for the convenience of the programmer when entering literal hexps. These non-strict hexps should be normalized to strict hexps before further manipulation.
8
-
9
- ## Strict hexps
10
-
11
- A strict hexp is a triplet, it represents a single HTML node. The first element is the tag name, the second a dictionary of attributes, the third is a list of child nodes.
12
-
13
- If the language implements the concept of a symbol (interned string), the tag name MUST BE a symbol. Otherwise it will be represented as a regular string.
14
-
15
- The attributes are represented in a dictionary (hash), with both keys and values being strings.
16
-
17
- The list of child nodes is a list (array) of other hexps or strings, the latter representing text nodes in the corresponding DOM.
18
-
19
- An example in Ruby of a strict hexp :
20
-
21
- ````ruby
22
- [:div, {'class': 'hexp-example'}, [
23
- [:p, {}, "Hello, world"]
24
- ]
25
- ]
26
- ````
27
-
28
- A normalized hexp MUST be made immutable (frozen, persistent) if the runtime supports it. Operations that alter a hexp MUST return a new hexp values, rather than changing the hexp value in-place.
29
-
30
- ## Non-strict hexps
31
-
32
- Following simplifications are allowed for entering literal hexps, the implementation MUST provide a mechanism for converting these to strict hexps.
33
-
34
- ````ruby
35
- # non-strict -> strict
36
- [:p] -> [:p, {}, []]
37
- [:p, {'class' => 'foo'}] -> [:p, {'class' => 'foo'}, []]
38
- [:p, ['hello,', [:br], 'world'] -> [:p, {}, ['hello,', [:br, {}, []], 'world']
39
- ````
40
-
41
- ### Omitting attributes or children
42
-
43
- If the dictionary of attributes is empty, it may be omitted.
44
-
45
- If the list of children is empty, it may be omitted.
46
-
47
- ### A single text node as child
48
-
49
- If the represented node its only child is a text node, a single string may be given rather than a list of children. An example would be `<p>Hello, world</p>`, this can be represented as `[:p, "Hello, world"]`, which would be normalized to `[:p, {}, ["Hello, world"]]`.
50
-
51
- ### Standard coercion protocol
52
-
53
- In a dynamically typed object-oriented language, a convention may be set for a protocol that objects can implement to return a strict hexp representation of themselves. For Ruby this will be the `to_hexp` method. In the list of children, objects can be added that implement `to_hexp`. The normalization procedure must detect that the object implements this method, and add the resulting hexps to the list of children.
data/notes DELETED
@@ -1,34 +0,0 @@
1
- http://begriffs.github.io/showpiece/
2
-
3
- TODO
4
- ====
5
- * Rename Hexp::Node to Hexp::Element
6
- * Rename Selector to Selection
7
-
8
- Issues
9
- ======
10
-
11
- Root elements should not be treated separately
12
-
13
- A `rewrite` operation currently yields all nodes except the root node. Rewrite allows you to replace a node with zero, one or more nodes. My thinking at the time was that I wanted to make sure a single Hexp was returned, so if one could rewrite the root node that would be problematic.
14
-
15
- This however makes for a special case that is not very intuitive. When implementing `Hexp::Node::Selector` I came across this again. One can use a Selector strictly as an Enumerable
16
-
17
- ```ruby
18
- # Find the first child element of all elements with class="strong"
19
- hexp.select {|el| el.class? 'strong' }.map {|el| el.children.first }
20
- ```
21
-
22
- In this case there is no reason why that shouldn't iterate the whole tree, including the node. Other operations on `Selector` however do a Rewrite of the selected elements, and in this case the "all-except-the-root-node" limitation applies.
23
-
24
- ``` ruby
25
- # Add class="strong" to all divs
26
- H[:div, [
27
- [:div, 'one'],
28
- [:div, 'two']
29
- ]
30
- ].select{|node| node.tag==:div}.attr('class', 'strong').to_hexp
31
- #=> H[:div, [H[:div, {"class"=>"strong"}, ["one"]], H[:div, {"class"=>"strong"}, ["two"]]]]
32
- ```
33
-
34
- The top-level node is unaffected. To remove this limitation `Rewriter` will have to return a `Hexp::List` when zero or multiple elements are returned. Hexp::Node and Hexp::List will also have to implement as much as possible the same interface, so they can be largely used intechangably. This should especially be possible for all select/rewrite operations.