ultimatepp/tutorial/CoreTutorial/Tutorial.cpp

222 lines
5 KiB
C++

#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<String>& 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<String>& 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<String, Vector<Tuple<int, String>>> 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<String> 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<String> code;
while(i < src.GetCount()) {
String block;
while(i < src.GetCount() && TrimLeft(src[i]).StartsWith("///")) {
FlushCode(code);
Vector<String> 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();
}