summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/main.c b/main.c
index f52297d..14794fb 100644
--- a/main.c
+++ b/main.c
@@ -25,6 +25,7 @@ typedef struct {
int hvarc;
Str docroot;
Str header_file, footer_file;
+ unsigned wrap_width;
} Options;
Options opts = { 0 };
@@ -88,6 +89,47 @@ int uri_ch_allowed(char c) {
|| c == '%';
}
+int str_to_uint(Str s, unsigned *out) {
+ unsigned x = 0;
+ if (!s.n) return -1;
+ for (int i = 0; i < s.n; i++) {
+ if (s.s[i] < '0' || s.s[i] > '9') return -1;
+ x = x * 10 + (s.s[i] - '0');
+ }
+ *out = x;
+ return 0;
+}
+
+void str_cat_wrap_lines(Str *out, Str src, int width, int hanging_indent, Arena *a) {
+ Str line;
+ while (next_line(&src, &line)) {
+ unsigned col = 1;
+ while (line.n > 0) {
+ if (line.s[0] == ' ') {
+ line = str_skip(line, 1);
+space:
+ col++;
+ str_catc(out, ' ', a);
+ } else {
+ Cut c = str_cut(line, ' ');
+ if (col + c.head.n > width) {
+ str_catc(out, '\n', a);
+ col = 1;
+ for (int i = 0; i < hanging_indent; i++) {
+ str_catc(out, ' ', a);
+ col++;
+ }
+ }
+ str_cat(out, c.head, a);
+ col += c.head.n;
+ line = c.tail;
+ goto space;
+ }
+ }
+ str_catc(out, '\n', a);
+ }
+}
+
void str_cat_uri_internal(Str *s, Str uri, Arena *a) {
for (isize i = 0; i < uri.n; i++) {
char c = uri.s[i];
@@ -497,10 +539,17 @@ int wdoc(FILE *f, Doc **dp, Arena *perm, Arena *scratch) {
Doc *d = new(perm, Doc);
BlockList blk = blk_gather(buf, scratch);
for (size_t i = 0; i < blk.len; i++) {
- if (blk.data[i].type == LN_HDR1 && !d->title.s) {
- d->title = blk.data[i].lines->txt;
+ Block *b = &blk.data[i];
+ if (b->type == LN_HDR1 && !d->title.s) {
+ d->title = b->lines->txt;
+ }
+ Str blk_txt = { 0 };
+ markup_block(&blk_txt, b, scratch, scratch);
+ if (b->type == LN_CODE || opts.wrap_width == 0) {
+ str_cat(&d->html, blk_txt, perm);
+ } else {
+ str_cat_wrap_lines(&d->html, blk_txt, opts.wrap_width, 0, perm);
}
- markup_block(&d->html, &blk.data[i], perm, scratch);
if (i + 1 < blk.len) str_cat(&d->html, S("\n"), perm);
}
*dp = d;
@@ -560,7 +609,8 @@ void usage(const char *cmd) {
" -R --root set a root url prepended to absolute paths\n"
" -H --header prepend the given file before the document\n"
" -F --footer append the given file after the document\n"
- " -L --lang set the document's language\n",
+ " -L --lang set the document's language\n"
+ " -w --width wrap lines at the given column width\n",
cmd, cmd);
}
@@ -670,7 +720,7 @@ int main(int argc, const char **argv) {
Str param = { 0 };
opts.from_stdin = 1;
- while ((r = arg_get(&a, "?sliqc:h:t:L:R:H:F:", &param,
+ while ((r = arg_get(&a, "?sliqc:h:t:L:R:H:F:w:", &param,
"help", '?',
"standalone", 's',
"smartq", 'q',
@@ -682,7 +732,8 @@ int main(int argc, const char **argv) {
"root", 'R',
":hvar", 'h',
"header", 'H',
- "footer", 'F')) >= ARG_OK) {
+ "footer", 'F',
+ ":width", 'w')) >= ARG_OK) {
Arena reset = scratch;
FILE *f;
switch (r) {
@@ -726,6 +777,12 @@ int main(int argc, const char **argv) {
case 'F':
opts.footer_file = param;
break;
+ case 'w':
+ if (str_to_uint(param, &opts.wrap_width)) {
+ fprintf(stderr, "invalid wrap width '%*s'\n", (int)param.n, param.s);
+ return 1;
+ }
+ break;
default:
if (str_eql(param, S("-"))) {
if (wdoc(stdin, &doc, &perm, &scratch)) {