Minify tag whitespace

This commit is contained in:
Wilson Lin 2018-08-08 14:31:28 +12:00
parent 652cc31a0a
commit 17896a20c4
5 changed files with 53 additions and 12 deletions

View File

@ -112,6 +112,18 @@ This includes tags that close automatically because of siblings (e.g. `<li><li>`
It's an error if a tag is self-closed. Valid in XML, not in HTML.
#### `HBE_PARSE_NO_SPACE_BEFORE_ATTR`
It's an error if there is no whitespace before an attribute.
Most likely, the cause of this error is either invalid syntax or something like:
```html
<div class="a"name="1"></div>
```
(Note the lack of space between the end of the `class` attribute and the beginning of the `name` attribute.)
#### `HBE_PARSE_UNEXPECTED_END` and `HBE_PARSE_EXPECTED_NOT_FOUND`
General syntax errors.

View File

@ -45,6 +45,7 @@ typedef enum hbe_errcode {
HBE_PARSE_ILLEGAL_CHILD,
HBE_PARSE_UNCLOSED_TAG,
HBE_PARSE_SELF_CLOSING_TAG,
HBE_PARSE_NO_SPACE_BEFORE_ATTR,
HBE_PARSE_UNEXPECTED_END,
HBE_PARSE_EXPECTED_NOT_FOUND,

View File

@ -11,7 +11,11 @@
#include "../streamoptions.c"
void hbsh_attr(hbs_options_t so, hbu_pipe_t pipe) {
#define HBSH_ATTR_QUOTED 1
#define HBSH_ATTR_UNQUOTED 2
#define HBSH_ATTR_NOVAL 3
int hbsh_attr(hbs_options_t so, hbu_pipe_t pipe) {
hbu_buffer_t name = hbu_buffer_create();
while (1) {
@ -46,14 +50,18 @@ void hbsh_attr(hbs_options_t so, hbu_pipe_t pipe) {
if (hbr_attrvalquote_check(hbu_pipe_peek(pipe))) {
// Quoted attribute value
hbsh_quoteattrval(pipe, collapse_and_trim_whitespace);
} else {
if (!hbs_options_supressed_error(so, HBE_PARSE_UNQUOTED_ATTR)) {
hbu_pipe_error(pipe, HBE_PARSE_UNQUOTED_ATTR, "Unquoted attribute value");
}
// Unquoted attribute value
hbsh_unquoteattrval(pipe);
return HBSH_ATTR_QUOTED;
}
if (!hbs_options_supressed_error(so, HBE_PARSE_UNQUOTED_ATTR)) {
hbu_pipe_error(pipe, HBE_PARSE_UNQUOTED_ATTR, "Unquoted attribute value");
}
// Unquoted attribute value
hbsh_unquoteattrval(pipe);
return HBSH_ATTR_UNQUOTED;
}
return HBSH_ATTR_NOVAL;
}
#endif // _HDR_HYPERBUILD_STREAM_HELPER_ATTR

View File

@ -31,8 +31,17 @@ void hbs_tag(hbs_options_t so, hbu_pipe_t pipe, hb_char_t *parent) {
hbu_pipe_require(pipe, '<');
hbu_buffer_t opening_name = hbsh_tagname(so, pipe);
int last_attr_type = -1;
while (1) {
size_t ws_accepted = hbu_pipe_accept_while_predicate(pipe, &hbr_whitespace_check);
// At the beginning of this loop, the last parsed unit was either the tag name
// or an attribute (including its value, if it had one)
size_t ws_accepted;
if (so->remove_tag_whitespace) {
ws_accepted = hbu_pipe_skip_while_predicate(pipe, &hbr_whitespace_check);
} else {
ws_accepted = hbu_pipe_accept_while_predicate(pipe, &hbr_whitespace_check);
}
if (hbu_pipe_accept_if(pipe, '>')) {
break;
@ -46,12 +55,17 @@ void hbs_tag(hbs_options_t so, hbu_pipe_t pipe, hb_char_t *parent) {
break;
}
// TODO Check for whitespace between attributes and before self-closing tag
if (!ws_accepted) {
hbu_pipe_require_predicate(pipe, &hbr_whitespace_check, "whitespace between attributes");
hbu_pipe_error(pipe, HBE_PARSE_NO_SPACE_BEFORE_ATTR, "No whitespace before attribute");
}
hbsh_attr(so, pipe);
if (so->remove_tag_whitespace) {
if (last_attr_type != HBSH_ATTR_QUOTED) {
hbu_pipe_write(pipe, ' ');
}
}
last_attr_type = hbsh_attr(so, pipe);
}
hb_char_t *tag_name = hbu_buffer_underlying(opening_name);

View File

@ -552,8 +552,11 @@ void hbu_pipe_skip_amount(hbu_pipe_t pipe, size_t amount) {
*
* @param pipe pipe
* @param pred predicate
* @return amount of characters skipped
*/
void hbu_pipe_skip_while_predicate(hbu_pipe_t pipe, hbu_pipe_predicate_t pred) {
size_t hbu_pipe_skip_while_predicate(hbu_pipe_t pipe, hbu_pipe_predicate_t pred) {
size_t count = 0;
while (1) {
hb_eod_char_t c = hbu_pipe_peek_eoi(pipe);
@ -562,7 +565,10 @@ void hbu_pipe_skip_while_predicate(hbu_pipe_t pipe, hbu_pipe_predicate_t pred) {
}
hbu_pipe_skip(pipe);
count++;
}
return count;
}
/**