diff --git a/README b/README
deleted file mode 100644
index 0f45b870..00000000
--- a/README
+++ /dev/null
@@ -1,56 +0,0 @@
-LibCSS -- a CSS parser and selection engine
-===========================================
-
-Overview
---------
-
- LibCSS is a CSS parser and selection engine. It aims to parse the forward
- compatible CSS grammar.
-
-Requirements
-------------
-
- LibCSS requires the following tools:
-
- + A C99 capable C compiler
- + GNU make or compatible
- + Pkg-config
- + Perl (for the testcases)
- + Python3 (minimum 3.6, for generated selection code)
-
- LibCSS also requires the following libraries to be installed:
-
- + LibParserUtils
- + LibWapcaplet
-
-Compilation
------------
-
- If necessary, modify the toolchain settings in the Makefile.
- Invoke make:
-
- $ make
-
-Regenerating generated selection source code
---------------------------------------------
-
- To regenerate the selection sources (computed style data accesses),
- note this requires python3:
-
- $ make select_generator
-
-Verification
-------------
-
- To verify that the parser is working, it is necessary to specify a
- different makefile target than that used for normal compilation, thus:
-
- $ make test
-
-API documentation
------------------
-
- Currently, there is none. However, the code is well commented and the
- public API may be found in the "include" directory. The testcase sources
- may also be of use in working out how to use it.
-
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..8bc11b59
--- /dev/null
+++ b/README.md
@@ -0,0 +1,56 @@
+LibCSS -- a CSS parser and selection engine
+===========================================
+
+Overview
+--------
+
+LibCSS is a CSS parser and selection engine. It aims to parse the forward
+compatible CSS grammar.
+
+Requirements
+------------
+
+LibCSS requires the following tools:
+
+* A C99 capable C compiler
+* GNU make or compatible
+* Pkg-config
+* Perl (for the testcases)
+* Python3 (minimum 3.6, for generated selection code)
+
+LibCSS also requires the following libraries to be installed:
+
+* LibParserUtils
+* LibWapcaplet
+
+Compilation
+-----------
+
+If necessary, modify the toolchain settings in the Makefile.
+Invoke make:
+
+ make
+
+Regenerating generated selection source code
+--------------------------------------------
+
+To regenerate the selection sources (computed style data accesses),
+note this requires python3:
+
+ make select_generator
+
+Verification
+------------
+
+To verify that the parser is working, it is necessary to specify a
+different makefile target than that used for normal compilation, thus:
+
+ make test
+
+API documentation
+-----------------
+
+Currently, there is none. However, the code is well commented and the
+public API may be found in the "include" directory. The testcase sources
+may also be of use in working out how to use it.
+
diff --git a/docs/API-ABI-Changes b/docs/API-ABI-Changes
deleted file mode 100644
index e567d80b..00000000
--- a/docs/API-ABI-Changes
+++ /dev/null
@@ -1,77 +0,0 @@
-LibCSS API & ABI Changes
-========================
-
- This document explains how to upgrade clients to use new versions of LibCSS.
-
-
-LibCSS 0.2.0 --> LibCSS 0.3.0
------------------------------
-
- Both the API and ABI are changed.
-
- LibCSS no longer lets clients provide a memory allocator function.
- This change affects the following functions:
-
- From include/libcss/computed.h -- css_computed_style_create()
-
- From include/libcss/select.h -- css_select_ctx_create()
-
- From include/libcss/stylesheet.h -- css_stylesheet_create()
-
-
- There are changes to selection handler callback table:
-
- node_classes
- LibCSS no longer frees the any array of classes passed to the
- node_classes callback. It does still unref the individual strings.
- This means clients need not allocate a new array each call, but can
- keep the array cached on the node.
-
- set_libcss_node_data
- New selection handler function used to store a private cache belonging
- to libcss on document element nodes. When the node is deleted or
- modified, clients should call css_libcss_node_data_handler().
-
- get_libcss_node_data
- New selection handler function used to retrieve private cache belonging
- to libcss from document element nodes.
-
-
-LibCSS 0.3.0 --> LibCSS 0.4.0
------------------------------
-
- The API is changed.
-
- Due to the change from CSS2 overflow to CSS3 overflow properties, the
- computed style access functions for overflow properties have changed.
- The overflow property is removed. Added are overflow-x and overflow-y
- properties. (The overflow shorthand property now sets overflow-x and
- overflow-y.)
-
- This change affects the following functions:
-
- Removed from include/libcss/computed.h -- css_computed_overflow()
-
- Added to include/libcss/computed.h -- css_computed_overflow_x()
-
- Added to include/libcss/computed.h -- css_computed_overflow_y()
-
-
-LibCSS 0.5.0 --> LibCSS 0.6.0
------------------------------
-
- The API is changed.
-
- The way that presentational hints are handled has changed to be more
- optimal. Instead of calling the presentational hint callback once
- per property per node to get each hint, we now call the callback once
- per node to get all the hints that apply to it.
-
- There are changes to selection handler callback table:
-
- node_presentational_hint
- Rather than asking for any hint for the given node and property,
- it now asks for an array of hints that should apply to the node.
-
- The css_hint structure has been changed to include the property which
- the hint applies to.
diff --git a/docs/API-ABI-Changes.md b/docs/API-ABI-Changes.md
new file mode 100644
index 00000000..28f04ed9
--- /dev/null
+++ b/docs/API-ABI-Changes.md
@@ -0,0 +1,77 @@
+LibCSS API & ABI Changes
+========================
+
+This document explains how to upgrade clients to use new versions of LibCSS.
+
+
+LibCSS 0.2.0 --> LibCSS 0.3.0
+-----------------------------
+
+Both the API and ABI are changed.
+
+LibCSS no longer lets clients provide a memory allocator function.
+This change affects the following functions:
+
+| Header | Function |
+| ----------------------------- | --------------------------- |
+| `include/libcss/computed.h` | css_computed_style_create() |
+| `include/libcss/select.h` | css_select_ctx_create() |
+| `include/libcss/stylesheet.h` | css_stylesheet_create() |
+
+
+There are changes to selection handler callback table:
+
+* node_classes
+ * LibCSS no longer frees the any array of classes passed to the
+ node_classes callback. It does still unref the individual strings.
+ This means clients need not allocate a new array each call, but can
+ keep the array cached on the node.
+
+* set_libcss_node_data
+ * New selection handler function used to store a private cache belonging
+ to libcss on document element nodes. When the node is deleted or
+ modified, clients should call css_libcss_node_data_handler().
+
+* get_libcss_node_data
+ * New selection handler function used to retrieve private cache belonging
+ to libcss from document element nodes.
+
+
+LibCSS 0.3.0 --> LibCSS 0.4.0
+-----------------------------
+
+The API is changed.
+
+Due to the change from CSS2 overflow to CSS3 overflow properties, the
+computed style access functions for overflow properties have changed.
+The overflow property is removed. Added are overflow-x and overflow-y
+properties. (The overflow shorthand property now sets overflow-x and
+overflow-y.)
+
+This change affects the following functions:
+
+| Change | Header | Function |
+| ------- | --------------------------- | --------------------------- |
+| Removed | `include/libcss/computed.h` | `css_computed_overflow()` |
+| Added | `include/libcss/computed.h` | `css_computed_overflow_x()` |
+| Added | `include/libcss/computed.h` | `css_computed_overflow_y()` |
+
+
+LibCSS 0.5.0 --> LibCSS 0.6.0
+-----------------------------
+
+The API is changed.
+
+The way that presentational hints are handled has changed to be more
+optimal. Instead of calling the presentational hint callback once
+per property per node to get each hint, we now call the callback once
+per node to get all the hints that apply to it.
+
+There are changes to selection handler callback table:
+
+* node_presentational_hint
+ * Rather than asking for any hint for the given node and property,
+ it now asks for an array of hints that should apply to the node.
+
+The css_hint structure has been changed to include the property which
+the hint applies to.
diff --git a/docs/API b/docs/API.md
similarity index 81%
rename from docs/API
rename to docs/API.md
index 6115b5bb..c0ef9329 100644
--- a/docs/API
+++ b/docs/API.md
@@ -22,16 +22,19 @@ Load one or more CSS files
A stylesheet is represented by the opaque type css_stylesheet. To create one,
use css_stylesheet_create(), for example:
- css_stylesheet *sheet;
- css_stylesheet_params params;
- /* Set params */
- ...
- code = css_stylesheet_create(¶ms, &sheet);
- if (code != CSS_OK)
- ...
+```c
+css_stylesheet *sheet;
+css_stylesheet_params params;
+/* Set params */
+...
+code = css_stylesheet_create(¶ms, &sheet);
+if (code != CSS_OK)
+ ...
+```
The arguments are as follows:
+```
+ css_stylesheet_params params
| + uint32_t params_version
| | Version of the params struct.
@@ -87,15 +90,18 @@ The arguments are as follows:
|
+ css_stylesheet **stylesheet
Updated with the newly created stylesheet object.
+```
Once the stylesheet has been created, CSS source data can be added to it. LibCSS
parses the data into internal structures. Only data in memory is supported; you
must handle reading from files or the network if required. Data is added using
css_stylesheet_append_data(), for example:
- code = css_stylesheet_append_data(sheet, data, length);
- if (code != CSS_OK && code != CSS_NEEDDATA)
- ...
+```c
+code = css_stylesheet_append_data(sheet, data, length);
+if (code != CSS_OK && code != CSS_NEEDDATA)
+ ...
+```
The second argument is a pointer to a buffer containing some CSS to be parsed,
with length in bytes given in the 3rd argument.
@@ -109,9 +115,11 @@ data may be expected. The two states can be treated identically.
When all the data has been supplied, css_stylesheet_data_done() completes the
processing:
- code = css_stylesheet_data_done(sheet);
- if (code != CSS_OK)
- ...
+```c
+code = css_stylesheet_data_done(sheet);
+if (code != CSS_OK)
+ ...
+```
The stylesheet is now in memory and ready for further use.
@@ -122,7 +130,7 @@ Use the Selection API to determine styles
The Selection API is currently the only way to get information about styles from
stylesheets that have been loaded. It takes a document node as input and returns
the computed style that applies to that node. For example, it can be used to
-answer the question "What style should this
element have?"
+answer the question "What style should this `` element have?"
CSS selectors can be complex and apply to certain arrangments of elements within
a document tree. Therefore LibCSS has to be able to navigate your document tree
@@ -130,7 +138,9 @@ and read attributes of it to determine if a style applies. It does this through
a series of functions that you supply. In this way LibCSS is independent of the
representation of the document. For example, with the style rule:
- table h2 { color: red; }
+```css
+table h2 { color: red; }
+```
when requesting the style for an h2 element node, LibCSS will search its
ancestors for a table element to determine if this style applies.
@@ -139,17 +149,21 @@ The first step in using the Selection API is creating a selection context. This
is a list of the stylesheets to be used. A context is created using
css_select_ctx_create():
- css_select_ctx *select_ctx;
- code = css_select_ctx_create(&select_ctx);
- if (code != CSS_OK)
- ...
+```c
+css_select_ctx *select_ctx;
+code = css_select_ctx_create(&select_ctx);
+if (code != CSS_OK)
+ ...
+```
Stylesheets are added to the context using css_select_ctx_append_sheet():
- code = css_select_ctx_append_sheet(select_ctx, sheet, CSS_ORIGIN_AUTHOR,
- CSS_MEDIA_ALL);
- if (code != CSS_OK)
- ...
+```c
+code = css_select_ctx_append_sheet(select_ctx, sheet, CSS_ORIGIN_AUTHOR,
+ CSS_MEDIA_ALL);
+if (code != CSS_OK)
+ ...
+```
When adding a stylesheet, the origin and media can be specified. These are used
in the computation of styles as defined in the CSS specification.
@@ -158,21 +172,26 @@ Alternatively stylesheets may be added using css_select_ctx_insert_sheet().
After the context has been prepared, an empty computed style is created:
- css_computed_style *style;
- code = css_computed_style_create(&style);
- if (code != CSS_OK)
- ...
+```c
+css_computed_style *style;
+code = css_computed_style_create(&style);
+if (code != CSS_OK)
+ ...
+```
The style is then determined for a document node using css_select_style():
- code = css_select_style(select_ctx, element_node, 0,
- CSS_MEDIA_SCREEN, NULL, style,
- &select_handler, 0);
- if (code != CSS_OK)
- ...
+```c
+code = css_select_style(select_ctx, element_node, 0,
+ CSS_MEDIA_SCREEN, NULL, style,
+ &select_handler, 0);
+if (code != CSS_OK)
+ ...
+```
The arguments are as follows:
+```
+ css_select_ctx *ctx
| The selection context, as described above.
|
@@ -201,31 +220,34 @@ The arguments are as follows:
+ css_computed_style **result
Updated to the computed styles for the node. Array indexed by
css_pseudo_element.
+```
The types of the handler functions that need to be supplied and the definition
of css_select_handler are given in libcss/select.h. The functions all have the
following in common:
- * the first argument is the private data pointer that was the last argument to
- css_select_style()
+* the first argument is the private data pointer that was the last argument to
+ css_select_style()
- * the second argument is the document node that is being queried is some way
+* the second argument is the document node that is being queried is some way
- * the last one or two arguments are pointers that must be updated with the
+* the last one or two arguments are pointers that must be updated with the
required information
- * the return value is a css_error and should be CSS_OK if everything worked and
- an error code otherwise
+* the return value is a css_error and should be CSS_OK if everything worked and
+ an error code otherwise
For example, the node_name function, which determines the element name of a
node, could be this:
- css_error node_name(void *pw, void *n, lwc_string **name)
- {
- my_document_node *node = n;
- *name = lwc_string_ref(node->name);
- return CSS_OK;
- }
+```c
+css_error node_name(void *pw, void *n, lwc_string **name)
+{
+ my_document_node *node = n;
+ *name = lwc_string_ref(node->name);
+ return CSS_OK;
+}
+```
where my_document_node is your document tree node type (e.g. a struct of some
sort).
@@ -244,9 +266,11 @@ work to read the properties correctly.
For example, the css_computed_color() accessor retrieves the color property:
- uint8_t color_type;
- css_color color_shade;
- color_type = css_computed_color(style, &color_shade);
+```c
+uint8_t color_type;
+css_color color_shade;
+color_type = css_computed_color(style, &color_shade);
+```
In this case color_type can be CSS_COLOR_INHERIT or CSS_COLOR_COLOR. In the
latter case, color_shade contains the actual color in RRGGBBAA format. Together
diff --git a/docs/Bytecode b/docs/Bytecode.md
similarity index 98%
rename from docs/Bytecode
rename to docs/Bytecode.md
index 272fd07b..699b4e8e 100644
--- a/docs/Bytecode
+++ b/docs/Bytecode.md
@@ -4,6 +4,7 @@ CSS style declaration bytecode
Format
------
+```
[]
is 32 bits wide:
@@ -20,6 +21,7 @@ The 8 bits of flag data are defined as follows:
011 => revert
100 => unset
bit 0 : value is important
+```
The 14 bits of value are opcode-specific.
@@ -35,9 +37,10 @@ assigned to the fractional part.
Strings are stored as a 32bit index into a table of interned string pointers.
The table is found in the stylesheet object.
-CSS dimensions are stored as two 32bit values: .
+CSS dimensions are stored as two 32bit values: ``.
Length is a 32bit numeric value (as described above) and unit is as follows:
+```
bit 8 set => length unit
bits 9-31: MBZ
bits 0-7 :
@@ -94,6 +97,7 @@ Length is a 32bit numeric value (as described above) and unit is as follows:
00000000 => dpi
00000001 => dpcm
00000010 => dppx
+```
CSS colours are stored as one 32bit value. See "Colour" for their format.
@@ -106,33 +110,38 @@ component parts, and then creating bytecode for these.
For example, "background: red none no-repeat scroll left top !important;" would
be decomposed to:
- background-color: red !important;
- background-image: none !important;
- background-repeat: no-repeat !important;
- background-attachment: scroll !important;
- background-position: left top !important;
+```css
+background-color: red !important;
+background-image: none !important;
+background-repeat: no-repeat !important;
+background-attachment: scroll !important;
+background-position: left top !important;
+```
and bytecode generated for each of these properties.
The full list of CSS 2.1 shorthand properties is:
- background
- border-color
- border-style
- border-{top,right,bottom,left}
- border-width
- border
- cue
- font
- list-style
- margin
- outline
- padding
- pause
+```
+background
+border-color
+border-style
+border-{top,right,bottom,left}
+border-width
+border
+cue
+font
+list-style
+margin
+outline
+padding
+pause
+```
Opcodes
-------
+```
00 - azimuth
(14bits) :
bits 8-13: MBZ
@@ -1402,3 +1411,4 @@ Opcodes
bits 0-6: MBZ
7e-3ff - Reserved for future expansion.
+```
diff --git a/docs/Colour b/docs/Colour
deleted file mode 100644
index b3e78503..00000000
--- a/docs/Colour
+++ /dev/null
@@ -1,10 +0,0 @@
-The exported representation of colours is an unsigned 32bit value in host order
-
-The value is divided into four 8bit channels. These are:
-
-Bits Name Desciption
-0-7 Blue The blue intensity of the colour 0 is off 0xff is fully on
-8-15 Green The green intensity of the colour 0 is off 0xff is fully on
-16-23 Red The red intensity of the colour 0 is off 0xff is fully on
-24-31 Alpha The Alpha component represents the opacity of the colour 0 is fully transparent and 0xff is opaque
-
diff --git a/docs/Colour.md b/docs/Colour.md
new file mode 100644
index 00000000..baa98702
--- /dev/null
+++ b/docs/Colour.md
@@ -0,0 +1,10 @@
+The exported representation of colours is an unsigned 32bit value in host order
+
+The value is divided into four 8bit channels. These are:
+
+| Bits | Name | Desciption |
+| ------- | ----- | ---------- |
+| ` 0- 7` | Blue | The blue intensity of the colour `0` is off `0xff` is fully on |
+| ` 8-15` | Green | The green intensity of the colour `0` is off `0xff` is fully on |
+| `16-23` | Red | The red intensity of the colour `0` is off `0xff` is fully on |
+| `24-31` | Alpha | The Alpha component represents the opacity of the colour `0` is fully transparent and `0xff` is opaque |
diff --git a/docs/Grammar b/docs/Grammar
deleted file mode 100644
index c3d24b41..00000000
--- a/docs/Grammar
+++ /dev/null
@@ -1,210 +0,0 @@
-Expanded grammar rules
-======================
-
-This file provides a fully-expanded version of (a slightly modified)
-forward-compatible CSS grammar. See CSS3 Syntax $4.3.2 for the compact version.
-
-start -> ws stylesheet EOF
-
-stylesheet -> CDO ws stylesheet
-stylesheet -> CDC ws stylesheet
-stylesheet -> statement stylesheet
-stylesheet ->
-
-statement -> ruleset
-statement -> at-rule
-
-ruleset -> selector '{' ws ruleset-end
-ruleset -> '{' ws ruleset-end
-
-ruleset-end -> declaration decl-list '}' ws
-ruleset-end -> decl-list '}' ws
-
-at-rule -> ATKEYWORD ws any0 at-rule-end
-
-at-rule-end -> block
-at-rule-end -> ';' ws
-
-block -> '{' ws block-content '}' ws
-
-block-content -> any block-content
-block-content -> block block-content
-block-content -> ATKEYWORD ws block-content
-block-content -> ';' ws block-content
-block-content ->
-
-selector -> any1
-
-declaration -> property ':' ws value1
-
-decl-list -> ';' ws decl-list-end
-decl-list ->
-
-decl-list-end -> declaration decl-list
-decl-list-end -> decl-list
-
-property -> IDENT ws
-
-value0 -> value value0
-value0 ->
-
-value1 -> value value0
-
-value -> any
-value -> block
-value -> ATKEYWORD ws
-
-any0 -> any any0
-any0 ->
-
-any1 -> any any0
-
-any -> IDENT ws
-any -> NUMBER ws
-any -> PERCENTAGE ws
-any -> DIMENSION ws
-any -> STRING ws
-any -> CHAR ws
-any -> URI ws
-any -> HASH ws
-any -> UNICODE-RANGE ws
-any -> INCLUDES ws
-any -> DASHMATCH ws
-any -> PREFIXMATCH ws
-any -> SUFFIXMATCH ws
-any -> SUBSTRINGMATCH ws
-any -> FUNCTION ws any0 ')' ws
-any -> '(' ws any0 ')' ws
-any -> '[' ws any0 ']' ws
-
-ws -> S ws
-ws ->
-
-Differences from the specification
-----------------------------------
-
-1) The start non-terminal has been introduced. It eats any leading whitespace
- and handles EOF.
-2) The "stylesheet -> S stylesheet" production has been removed.
-3) The "stylesheet -> CDO stylesheet" production has been changed to
- "stylesheet -> CDO ws stylesheet".
-4) The "stylesheet -> CDC stylesheet" production has been changed to
- "stylesheet -> CDC ws stylesheet".
-
-Essentially, the above changes remove the expectation of leading whitespace
-from the stylesheet non-terminal. This is handled by either the start
-non-terminal, or by the changes made to the production rules for the stylesheet
-non-terminal. Note that the "stylesheet -> statement stylesheet" production
-does not require modification as the statement production rule already consumes
-any whitespace following the statement.
-
-If '{', '}', '[', ']', '(', ')', and ';' are omitted from any, then the above
-grammar is LL(1).
-
-Nullable productions
---------------------
-
-stylesheet, block-content, decl-list, decl-list-end, value0, any0, ws
-
-FIRST sets
-----------
-
-start CDO, CDC, S, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF
-stylesheet CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD
-statement IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
-ruleset IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{'
-ruleset-end IDENT, ';'
-at-rule ATKEYWORD
-at-rule-end '{', ';'
-block '{'
-block-content IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD, ';'
-selector IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '['
-declaration IDENT
-decl-list ';', '}'
-decl-list-end IDENT, ';', '}'
-property IDENT
-value0 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
-value1 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
-value IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
-any0 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '['
-any1 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '['
-any IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '['
-ws S
-
-FOLLOW sets
------------
-
-start
-stylesheet EOF
-statement CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF
-ruleset CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF
-ruleset-end CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF
-at-rule CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF
-at-rule-end CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF
-block CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF, ';', '}'
-block-content '}'
-selector '{'
-declaration ';', '}'
-decl-list '}'
-decl-list-end '}'
-property ':'
-value0 ';', '}'
-value1 ';', '}'
-value IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD, ';', '}'
-any0 '{', ';', ')', ']'
-any1 '{'
-any IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
- UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
- SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ';', ATKEYWORD, '}'
-ws CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
- CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
- PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
- '[', '{', ATKEYWORD, EOF, ';', '}', ':'
-
-
diff --git a/docs/Grammar.md b/docs/Grammar.md
new file mode 100644
index 00000000..75051336
--- /dev/null
+++ b/docs/Grammar.md
@@ -0,0 +1,214 @@
+Expanded grammar rules
+======================
+
+This file provides a fully-expanded version of (a slightly modified)
+forward-compatible CSS grammar. See CSS3 Syntax $4.3.2 for the compact version.
+
+```
+start -> ws stylesheet EOF
+
+stylesheet -> CDO ws stylesheet
+stylesheet -> CDC ws stylesheet
+stylesheet -> statement stylesheet
+stylesheet ->
+
+statement -> ruleset
+statement -> at-rule
+
+ruleset -> selector '{' ws ruleset-end
+ruleset -> '{' ws ruleset-end
+
+ruleset-end -> declaration decl-list '}' ws
+ruleset-end -> decl-list '}' ws
+
+at-rule -> ATKEYWORD ws any0 at-rule-end
+
+at-rule-end -> block
+at-rule-end -> ';' ws
+
+block -> '{' ws block-content '}' ws
+
+block-content -> any block-content
+block-content -> block block-content
+block-content -> ATKEYWORD ws block-content
+block-content -> ';' ws block-content
+block-content ->
+
+selector -> any1
+
+declaration -> property ':' ws value1
+
+decl-list -> ';' ws decl-list-end
+decl-list ->
+
+decl-list-end -> declaration decl-list
+decl-list-end -> decl-list
+
+property -> IDENT ws
+
+value0 -> value value0
+value0 ->
+
+value1 -> value value0
+
+value -> any
+value -> block
+value -> ATKEYWORD ws
+
+any0 -> any any0
+any0 ->
+
+any1 -> any any0
+
+any -> IDENT ws
+any -> NUMBER ws
+any -> PERCENTAGE ws
+any -> DIMENSION ws
+any -> STRING ws
+any -> CHAR ws
+any -> URI ws
+any -> HASH ws
+any -> UNICODE-RANGE ws
+any -> INCLUDES ws
+any -> DASHMATCH ws
+any -> PREFIXMATCH ws
+any -> SUFFIXMATCH ws
+any -> SUBSTRINGMATCH ws
+any -> FUNCTION ws any0 ')' ws
+any -> '(' ws any0 ')' ws
+any -> '[' ws any0 ']' ws
+
+ws -> S ws
+ws ->
+```
+
+Differences from the specification
+----------------------------------
+
+1) The start non-terminal has been introduced. It eats any leading whitespace
+ and handles EOF.
+2) The "stylesheet -> S stylesheet" production has been removed.
+3) The "stylesheet -> CDO stylesheet" production has been changed to
+ "stylesheet -> CDO ws stylesheet".
+4) The "stylesheet -> CDC stylesheet" production has been changed to
+ "stylesheet -> CDC ws stylesheet".
+
+Essentially, the above changes remove the expectation of leading whitespace
+from the stylesheet non-terminal. This is handled by either the start
+non-terminal, or by the changes made to the production rules for the stylesheet
+non-terminal. Note that the "stylesheet -> statement stylesheet" production
+does not require modification as the statement production rule already consumes
+any whitespace following the statement.
+
+If '{', '}', '[', ']', '(', ')', and ';' are omitted from any, then the above
+grammar is LL(1).
+
+Nullable productions
+--------------------
+
+stylesheet, block-content, decl-list, decl-list-end, value0, any0, ws
+
+FIRST sets
+----------
+
+```
+start CDO, CDC, S, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF
+stylesheet CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD
+statement IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
+ruleset IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{'
+ruleset-end IDENT, ';'
+at-rule ATKEYWORD
+at-rule-end '{', ';'
+block '{'
+block-content IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD, ';'
+selector IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '['
+declaration IDENT
+decl-list ';', '}'
+decl-list-end IDENT, ';', '}'
+property IDENT
+value0 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
+value1 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
+value IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD
+any0 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '['
+any1 IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '['
+any IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '['
+ws S
+```
+
+FOLLOW sets
+-----------
+
+```
+start
+stylesheet EOF
+statement CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF
+ruleset CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF
+ruleset-end CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF
+at-rule CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF
+at-rule-end CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF
+block CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF, ';', '}'
+block-content '}'
+selector '{'
+declaration ';', '}'
+decl-list '}'
+decl-list-end '}'
+property ':'
+value0 ';', '}'
+value1 ';', '}'
+value IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ATKEYWORD, ';', '}'
+any0 '{', ';', ')', ']'
+any1 '{'
+any IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING, CHAR, URI, HASH,
+ UNICODE-RANGE, INCLUDES, DASHMATCH, PREFIXMATCH, SUFFIXMATCH,
+ SUBSTRINGMATCH, FUNCTION, '(', '[', '{', ';', ATKEYWORD, '}'
+ws CDO, CDC, IDENT, NUMBER, PERCENTAGE, DIMENSION, STRING,
+ CHAR, URI, HASH, UNICODE-RANGE, INCLUDES, DASHMATCH,
+ PREFIXMATCH, SUFFIXMATCH, SUBSTRINGMATCH, FUNCTION, '(',
+ '[', '{', ATKEYWORD, EOF, ';', '}', ':'
+```
diff --git a/docs/Lexer b/docs/Lexer
deleted file mode 100644
index 23626d13..00000000
--- a/docs/Lexer
+++ /dev/null
@@ -1,31 +0,0 @@
-Lexical analyser
-================
-
-This document contains various snippets of information about the lexer
-implementation.
-
-First sets
-----------
-
-IDENT [a-zA-Z] | '-' | '_' | [^#x0-#x7F] | '\'
-ATKEYWORD '@'
-STRING '"' | "'"
-INVALID_STRING '"' | "'"
-HASH '#'
-NUMBER [0-9] | '.' | '-' | '+'
-PERCENTAGE [0-9] | '.' | '-' | '+'
-DIMENSION [0-9] | '.'
-URI [Uu]
-UNICODE-RANGE [Uu]
-CDO '<'
-CDC '-'
-S #x9 | #xA | #xC | #xD | #x20
-COMMENT '/'
-FUNCTION [a-zA-Z] | '-' | '_' | [^#x0-#x7F] | '\'
-INCLUDES '~'
-DASHMATCH '|'
-PREFIXMATCH '^'
-SUFFIXMATCH '$'
-SUBSTRINGMATCH '*'
-CHAR anything except " or '
-
diff --git a/docs/Lexer.md b/docs/Lexer.md
new file mode 100644
index 00000000..064d1ee7
--- /dev/null
+++ b/docs/Lexer.md
@@ -0,0 +1,32 @@
+Lexical analyser
+================
+
+This document contains various snippets of information about the lexer
+implementation.
+
+First sets
+----------
+
+```
+IDENT [a-zA-Z] | '-' | '_' | [^#x0-#x7F] | '\'
+ATKEYWORD '@'
+STRING '"' | "'"
+INVALID_STRING '"' | "'"
+HASH '#'
+NUMBER [0-9] | '.' | '-' | '+'
+PERCENTAGE [0-9] | '.' | '-' | '+'
+DIMENSION [0-9] | '.'
+URI [Uu]
+UNICODE-RANGE [Uu]
+CDO '<'
+CDC '-'
+S #x9 | #xA | #xC | #xD | #x20
+COMMENT '/'
+FUNCTION [a-zA-Z] | '-' | '_' | [^#x0-#x7F] | '\'
+INCLUDES '~'
+DASHMATCH '|'
+PREFIXMATCH '^'
+SUFFIXMATCH '$'
+SUBSTRINGMATCH '*'
+CHAR anything except " or '
+```
diff --git a/docs/Representation b/docs/Representation.md
similarity index 98%
rename from docs/Representation
rename to docs/Representation.md
index b91419f8..ffebf2c2 100644
--- a/docs/Representation
+++ b/docs/Representation.md
@@ -3,6 +3,7 @@ LibCSS internal stylesheet representation
Selector:
+```c
struct selector {
selector_type type; /**< Type of selector */
@@ -26,9 +27,11 @@ struct selector {
struct selector *next; /**< Next selector in list */
struct selector *prev; /**< Previous selector */
};
+```
Rule:
+```c
struct rule {
rule_type type; /**< Type of rule */
@@ -68,9 +71,11 @@ struct rule {
struct rule *next; /**< Next rule */
struct rule *prev; /**< Previous rule */
};
+```
Stylesheet:
+```c
struct stylesheet {
#define HASH_SIZE (37)
struct selector *selectors[HASH_SIZE]; /**< Hashtable of selectors */
@@ -95,4 +100,4 @@ struct stylesheet {
struct stylesheet *next; /**< Next in sibling list */
struct stylesheet *prev; /**< Previous in sibling list */
};
-
+```
diff --git a/docs/Tokens b/docs/Tokens.md
similarity index 99%
rename from docs/Tokens
rename to docs/Tokens.md
index 9535e813..a6d89eb6 100644
--- a/docs/Tokens
+++ b/docs/Tokens.md
@@ -7,6 +7,7 @@ by the lexer. In case of ambiguity, the longest match wins.
Components
----------
+```
ident ::= '-'? nmstart nmchar*
name ::= nmchar+
nmstart ::= [a-zA-Z] | '_' | nonascii | escape
@@ -21,10 +22,12 @@ urlchar ::= [#x9#x21#x23-#x26#x28#x2A-#x7E] | nonascii | escape
nl ::= #xA | #xD #xA | #xD | #xC
w ::= wc*
wc ::= #x9 | #xA | #xC | #xD | #x20
+```
Tokens
------
+```
IDENT ::= ident
ATKEYWORD ::= '@' ident
STRING ::= string
@@ -46,6 +49,7 @@ PREFIXMATCH ::= "^="
SUFFIXMATCH ::= "$="
SUBSTRINGMATCH ::= "*="
CHAR ::= any other character, except " or '
+```
Differences from the CSS3 Syntax module specification
-----------------------------------------------------
diff --git a/test/README b/test/README.md
similarity index 69%
rename from test/README
rename to test/README.md
index 557adf9c..ed1320d3 100644
--- a/test/README
+++ b/test/README.md
@@ -10,7 +10,7 @@ Testcase command lines
Testcase command lines are in a unified format, thus:
- [ ]
+ [ ]
The aliases file parameter will always be specified (as it is required for
the library to work at all).
@@ -34,20 +34,22 @@ added to this index as they are created.
The test index file format is as follows:
- file = *line
+```
+file = *line
- line = ( entry / comment / blank ) LF
+line = ( entry / comment / blank ) LF
- entry = testname 1*HTAB description [ 1*HTAB datadir ]
- comment = "#" *non-newline
- blank = 0
+entry = testname 1*HTAB description [ 1*HTAB datadir ]
+comment = "#" *non-newline
+blank = 0
- testname = 1*non-reserved
- description = 1*non-reserved
- datadir = 1*non-reserved
+testname = 1*non-reserved
+description = 1*non-reserved
+datadir = 1*non-reserved
- non-newline = VCHAR / WSP
- non-reserved = VCHAR / SP
+non-newline = VCHAR / WSP
+non-reserved = VCHAR / SP
+```
Each entry contains a mandatory binary name and description followed by
an optional data directory specifier. The data directory specifier is
@@ -57,7 +59,7 @@ directory in the source tree.
If a data directory is specified, the test binary will be invoked for
each data file listed within the data directory INDEX, passing the
-filename as the second parameter (, above).
+filename as the second parameter (``, above).
Data Index
----------
@@ -67,18 +69,20 @@ index of all available test data files.
The data index file format is as follows:
- file = *line
+```
+file = *line
- line = ( entry / comment / blank ) LF
+line = ( entry / comment / blank ) LF
- entry = dataname 1*HTAB description
- comment = "#" *non-newline
- blank = 0
+entry = dataname 1*HTAB description
+comment = "#" *non-newline
+blank = 0
- dataname = 1*non-reserved
- description = 1*non-reserved
+dataname = 1*non-reserved
+description = 1*non-reserved
- non-newline = VCHAR / WSP
- non-reserved = VCHAR / SP
+non-newline = VCHAR / WSP
+non-reserved = VCHAR / SP
+```
Each entry contains a mandatory data file name and description.
diff --git a/test/data/parse/README b/test/data/parse/README.md
similarity index 69%
rename from test/data/parse/README
rename to test/data/parse/README.md
index 135dd3be..a9844f6a 100644
--- a/test/data/parse/README
+++ b/test/data/parse/README.md
@@ -4,6 +4,7 @@ Parser testcases
Format
------
+```
#data
#errors
@@ -11,17 +12,18 @@ Format
#expected
#reset
+```
Format of rule list
-------------------
- line ::= rule | bytecode
- rule ::= '| ' type ' '+ name
- name ::= .+
- type ::= [0-9]+
- bytecode ::= '| ' ' '* hexnum (' '+ (hexnum | ptr))*
- hexnum ::= '0x' [0-9a-fA-F]+
- ptr ::= 'PTR(' .* ')'
+ line ::= rule | bytecode
+ rule ::= '| ' type ' '+ name
+ name ::= .+
+ type ::= [0-9]+
+ bytecode ::= '| ' ' '* hexnum (' '+ (hexnum | ptr))*
+ hexnum ::= '0x' [0-9a-fA-F]+
+ ptr ::= 'PTR(' .* ')'
Type corresponds to css_rule_type. Consult the library sources for the values.
@@ -32,6 +34,7 @@ documentation for what the hexnums should be representing.
Example
-------
+```
#data
* { color: #ff0000; background-image: url("foo.png"); }
#errors
@@ -40,9 +43,10 @@ Example
| 0x0200000f 0xff000000
| 0x02000003 PTR(foo.png)
#reset
+```
TODO
----
- + Permit nesting of rules (for nested block support)
+* Permit nesting of rules (for nested block support)
diff --git a/test/data/parse2/README b/test/data/parse2/README.md
similarity index 65%
rename from test/data/parse2/README
rename to test/data/parse2/README.md
index dec15f4a..862aa127 100644
--- a/test/data/parse2/README
+++ b/test/data/parse2/README.md
@@ -4,6 +4,7 @@ Parser testcases
Format
------
+```
#data
#errors
@@ -11,18 +12,20 @@ Format
#expected
#reset
+```
Format of cssom tree
--------------------
- line ::= rule | declaration
- rule ::= '| ' name
- name ::= .+
- declaration ::= '| ' property-name ': ' property-value
+ line ::= rule | declaration
+ rule ::= '| ' name
+ name ::= .+
+ declaration ::= '| ' property-name ': ' property-value
Example
-------
+```
#data
* { color: #ff0000; background-image: url("foo.png"); }
#errors
@@ -31,9 +34,10 @@ Example
| color: #ff000000
| background-image: url("foo.png")
#reset
+```
TODO
----
- + Permit nesting of rules (for nested block support)
+* Permit nesting of rules (for nested block support)