|
|
md2point.c - pointtools - Simple point utilities to hold text presentations. |
|
|
 |
git clone git://bitreich.org/pointtools/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/pointtools/ (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
 |
LICENSE |
|
|
|
--- |
|
|
|
md2point.c (3365B) |
|
|
|
--- |
|
|
|
1 /* |
|
|
|
2 * See LICENSE for license details. |
|
|
|
3 */ |
|
|
|
4 #include <err.h> |
|
|
|
5 #include <limits.h> |
|
|
|
6 #include <stdio.h> |
|
|
|
7 #include <stdlib.h> |
|
|
|
8 #include <string.h> |
|
|
|
9 #include <unistd.h> |
|
|
|
10 |
|
|
|
11 #ifdef NEED_STRLCPY /* OpenBSD implementation */ |
|
|
|
12 size_t |
|
|
|
13 strlcpy(char *dst, const char *src, size_t dsize) { |
|
|
|
14 const char *osrc = src; |
|
|
|
15 size_t nleft = dsize; |
|
|
|
16 |
|
|
|
17 if (nleft != 0) { |
|
|
|
18 while (--nleft != 0) { |
|
|
|
19 if ((*dst++= *src++) == '\0') |
|
|
|
20 break; |
|
|
|
21 } |
|
|
|
22 } |
|
|
|
23 |
|
|
|
24 if (nleft == 0) { |
|
|
|
25 if (dsize != 0) |
|
|
|
26 *dst = '\0'; |
|
|
|
27 while (*src++) |
|
|
|
28 ; |
|
|
|
29 } |
|
|
|
30 |
|
|
|
31 return(src - osrc - 1); |
|
|
|
32 } |
|
|
|
33 #endif /* NEED_STRLCPY */ |
|
|
|
34 |
|
|
|
35 /* from git://bitreich.org/utf8expr */ |
|
|
|
36 size_t |
|
|
|
37 utf8strlen(const char *s) |
|
|
|
38 { |
|
|
|
39 size_t i; |
|
|
|
40 |
|
|
|
41 for (i = 0; *s; s++) { |
|
|
|
42 if ((*s & 0xc0) != 0x80) |
|
|
|
43 i++; |
|
|
|
44 } |
|
|
|
45 |
|
|
|
46 return i; |
|
|
|
47 } |
|
|
|
48 |
|
|
|
49 void |
|
|
|
50 fprintunderline(FILE *fp, const char *str) |
|
|
|
51 { |
|
|
|
52 size_t i, len; |
|
|
|
53 |
|
|
|
54 fprintf(fp, "\n %s\n ", str); |
|
|
|
55 len = utf8strlen(str); |
|
|
|
56 for (i = 0; i <= len; ++i) |
|
|
|
57 fputs("=", fp); |
|
|
|
58 fputs("\n\n", fp); |
|
|
|
59 } |
|
|
|
60 |
|
|
|
61 void |
|
|
|
62 escapechars(char *s) |
|
|
|
63 { |
|
|
|
64 for (; *s; s++) { |
|
|
|
65 if (*s == '\n') { |
|
|
|
66 *s = '\0'; |
|
|
|
67 return; |
|
|
|
68 } |
|
|
|
69 |
|
|
|
70 /* |
|
|
|
71 * Only allow ASCII printable a-zA-Z0-9 for simplicity. |
|
|
|
72 */ |
|
|
|
73 if ((*s >= 'a' && *s <= 'z') |
|
|
|
74 || (*s >= 'A' && *s <= 'Z') |
|
|
|
75 || (*s >= '0' && *s <= '9')) { |
|
|
|
76 continue; |
|
|
|
77 } |
|
|
|
78 *s = '_'; |
|
|
|
79 } |
|
|
|
80 } |
|
|
|
81 |
|
|
|
82 void |
|
|
|
83 fprintesc(FILE *fp, const char *s) |
|
|
|
84 { |
|
|
|
85 int intext = 0; |
|
|
|
86 |
|
|
|
87 fputs(" ", fp); |
|
|
|
88 for (; *s; s++) { |
|
|
|
89 switch (*s) { |
|
|
|
90 case ' ': |
|
|
|
91 fputc(' ', fp); |
|
|
|
92 break; |
|
|
|
93 case '\t': |
|
|
|
94 fprintf(fp, " "); |
|
|
|
95 break; |
|
|
|
96 case '*': |
|
|
|
97 if (intext) { |
|
|
|
98 fputc(*s, fp); |
|
|
|
99 } else { |
|
|
|
100 fputc('o', fp); |
|
|
|
101 intext = 1; |
|
|
|
102 } |
|
|
|
103 break; |
|
|
|
104 default: |
|
|
|
105 intext = 1; |
|
|
|
106 fputc(*s, fp); |
|
|
|
107 break; |
|
|
|
108 } |
|
|
|
109 } |
|
|
|
110 fputs("\n", fp); |
|
|
|
111 } |
|
|
|
112 |
|
|
|
113 void |
|
|
|
114 mkfilename(char *fname, char *str, size_t bufsiz, int i) |
|
|
|
115 { |
|
|
|
116 char buf[PATH_MAX]; |
|
|
|
117 |
|
|
|
118 strlcpy(buf, str, sizeof(buf)); |
|
|
|
119 escapechars(buf); |
|
|
|
120 snprintf(fname, bufsiz, "%.4d-%s.txt", i, buf); |
|
|
|
121 } |
|
|
|
122 |
|
|
|
123 void |
|
|
|
124 copyfile(char *dst, char *src) |
|
|
|
125 { |
|
|
|
126 int c; |
|
|
|
127 FILE *fsrc, *fdst; |
|
|
|
128 |
|
|
|
129 if (src[0] == '\0' || dst[0] == '\0' || |
|
|
|
130 !(fsrc = fopen(src, "r")) || !(fdst = fopen(dst, "w"))) |
|
|
|
131 err(1, "copyfile: %s -> %s", src, dst); |
|
|
|
132 |
|
|
|
133 while ((c = fgetc(fsrc)) != EOF) |
|
|
|
134 fputc(c, fdst); |
|
|
|
135 |
|
|
|
136 fclose(fsrc); |
|
|
|
137 fclose(fdst); |
|
|
|
138 } |
|
|
|
139 |
|
|
|
140 int |
|
|
|
141 main(void) |
|
|
|
142 { |
|
|
|
143 size_t i = 0; |
|
|
|
144 char *line = NULL; |
|
|
|
145 size_t linesize = 0; |
|
|
|
146 ssize_t linelen; |
|
|
|
147 char title[PATH_MAX] = "", fname[PATH_MAX] = "", fname_old[PATH_MAX] = ""; |
|
|
|
148 FILE *fp = NULL; |
|
|
|
149 |
|
|
|
150 while ((linelen = getline(&line, &linesize, stdin)) > 0) { |
|
|
|
151 if (line[linelen - 1] == '\n') |
|
|
|
152 line[--linelen] = '\0'; |
|
|
|
153 |
|
|
|
154 if (line[0] == '%') |
|
|
|
155 continue; |
|
|
|
156 |
|
|
|
157 if (line[0] == '\\') { |
|
|
|
158 if (line[1] == '\0') |
|
|
|
159 continue; |
|
|
|
160 |
|
|
|
161 /* ignore text before first header */ |
|
|
|
162 if (fp) |
|
|
|
163 fprintesc(fp, line+1); |
|
|
|
164 } else if (line[0] == '#' && line[1] == '#') { |
|
|
|
165 if (fp) { |
|
|
|
166 fclose(fp); |
|
|
|
167 fp = NULL; |
|
|
|
168 } |
|
|
|
169 strlcpy(title, line + 2, sizeof(title)); |
|
|
|
170 mkfilename(fname, title, sizeof(fname), i++); |
|
|
|
171 if (!(fp = fopen(fname, "w"))) |
|
|
|
172 err(1, "fopen: %s", fname); |
|
|
|
173 if (line[2] == '\0') |
|
|
|
174 fputs("\n", fp); |
|
|
|
175 else |
|
|
|
176 fprintunderline(fp, title); |
|
|
|
177 } else if (linelen > 5 && !strncmp(line, "#pause", linelen)) { |
|
|
|
178 if (fp) { |
|
|
|
179 fclose(fp); |
|
|
|
180 fp = NULL; |
|
|
|
181 } |
|
|
|
182 strlcpy(fname_old, fname, sizeof(fname_old)); |
|
|
|
183 mkfilename(fname, title, sizeof(fname), i++); |
|
|
|
184 copyfile(fname, fname_old); |
|
|
|
185 if (fname[0] != '\0' && !(fp = fopen(fname, "a"))) |
|
|
|
186 err(1, "fopen: %s", fname); |
|
|
|
187 } else { |
|
|
|
188 /* ignore text before first header */ |
|
|
|
189 if (fp) |
|
|
|
190 fprintesc(fp, line); |
|
|
|
191 } |
|
|
|
192 } |
|
|
|
193 |
|
|
|
194 free(line); |
|
|
|
195 |
|
|
|
196 return 0; |
|
|
|
197 } |
|