md2point.c - pointtools - Simple point utilities to hold text presentations. | |
git clone git://bitreich.org/pointtools/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfr… | |
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_… | |
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", linel… | |
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 } |