Separating input into blocks

1

Separating input into blocks

2
@Def(input prereqs)
@put(globals)
@End(input prereqs)
3
@def(globals)
enum class Read_State {
new_element
@put(read states)
};
@end(globals)
4
@add(globals)
using RS = Read_State;
@end(globals)
5
@Add(open input elements)
Read_State state = RS::new_element;
@End(open input elements)
6
@Def(process line)
do {
auto &state = inputs.cur().state;
@put(line vars);
@put(states with newlines);
@put(handle newlines);
@put(states without newlines);
@put(unknown line);
} while (false);
@End(process line)
7
@def(handle newlines)
if (line.empty()) {
state = RS::new_element;
break;
}
@end(handle newlines)
8
@def(read states),
header
@end(read states)
9
@def(states without newlines)
if (line[0] == '#' && (state == RS::new_element || state == RS::header)) {
bool was_new { state == RS::new_element };
state = RS::header;
@put(got header line);
break;
}
@end(states without newlines)
10
@def(unknown line)
std::cerr << "!! " << line << '\n';
@end(unknown line)
11
@Add(includes)
#include <vector>
@End(includes)
12
@add(globals)
struct Block {
Read_State state;
std::vector<std::string> value;
std::vector<std::string> notes;
int level;
};
@end(globals)
13
@Add(input elements)
std::vector<Block> blocks;
@End(input elements);
14
@def(line vars)
auto &blocks =
inputs.cur_input().blocks;
@end(line vars)
15
@def(got header line)
auto b { line.begin() };
auto e { line.end() };
int l { 0 };
for (; b != e && *b == '#'; ++b, ++l) {}
for (; b != e && *b == ' '; ++b) {}
if (was_new || blocks.empty() || blocks.back().state != RS::header ||
blocks.back().notes.size()
) {
blocks.push_back({ RS::header, {}, {}, l });
}
blocks.back().value.emplace_back(
b, e
);
@end(got header line)
16
@add(read states),
code,
after_code
@end(read states)
17
@def(states with newlines)
if (line.size() >= 3 && line.substr(0, 3) == "```" &&
state == RS::new_element
) {
state = RS::code;
@put(enter code block);
break;
}
@end(states with newlines)
18
@add(states with newlines)
if (state == RS::code) {
if (line == "```") {
state = RS::after_code;
} else {
@put(got code line);
}
break;
}
@end(states with newlines)
19
@def(enter code block)
blocks.push_back({ RS::code, {}, {}, 0 });
@end(enter code block)
20
@def(got code line)
blocks.back().value.push_back(line);
@end(got code line)
21
@add(read states),
notes
@end(read states)
22
@add(states without newlines)
if (line[0] == '*') {
if (
state == RS::header ||
state == RS::after_code ||
state == RS::notes
@put(can have notes)
) {
state = RS::notes;
@put(got note);
break;
}
}
@end(states without newlines)
23
@add(states without newlines)
if (line[0] == ' ' && state == RS::notes) {
@put(add note);
break;
}
@end(states without newlines)
24
@def(got note)
auto b { line.begin() };
auto e { line.end() };
for (; b != e && (*b == '*' || *b == ' '); ++b) {}
blocks.back().notes.emplace_back(b, e);
@end(got note)
25
@def(add note)
blocks.back().notes.back() += line;
@end(add note)
26
@add(read states),
para
@end(read states)
27
@add(states without newlines)
@put(pre default states);
if (line[0] != ' ') {
if (state == RS::new_element || state == RS::para) {
@put(create para);
@put(add para);
state = RS::para;
break;
}
}
@end(states without newlines)
28
@def(create para)
if (state == RS::new_element) {
@put(create para block);
blocks.back().value.push_back(line);
}
@end(create para)
29
@def(create para block)
if (blocks.empty() || blocks.back().state != RS::para) {
blocks.push_back({ RS::para, {}, {}, 0 });
}
@end(create para block)
30
@def(add para)
if (state == RS::para) {
blocks.back().value.back() += " " + line;
}

@end(add para)
31
@add(read states),
img
@end(read states)
32
@def(can have notes) ||
state == RS::img
@end(can have notes)
33
@def(pre default states)
if (line[0] == '!') {
if (state == RS::new_element || state == RS::img) {
@put(create img);
@put(add img);
state = RS::img;
break;
}
}
@end(pre default states)
34
@def(create img)
if (state == RS::new_element) {
@put(create img block);
}
@end(create img)
35
@def(create img block)
if (blocks.empty() || blocks.back().state != RS::img ||
blocks.back().notes.size()
) {
blocks.push_back({ RS::img, {}, {}, 0 });
}
@end(create img block)
36
@def(add img)
if (line.size() < 3 || line[1] != '(' || line[line.size() - 1] != ')') {
std::cerr << "wrong line " << line << "\n";
}
blocks.back().value.push_back(line.substr(2, line.size() - 3));
@end(add img)