чување 42093fa16b10ba187b06e706876e845f7d43cdc4
родитељ bebfed32de3fa0950fe78be3d075bb1458e182db
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Fri, 19 May 2023 21:52:42 +0200
* Don't allow elements which are not allowed within <p> to be output inside it
* Skip trailing slashes on "void elements"
(https://html.spec.whatwg.org/multipage/syntax.html#void-elements)
* Minor manpage fixes
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
измењених датотека: 4, додавања: 112(+), брисања: 48(-)
diff --git a/TODO b/TODO
@@ -1,11 +1,13 @@
TODO
====
-[ ] Tighten up what's allowed within <p> (<pre> is not!)
+[x] Tighten up what's allowed within <p> (<pre> is not!)
-[ ] Skip trailing slashes on "void elements":
+[x] Skip trailing slashes on "void elements":
https://html.spec.whatwg.org/multipage/syntax.html#void-elements
+[x] Check & inside backticks (also in manpage)
+
< > Add <abbr>?
diff --git a/examples/macros/index.slw b/examples/macros/index.slw
@@ -2,7 +2,7 @@
stylesheet: style.css
---
-{=!copyright}Copyright © John Doe. <br />
+{=!copyright}Copyright © John Doe. {br}
All rights reserved.{/=!copyright}
{header}Header: {=copyright}{/header}
diff --git a/slweb.1.in b/slweb.1.in
@@ -102,8 +102,9 @@ are using a minimal subset of Markdown with added directives.
.BR Backticks .
Text inside \fC`backticks`\fR will be put inside \fC<code></code>\fR. Text
surrounded by triple backticks (\fC```\fR) on the lines by themselves will be
-put inside \fC<pre></pre>\fR. Any \[lq]less-than\[rq] character inside backticks
-will be converted to \fC<\fR. Any text following the first triple backticks
+put inside \fC<pre></pre>\fR. Any \[lq]less-than\[rq] characters inside backticks
+will be converted to \fC<\fR and \[lq]ampersand\[rq] characters to
+\fC&\fR. Any text following the first triple backticks
until the end of the line will be ignored. This is to account for language
highlighting specification, which isn't yet supported.
.
@@ -153,7 +154,7 @@ gives (some lines are wrapped for this manual):
<p>This is a text<a href="#footnote-1" id="footnote-text-1">
<sup>1</sup></a>.</p>
-<hr />
+<hr>
<p id="footnote-1"><a href="#footnote-text-1">1.</a>
With a footnote!</p>
.CDE
@@ -173,7 +174,7 @@ will produce
Inline footnote<a href="#inline-footnote-1"
id="inline-footnote-text-1"><sup>1</sup></a> in a
paragraph.
-<hr />
+<hr>
<p id="inline-footnote-1"><a href="#inline-footnote-text-1">
1.</a> Footnote text</p>
.CDE
@@ -209,7 +210,7 @@ headings.
.
.IP \[bu]
.BR "Horizontal rules" .
-Three dashes at the start of the line will produce a \fC<hr />\fR in the output.
+Three dashes at the start of the line will produce a \fC<hr>\fR in the output.
As this Markdown feature clashes with
.SM YAML
block boundaries, it will work only if
@@ -240,7 +241,7 @@ Which will produce:
<figure>
<a href="/path/to/image.png" title="Some title" class="image"
target="_blank"><img src="/path/to/image.png" alt="Some title"
- width="100" height="50" /></a><figcaption>Some title</figcaption>
+ width="100" height="50" ></a><figcaption>Some title</figcaption>
</figure>
.CDE
.
@@ -273,7 +274,7 @@ with backticks, any \[lq]less-than\[rq] character will be converted to
.
.IP \[bu]
.BR "Line breaks" .
-Two spaces followed by a newline will become \fC<br />\fR.
+Two spaces followed by a newline will become \fC<br>\fR.
.
.IP \[bu]
.BR Links .
@@ -769,7 +770,7 @@ body (inside a \fC<header>\fR tag if it is set), surrounded by
.IP \[bu]
.BR canonical .
Contents of this variable will be added as a value of a \fCrel\fR attribute for
-the \fC<link rel="canonical" />\fR tag.
+the \fC<link rel="canonical">\fR tag.
.
.IP \[bu]
.BR csv-delimiter .
@@ -856,7 +857,7 @@ containing a list of values to be inserted into meta tags. The first row of this
TSV file is treated as the header row and ignored. First column in this TSV file
contains the meta variable names, and the second column contains meta variable
values. For each row, a \fC<meta name="\f[CI]firstcol\fC"
-content="\f[CI]secondcol\fC" />\fR is inserted, where
+content="\f[CI]secondcol\fC">\fR is inserted, where
.I firstcol
is the first column, and
.I secondcol
@@ -886,7 +887,7 @@ in the
file, a
.
.CDS 8
-<meta name="og:url" content="https://example.com/" />
+<meta name="og:url" content="https://example.com/">
.CDE
.
.IP ""
@@ -923,7 +924,7 @@ tags.
.BR stylesheet .
The contents of this variable will be treated as a
.SM CSS
-file name to be included using the \fC<link rel="stylesheet" />\fR tag. You can
+file name to be included using the \fC<link rel="stylesheet">\fR tag. You can
add more than one
.I stylesheet
declaration per
@@ -982,10 +983,10 @@ file \fCindex.html\fR contains:
<html lang="en">
<head>
<title>Test website</title>
- <meta charset="utf-8" />
- <meta name="description" content="My first website in slweb" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <meta name="generator" content="slweb" />
+ <meta charset="utf-8">
+ <meta name="description" content="My first website in slweb">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="generator" content="slweb">
</head>
<body>
diff --git a/slweb.c b/slweb.c
@@ -512,13 +512,13 @@ print_meta_var(FILE* output, u8** tsv_header, u8** tsv_register)
if (value)
print_output(output,
- "<meta name=\"%s\" content=\"%s\" />\n",
+ "<meta name=\"%s\" content=\"%s\">\n",
*tsv_register, value);
free(var_name);
}
else
- print_output(output, "<meta name=\"%s\" content=\"%s\" />\n",
+ print_output(output, "<meta name=\"%s\" content=\"%s\">\n",
*tsv_register, *(tsv_register + 1));
return 0;
}
@@ -582,7 +582,7 @@ process_stylesheet(FILE* output, const u8* css_filename, int output_yaml)
print_output(output, "stylesheet: %s\n", css_filename);
else
print_output(output,
- "<link rel=\"stylesheet\" href=\"%s\" />\n",
+ "<link rel=\"stylesheet\" href=\"%s\">\n",
css_filename);
output_firstcol = 1;
return 0;
@@ -2196,7 +2196,9 @@ process_inline_image(FILE* output, const u8* image_text,
const int add_link, const int add_figcaption)
{
if (add_figcaption)
+ {
print_output(output, "<figure>\n");
+ }
if (add_link)
print_output(output,
@@ -2207,11 +2209,12 @@ process_inline_image(FILE* output, const u8* image_text,
link_prefix ? (const char*)link_prefix : "",
image_url ? (char*)image_url : "", image_text);
- print_output(output, "<img src=\"%s\" alt=\"%s\" ",
- image_url ? (char*)image_url : "", image_text);
+ print_output(output, "<img src=\"%s\" alt=\"%s\"%s",
+ image_url ? (char*)image_url : "", image_text,
+ image_url ? " " : "");
if (image_url)
print_image_dimensions(output, image_file_prefix, image_url);
- print_output(output, "%s/>", image_url ? " " : "");
+ print_output(output, ">");
output_firstcol = 0;
@@ -2240,10 +2243,10 @@ process_image(FILE* output, const u8* image_text, const u8* image_file_prefix,
int
process_line_start(FILE* output, const u8* line, const u8* link_prefix,
const int first_line_in_doc, const int previous_line_blank,
- const int read_yaml_macros_and_links, const int list_para,
- const int new_para_ok)
+ int* previous_line_block, const int read_yaml_macros_and_links,
+ const int list_para, const int new_para_ok)
{
- if ((first_line_in_doc || previous_line_blank)
+ if ((first_line_in_doc || previous_line_blank || *previous_line_block)
&& !(ANY(state, ST_BLOCKQUOTE | ST_PRE)))
{
if (!list_para)
@@ -2286,7 +2289,8 @@ process_line_start(FILE* output, const u8* line, const u8* link_prefix,
if (!read_yaml_macros_and_links)
{
print_output(output, "<p>");
- output_firstcol = 0;
+ *previous_line_block = 0;
+ output_firstcol = 0;
}
state |= ST_PARA_OPEN;
}
@@ -2297,17 +2301,18 @@ process_line_start(FILE* output, const u8* line, const u8* link_prefix,
int
process_text_token(FILE* output, const u8* line, const u8* link_prefix,
const int first_line_in_doc, const int previous_line_blank,
- const int processed_start_of_line, const int read_yaml_macros_and_links,
- const int list_para, u8** token, u8** ptoken, size_t* token_size,
- const int add_enclosing_paragraph, const int new_para_ok)
+ int* previous_line_block, const int processed_start_of_line,
+ const int read_yaml_macros_and_links, const int list_para, u8** token,
+ u8** ptoken, size_t* token_size, const int add_enclosing_paragraph,
+ const int new_para_ok)
{
if (!(IN(state, ST_YAML)))
{
if (add_enclosing_paragraph && !processed_start_of_line)
process_line_start(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
- read_yaml_macros_and_links, list_para,
- new_para_ok);
+ previous_line_block, read_yaml_macros_and_links,
+ list_para, new_para_ok);
**ptoken = 0;
if (**token && !read_yaml_macros_and_links
&& !(IN(state, ST_MACRO_BODY)))
@@ -2416,7 +2421,7 @@ process_horizontal_rule(FILE* output)
/* Temporarily break paragraph as hr is para-level */
if (IN(state, ST_PARA_OPEN))
print_output(output, "</p>\n");
- print_output(output, "<hr />\n");
+ print_output(output, "<hr>\n");
if (IN(state, ST_PARA_OPEN))
print_output(output, "<p>\n");
output_firstcol = 1;
@@ -2461,7 +2466,7 @@ begin_html_and_head(FILE* output)
"<html lang=\"%s\">\n"
"<head>\n"
"<title>%s</title>\n"
- "<meta charset=\"utf-8\" />\n",
+ "<meta charset=\"utf-8\">\n",
lang ? (char*)lang : "en", site_name ? (char*)site_name : "");
char* favicon = NULL;
@@ -2470,7 +2475,7 @@ begin_html_and_head(FILE* output)
if (!access(favicon, R_OK))
print_output(output,
"<link rel=\"shortcut icon\" type=\"image/x-icon\""
- " href=\"%s\" />\n",
+ " href=\"%s\">\n",
favicon_url ? (char*)favicon_url : "/favicon.ico");
free(favicon);
@@ -2484,25 +2489,25 @@ begin_html_and_head(FILE* output)
}
if (canonical && *canonical)
- print_output(output, "<link rel=\"canonical\" href=\"%s\" />\n",
+ print_output(output, "<link rel=\"canonical\" href=\"%s\">\n",
(char*)canonical);
if (feed && *feed && feed_desc && *feed_desc)
print_output(output,
"<link rel=\"alternate\""
" type=\"application/rss+xml\" href=\"%s\" "
- "title=\"%s\" />\n",
+ "title=\"%s\">\n",
(char*)feed, (char*)feed_desc);
if (site_desc && *site_desc)
print_output(output,
- "<meta name=\"description\" content=\"%s\" />\n",
+ "<meta name=\"description\" content=\"%s\">\n",
(char*)site_desc);
print_output(output,
"<meta name=\"viewport\" content=\"width=device-width,"
- " initial-scale=1\" />\n<meta name=\"generator\" "
- "content=\"slweb\" />\n");
+ " initial-scale=1\">\n<meta name=\"generator\" "
+ "content=\"slweb\">\n");
output_firstcol = 1;
return 0;
}
@@ -2761,6 +2766,7 @@ slweb_parse(FILE* output, const char* source_filename, const u8* buffer,
int skip_eol = 0;
int keep_token = 0;
int previous_line_blank = 0;
+ int previous_line_block = 0;
int processed_start_of_line = 0;
int add_image_links = 1;
int add_figcaption = 1;
@@ -2996,6 +3002,7 @@ do_line:
/* Output existing text up to ~~ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3036,6 +3043,7 @@ do_line:
/* Output existing text up to ~~ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3077,6 +3085,7 @@ do_line:
/* Output existing text up to ~ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3113,9 +3122,21 @@ do_line:
if (!read_yaml_macros_and_links)
{
if (IN(state, ST_PRE))
+ {
+ if (IN(state, ST_PARA_OPEN))
+ {
+ print_output(output, "</p>\n");
+ state &= ~ST_PARA_OPEN;
+ }
print_output(output, "<pre>");
+ }
else
+ {
print_output(output, "</pre>");
+ previous_line_block = 1;
+ /*if (IN(state, ST_PARA_OPEN))
+ print_output(output, "<p>");*/
+ }
output_firstcol = 0;
}
@@ -3149,6 +3170,7 @@ do_line:
/* Output existing text up to ` */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3255,6 +3277,7 @@ do_line:
/* Output existing text up to __ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3297,6 +3320,7 @@ do_line:
/* Output existing text up to _ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3379,6 +3403,7 @@ do_line:
{
process_line_start(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
read_yaml_macros_and_links, list_para, 1);
/* Ignore abbreviations (for now) */
@@ -3449,6 +3474,7 @@ do_line:
/* Output existing text up to * */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3492,6 +3518,7 @@ do_line:
/* Output existing text up to * */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3541,7 +3568,7 @@ do_line:
list_para = 1;
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
- processed_start_of_line,
+ &previous_line_block, processed_start_of_line,
read_yaml_macros_and_links, list_para, &token,
&ptoken, &token_size, 1, 1);
processed_start_of_line = 1;
@@ -3555,9 +3582,9 @@ do_line:
if (strlen((char*)pline) == 2 && *(pline + 1) == ' ')
{
- size_t br_len = strlen("<br />");
+ size_t br_len = strlen("<br>");
*ptoken = 0;
- strcat((char*)ptoken, "<br />");
+ strcat((char*)ptoken, "<br>");
ptoken += br_len;
output_firstcol = 0;
pline++;
@@ -3632,7 +3659,7 @@ do_line:
/* Output existing text up to { */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
- processed_start_of_line,
+ &previous_line_block, processed_start_of_line,
read_yaml_macros_and_links, list_para, &token,
&ptoken, &token_size, 0, 1);
processed_start_of_line = 1;
@@ -3768,6 +3795,7 @@ do_line:
/* Output existing text up to || */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -3990,6 +4018,11 @@ do_line:
if (!read_yaml_macros_and_links
&& !(IN(state, ST_BLOCKQUOTE)))
{
+ if (IN(state, ST_PARA_OPEN))
+ {
+ print_output(output, "</p>\n");
+ state &= ~ST_PARA_OPEN;
+ }
process_blockquote(output, 0);
output_firstcol = 0;
}
@@ -4024,7 +4057,7 @@ do_line:
*ptoken = 0;
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
- processed_start_of_line,
+ &previous_line_block, processed_start_of_line,
read_yaml_macros_and_links, list_para, &token,
&ptoken, &token_size, 0, 1);
processed_start_of_line = 1;
@@ -4100,6 +4133,7 @@ do_line:
*ptoken = 0;
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -4119,7 +4153,7 @@ do_line:
*ptoken = 0;
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
- processed_start_of_line,
+ &previous_line_block, processed_start_of_line,
read_yaml_macros_and_links, list_para, &token,
&ptoken, &token_size, 1, 1);
}
@@ -4227,10 +4261,21 @@ do_line:
link_macro),
token);
else
+ {
+ if (add_figcaption && IN(state, ST_PARA_OPEN))
+ {
+ print_output(output, "</p>\n");
+ state &= ~ST_PARA_OPEN;
+ }
+
process_inline_image(output, link_text,
image_file_prefix, link_prefix,
token, add_image_links,
add_figcaption);
+
+ if (add_figcaption)
+ previous_line_block = 1;
+ }
}
RESET_TOKEN(token, ptoken, token_size);
state &= ~(ST_LINK | ST_LINK_SECOND_ARG | ST_IMAGE
@@ -4308,9 +4353,20 @@ do_line:
else if (IN(state, ST_IMAGE_SECOND_ARG))
{
if (!read_yaml_macros_and_links)
+ {
+ if (add_figcaption && IN(state, ST_PARA_OPEN))
+ {
+ print_output(output, "</p>\n");
+ state &= ~ST_PARA_OPEN;
+ }
+
process_image(output, link_text,
image_file_prefix, link_prefix, token,
add_image_links, add_figcaption);
+
+ if (add_figcaption)
+ previous_line_block = 1;
+ }
RESET_TOKEN(token, ptoken, token_size);
state &= ~(ST_IMAGE | ST_IMAGE_SECOND_ARG);
pline++;
@@ -4324,6 +4380,7 @@ do_line:
case ':':
process_line_start(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
read_yaml_macros_and_links, list_para,
0);
@@ -4412,7 +4469,7 @@ do_line:
*ptoken = 0;
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
- processed_start_of_line,
+ &previous_line_block, processed_start_of_line,
read_yaml_macros_and_links, list_para, &token,
&ptoken, &token_size, 1, 1);
processed_start_of_line = 1;
@@ -4479,6 +4536,7 @@ do_line:
/* Output existing text up to $$ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -4515,6 +4573,7 @@ do_line:
/* Output existing text up to $ */
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -4791,6 +4850,7 @@ done_line:
| ST_IMAGE | ST_LINK))
process_text_token(output, line, link_prefix,
first_line_in_doc, previous_line_blank,
+ &previous_line_block,
processed_start_of_line,
read_yaml_macros_and_links, list_para,
&token, &ptoken, &token_size, 1, 1);
@@ -4887,6 +4947,7 @@ done_line:
if (!read_yaml_macros_and_links)
{
process_blockquote(output, 1);
+ previous_line_block = 1;
output_firstcol = 0;
}
}