#include "RichEdit/RichEdit.h" using namespace Upp; String out; int ch_major = 0; int ch_minor = 0; String qtf = "[ $$0,0#00000000000000000000000000000000:Default]" "[a83;*R6 $$1,3#31310162474203024125188417583966:caption]" "[b83;*6 $$2,3#07864147445237544204411237157677:title]" "[b42;a42 $$3,3#45413000475342174754091244180557:text]" "[l100;C@5*;1 $$4,4#20902679421464641399138805415013:code]" "[l100;*C$7;1 $$5,5#07531550463529505371228428965313:log]" "[H6;b73;*7 $$6,3#07864147445237544204111237153677:section]" ; #ifdef OUT #undef OUT #endif #define OUT(x) out << x << '\n'; String toc; void Section(const String& title) { String lbl = AsString(++ch_major); String text = String().Cat() << lbl << "." << ' ' + TrimBoth(title); lbl = "Chapter_" + lbl; qtf << "[s6;:" << lbl << ": " << text << "&]"; ch_minor = 0; toc << "&[A3^#" << lbl << "^ " << text << "]&"; } void FlushDoc(String& docblock) { docblock = TrimBoth(docblock); if(docblock.GetCount() == 0) return; OUT("============= DOC"); OUT(docblock); bool title = false; String style = "[s3;"; String lbl; if(docblock.StartsWith(".")) { docblock = AsString(ch_major) + "." + AsString(++ch_minor) + ' ' + TrimBoth(docblock.Mid(1)); style = ch_minor == 1 ? "[s2;" : "[s2;H4"; lbl = "Section_" + AsString(ch_major) + "_" + AsString(ch_minor); style << ":" << lbl << ":"; title = true; } qtf << style << " "; const char *s = docblock; String plain; while(*s) if((s == ~docblock || findarg(s[-1], '(', ' ', '\'', '\"') >= 0) && findarg(s[0], '*', '%', '_', '`', '^') >= 0 && s[1] && s[1] != ' ') { int c = *s++; const char *b = s; const char *dc = NULL; while(*s && *s != c) { if(*s == ':') dc = s; s++; } if(c == '^') { qtf << "[^"; if(dc) { qtf.Cat(b, dc); b = dc + 1; } else qtf.Cat(b, s); qtf << "^ "; } else qtf << decode(c, '*', "[* ", '%', "[/ ", '_', "[_ ", '`', title ? "[C@5 " : "[C@5* ", ""); while(b < s) { plain << '`' << *b; qtf << '`' << *b++; } qtf << "]"; if(*s) s++; } else { plain << '`' << *s; qtf << '`' << *s++; } qtf << "&]"; if(lbl.GetCount()) toc << "___[A2^#" << lbl << "^ " << plain << "]&"; docblock.Clear(); } void FlushLog(Vector& log) { if(log.GetCount() == 0) return; OUT("============ LOG"); OUT(Join(log, "\r\n")); qtf << "[s5; \1" << Join(log, "\n") << "\1&]&"; log.Clear(); } void FlushCode(Vector& code) { while(code.GetCount() && TrimBoth(code[0]).GetCount() == 0) code.Remove(0); while(code.GetCount() && TrimBoth(code.Top()).GetCount() == 0) code.Drop(); bool tabs = true; for(auto l : code) if(l.GetCount() && *l != '\t') { tabs = false; break; } if(tabs) for(auto& l : code) if(l.GetCount()) l.Remove(0); if(code.GetCount() == 0) return; OUT("============= CODE"); OUT(Join(code, "\r\n")); qtf << "&[s4; \1" << Join(code, "\n") << "\1&]&"; code.Clear(); } void MakeTutorial() { String log = LoadFile(GetStdLogPath()); StringStream ss(log); VectorMap>> logline; String path; int line; while(!ss.IsEof()) { String ln = ss.GetLine(); if(ln.StartsWith("-=>")) { SplitTo(ln.Mid(4), '@', path, ln); line = atoi(ln) - 1; } else if(ln.StartsWith("=-=")) logline.Add(String()).Add(MakeTuple(0, ln.Mid(4))); else if(path.GetCount()) logline.GetAdd(path).Add(MakeTuple(line, ln)); } for(auto&& f : ~logline) { if(IsNull(f.key)) { Section(f.value[0].b); continue; } Vector src = Split(Filter(LoadFile(f.key), [] (int c) { return c == '\r' ? 0 : c; }), '\n', false); int i = 0; int logi = 0; bool wasdoc = false; Vector code; while(i < src.GetCount()) { String block; while(i < src.GetCount() && TrimLeft(src[i]).StartsWith("///")) { FlushCode(code); Vector logblock; while(logi < f.value.GetCount() && f.value[logi].a <= i) logblock.Add(f.value[logi++].b); FlushLog(logblock); String line = src[i++]; int q = line.FindAfter("///"); if(TrimRight(line).GetCount() > q) { if(block.GetCount()) block << ' '; block << TrimBoth(line.Mid(q)); } else FlushDoc(block); wasdoc = true; } FlushDoc(block); while(i < src.GetCount() && !TrimLeft(src[i]).StartsWith("///")) { String tl = TrimLeft(src[i]); if(!tl.StartsWith("#if") && !tl.StartsWith("#end")) code.Add(src[i]); i++; } DUMPC(code); if(!wasdoc) code.Clear(); } } LOG("--------------------------------------------"); LOG(out); LOG("--------------------------------------------"); LOG(qtf); LOG("--------------------------------------------"); LOG(toc); RichEditWithToolBar edit; edit.SetReadOnly(); edit <<= toc + qtf; TopWindow win; win.Add(edit.SizePos()); win.Run(); }