Changeset 965


Ignore:
Timestamp:
06/27/20 23:14:01 (2 weeks ago)
Author:
Maciej Komosinski
Message:

Added a function to print genotypes in the LaTeX format, preserving colors and styles

Location:
cpp/frams/genetics
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/genman.cpp

    r955 r965  
    8686static ParamEntry GMparam_tab[] =
    8787{
    88         { "Genetics", 1, 10, "GenMan", },
     88        { "Genetics", 1, 11, "GenMan", },
    8989        { "gen_hist", 0, PARAM_DONTSAVE, "Remember history of genetic operations", "d 0 1 0", FIELD(history), "Required for phylogenetic analysis", },
    9090        { "gen_hilite", 0, 0, "Use syntax highlighting", "d 0 1 1", FIELD(hilite), "Use colors for genes?\n(slows down viewing/editing of huge genotypes)", },
     
    9292        { "operReport", 0, PARAM_DONTSAVE, "Operators report", "p()", PROCEDURE(p_report), "Show available genetic operators", },
    9393        { "toHTML", 0, PARAM_DONTSAVE, "HTMLize a genotype", "p s(s)", PROCEDURE(p_htmlize), "returns genotype expressed as colored HTML", },
    94         { "toHTMLshort", 0, PARAM_DONTSAVE, "HTMLize a genotype, shorten if needed", "p s(s)", PROCEDURE(p_htmlizeshort), "returns genotype (abbreviated if needed) expressed as colored HTML", },
     94        { "toHTMLshort", 0, PARAM_DONTSAVE, "HTMLize a genotype, shorten if needed", "p s(s)", PROCEDURE(p_htmlizeshort), "returns genotype (abbreviated if needed) in colored HTML format", },
     95        { "toLaTeX", 0, PARAM_DONTSAVE, "LaTeXize a genotype", "p s(s)", PROCEDURE(p_latexize), "returns genotype in colored LaTeX format", },
    9596        { "validate", 0, PARAM_DONTSAVE | PARAM_USERHIDDEN, "Validate", "p oGeno(oGeno)", PROCEDURE(p_validate), "returns validated (if possible) Geno object from supplied Geno", },
    9697        { "mutate", 0, PARAM_DONTSAVE | PARAM_USERHIDDEN, "Mutate", "p oGeno(oGeno)", PROCEDURE(p_mutate), "returns mutated Geno object from supplied Geno", },
     
    523524}
    524525
     526string GenMan::LaTeXize(const char *g)
     527{
     528        char buf[50];
     529        int len = strlen(g);
     530        int chars = 0, lines = 0; //currently not used
     531        uint32_t *styletab = new uint32_t[len];
     532        getFullStyle(g, styletab);
     533        string latex = "\\usepackage{xcolor}\n% Using \\texttt{} may be beneficial for some genetic encodings, but then you may lose bold/italic.\n\\noindent \\sloppy";
     534        uint32_t prevstyle, prevcolor, style = 0, color = 0;
     535        for (int i = 0; i < len; i++)
     536        {
     537                if (g[i] == '\r') continue;
     538                if (g[i] == '\n') { latex += "\\\\\n"; lines++; continue; }
     539                chars++;
     540                prevstyle = style;
     541                prevcolor = color;
     542                style = GENGETSTYLE(styletab[i]);
     543                color = GENGETCOLOR(styletab[i]);
     544
     545                // Unfortunately, LaTeX (as opposed to HTML) uses the same closing tags "}" for color, bold, italic, underline - so they cannot intersect.
     546                // Therefore we have to "turn off" everything on every change of style or color, and then "turn on" (to avoid problems with e.g. red-bold-blue-unbold or bold-italic-unbold-unitalic).
     547                // This could be optimized by a more complex logic and tracking which color/style section starts and ends within another section.
     548
     549                if (((style & GENSTYLE_INVALID) != (prevstyle & GENSTYLE_INVALID))
     550                        ||
     551                        ((style & GENSTYLE_BOLD) != (prevstyle & GENSTYLE_BOLD))
     552                        ||
     553                        ((style & GENSTYLE_ITALIC) != (prevstyle & GENSTYLE_ITALIC))
     554                        ||
     555                        ((i == 0 || (color != prevcolor))))
     556                {
     557                        if (prevstyle & GENSTYLE_INVALID) latex += "}";
     558                        if (prevstyle & GENSTYLE_BOLD) latex += "}";
     559                        if (prevstyle & GENSTYLE_ITALIC) latex += "}";
     560                        if (i != 0) latex += "}"; //for color
     561                        if (style & GENSTYLE_INVALID) latex += "\\underline{";
     562                        if (style & GENSTYLE_BOLD) latex += "\\textbf{";
     563                        if (style & GENSTYLE_ITALIC) latex += "\\textit{";
     564                        sprintf(buf, "\\textcolor[rgb]{%.2g,%.2g,%.2g}{", GENGET_R(color) / 255.0, GENGET_G(color) / 255.0, GENGET_B(color) / 255.0); latex += buf;
     565                }
     566                if (g[i] == '<') latex += "$<$"; else if (g[i] == '>') latex += "$>$"; else
     567                        if (g[i] == '-') latex += "$-$"; else if (g[i] == '|') latex += "$|$"; else
     568                                if (g[i] == '$') latex += "\\$"; else if (g[i] == '%') latex += "\\%"; else latex += g[i];
     569                if ((i % 3) == 0 && g[i] == ' ') latex += "\n"; //for readability, insert some newlines into latex...
     570                if (i % 10 == 0) latex += "{\\hskip 0pt}"; // https://tex.stackexchange.com/questions/33526/automatic-line-breaking-of-long-lines-of-text
     571        }
     572        delete[] styletab;
     573        latex += "}"; //for color (it was used at least once)
     574        if (style & GENSTYLE_BOLD) latex += "}";
     575        if (style & GENSTYLE_ITALIC) latex += "}";
     576        latex += "\n";
     577        return latex;
     578}
     579
     580void GenMan::p_latexize(ExtValue *args, ExtValue *ret)
     581{
     582        ret->setString(LaTeXize(args->getString().c_str()).c_str());
     583}
     584
    525585Geno GenMan::getSimplest(const SString& format)
    526586{
  • cpp/frams/genetics/genman.h

    r955 r965  
    6060        GenoOperators* getOper_f(const SString& format);
    6161        string HTMLize(const char *g, bool shorten);
     62        string LaTeXize(const char *g);
    6263        int findOperFormatIndex(const SString& format);
    6364public:
     
    8081        PARAMPROCDEF(p_htmlize);
    8182        PARAMPROCDEF(p_htmlizeshort);
     83        PARAMPROCDEF(p_latexize);
    8284        PARAMPROCDEF(p_validate);
    8385        PARAMPROCDEF(p_mutate);
Note: See TracChangeset for help on using the changeset viewer.