-
Notifications
You must be signed in to change notification settings - Fork 1
/
literate.c
77 lines (59 loc) · 1.9 KB
/
literate.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char** argv)
{
if (argc < 3) {
// print usage
printf("Usage: literate -[s|d] <input>\n");
printf(" Ex.: literate -s main.lc > main.c\n");
printf(" Ex.: literate -d main.lc > main.md\n");
exit(EXIT_FAILURE);
}
// get input filename from commandline
const char* input_path = argv[2];
// get command line flag (-s or -d)
const int should_print_code = (strncmp(argv[1], "-s", 2)==0) ? 1 : 0;
FILE *fp = fopen( input_path, "r"); // open file for reading
if (fp == NULL) {
perror("Fatal: Unable to open input file.\n");
exit(EXIT_FAILURE);
}
int last_char_was_newline = 0; // false
int in_code = 0; // false
int in_desired_block = 0; // false
char ch = ' '; // a safe default
// loop through every character
while ( (ch = (char) fgetc(fp) ) != EOF ) {
// an awkward boolean logic, but this figures out whether this character should be visible.
in_desired_block = (!should_print_code || (in_code == should_print_code));
// a super simple parser
if (ch == '\n') {
// update parser state
last_char_was_newline = 1;
in_code = 0;
// print newline when in desired block
if (in_desired_block) {
printf("%c",ch);
}
continue;
} else if (last_char_was_newline && ch == '>') {
// ... we've detected a code block
in_code = 1;
// output indented code block for markdown
if (in_desired_block) printf(" ");
continue;
} else if (last_char_was_newline && ch == ' ') {
// ... skip first space after ">"
last_char_was_newline = 0;
continue;
}
last_char_was_newline = 0;
// if we should, output the current character
if (in_desired_block) printf("%c",ch);
}
// close the open file
fclose(fp);
return EXIT_SUCCESS;
}