md2point.c - pointtools - Simple point utilities to hold text presentations.
HTML git clone git://bitreich.org/pointtools/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/pointtools/
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
DIR 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 }