1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/** -*-C-*-ish
HTMLnesting.k Copyright (C) 2005 Chris Morris
This file is distributed under the terms of the GNU Lesser General
Public Licence. See COPYING for licence.
*/
"<summary>HTML element nesting</summary>
<prose>This module defines allowed HTML nesting of elements for use by <moduleref>HTMLDocument</moduleref>. It is unlikely to be especially useful except for its use in that module.</prose>"
module HTMLnesting;
import Builtins;
import Tuples;
import Set;
// this module just defines some constants
globals {
HashSet<String> isab = makeIsab;
HashSet<String> cb = makeCb;
HashSet<String> cd = makeCd;
HashSet<String> cdo = makeCdo;
HashSet<String> ae = makeAe;
HashSet<String> pe = makePe;
HashSet<Tuples::Pair<String,String> > ne = makeNe;
}
HashSet<String> makeIsab() {
nestingdef = newHashSet(29,strHash);
for i in ["address","blockquote","div","h1","h2","h3","h4","h5","h6","hr","p","pre","ul","ol","dl","table","form","fieldset"] {
add(nestingdef,i);
}
return nestingdef;
}
HashSet<String> makeCb() {
nestingdef = newHashSet(29,strHash);
for i in ["address","blockquote","body","del","div","ins","li","td","th","fieldset","form"] {
add(nestingdef,i);
}
return nestingdef;
}
HashSet<String> makeCd() {
nestingdef = newHashSet(31,strHash);
for i in ["address","del","div","h1","h2","h3","h4","h5","h6","ins","pre","li","td","th","map","p","dt","dd","fieldset","label"] {
add(nestingdef,i);
}
return nestingdef;
}
HashSet<String> makeCdo() {
nestingdef = newHashSet(7,strHash);
for i in ["caption","legend","option","textarea"] {
add(nestingdef,i);
}
return nestingdef;
}
HashSet<String> makeAe() {
nestingdef = newHashSet(11,strHash);
for i in ["br","hr","img","input","col","area"] {
add(nestingdef,i);
}
return nestingdef;
}
HashSet<String> makePe() {
nestingdef = newHashSet(23,strHash);
for i in ["select","ul","ol","table","thead","tbody","tfoot","tr","dl","colgroup","optgroup","textarea","map"] {
add(nestingdef,i);
}
return nestingdef;
}
HashSet<(String,String)> makeNe() {
nestingdef = newHashSet(11);
for j in [("ul","li"),
("ol","li"),
("dl","dt"),
("dl","dd"),
("select","option"),
("select","optgroup"),
("optgroup","option")] {
add(nestingdef,j);
}
return nestingdef;
}
"<argument name='el'>The name of the element</argument>
<summary>Must the element be block-level?</summary>
<prose>Returns true if the element must be block-level, false otherwise.</prose>"
public Bool isAlwaysBlock(String el) = elem(el,isab);
"<argument name='el'>The name of the element</argument>
<summary>Might the element be block-level?</summary>
<prose>Returns true if the element might be block-level (i.e. the elements that must be block-level, plus <code>del</code> and <code>ins</code>), false otherwise.</prose>"
public Bool isBlock(String el) = (elem(el,isab) || el == "del" || el == "ins");
"<argument name='el'>The name of the element</argument>
<summary>Can the element contain block-level elements?</summary>
<prose>Returns true if the element may contain other block-level elements, false otherwise.</prose>"
public Bool containsBlock(String el) = elem(el,cb);
// of course, all non-empty inline elements can too.
"<argument name='el'>The name of the element</argument>
<summary>Can the block-level element contain text?</summary>
<prose>Returns true if the block-level element may contain text, false otherwise (or if the element is inline).</prose>"
public Bool containsCData(String el) = elem(el,cd);
"<argument name='el'>The name of the element</argument>
<summary>Can the element only contain text?</summary>
<prose>Returns true if the element may not contain any other elements (for example <code>textarea</code>), false otherwise.</prose>"
public Bool containsCDataOnly(String el) = elem(el,cdo);
"<argument name='el'>The name of the element</argument>
<summary>Is the element an empty element?</summary>
<prose>Returns true if the element is an empty element, false otherwise.</prose>"
public Bool alwaysEmpty(String el) = elem(el,ae);
"<argument name='el'>The name of the element</argument>
<summary>Do special nesting rules apply?</summary>
<prose>Returns true if children of this element have special rules, false otherwise. This is used for elements like <code>ul</code> which are not empty but may only have a very small set of elements added to them, for which special functions exist to do so.</prose>"
public Bool pretendEmpty(String el) = elem(el,pe);
"<argument name='ex'>A pair of element names in \"parent, child\" order</argument>
<summary>Is an exception to the general nesting rules allowed?</summary>
<prose>Returns true if the nesting exception in the pair is allowed. This is used to add exceptions to the elements where <functionref>pretendEmpty</functionref> is true (for example, <input>(\"ul\",\"li\")</input> returns true). Nesting exceptions are not made for the table elements, as editing these via addition of elements would be very error-prone - the specialised table editing functions in <moduleref>HTMLDocument</moduleref> should be used instead.</prose>"
public Bool nestingExceptions((String,String) ex) = elem(ex,ne);
// table elements not listed because editing tables that way could get messy.
"<summary>List all empty elements</summary>
<prose>Return a list of the names of all empty elements. This is used by <functionref>HTMLDocument::readFromString</functionref>.</prose>"
public [String] isAlwaysEmpty = array(ae);
"<summary>Retrieve dictionary of all empty elements</summary>
<prose>Return a HashSet of the names of all empty elements. This is used by <functionref>ElementTree::string</functionref> and <functionref>ElementTree::lazyPrint</functionref></prose>"
public HashSet<String> getAlwaysEmpty = ae;
|