#include #include enum { PLAIN=0, TITLE=1, ENUM=2, DECK=3 }; %%{ machine Parser; alphtype char; action mark { start = fpc; } action title { last = TITLE; } action plain { last = PLAIN; } action enum { last = ENUM; } action content { tk = input.substr(start - begin, fpc - start); if(last == TITLE) { title = tk; } else if(last == ENUM) { content += "° " + tk; content += "\n"; } else { content += input.substr(start - begin, fpc - start); content += "\n"; } last = PLAIN; } action meta { tk = input.substr(start - begin, fpc - start); if(last == DECK) { deck->config = json::parse(tk); std::cout << "META:" << deck->config << '\n'; } else { config = json::parse(tk); std::cout << "SLIDE META:" << config << '\n'; } } action image { std::string image = input.substr(start - begin, fpc - start); fmt::println("IMAGE image={}, start={}, length={}", image, start - begin, fpc - start); config["image"] = image; } action start { last = PLAIN; fmt::println("----- START"); } action start_slide { title.clear(); content.clear(); } action end_slide { deck->slides.emplace_back(title, content, config, deck->config); config.clear(); } eol = '\n'; start = '===' %start; end = '---' %end_slide; pound = '#' %title; asterisk = '*' %enum; bang = '!'; dash = '-' %enum; json = ('{'|'}'); other = ^(bang|pound|asterisk|eol|json) %plain; content = (any+ -- eol) >mark %content; image = bang '(' (any+) >mark %image ')' :>> eol; meta = ('{' ( any+ -- '}') '}') >mark %meta; title = pound space+ content :>> eol; enum = asterisk space+ content :>> eol; raw = (other (any+ -- eol)) >mark %content :>> eol; blank = space* >mark %content eol; slide = meta? blank* (title | enum | raw | blank | image)+ >start_slide :>> end eol; main := meta eol start eol (slide)+; }%% %% write data; bool Parser::parse(const std::string& input) { int cs = 0; const char *start = nullptr; const char *begin = input.data(); const char *p = input.data(); const char *pe = p + input.size(); const char *eof = p + input.size(); (void)eof; std::string tk; // need this so that @meta knows it's a deck config first last = DECK; %% write init; %% write exec; bool good = pe - p == 0; if(good) { finalize(); } else { error = true; std::cout << "!!!!!!!!!!!!!!!!!!!!!! error at:"; std::cout << p; } return good; }