/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "bmhParser.h"
#include "includeParser.h"
#include "mdOut.h"

#include "SkOSFile.h"
#include "SkOSPath.h"
#include <map>

class SubtopicKeys {
public:
    static constexpr const char* kClasses = "Classes";
    static constexpr const char* kConstants = "Constants";
    static constexpr const char* kConstructors = "Constructors";
    static constexpr const char* kDefines = "Defines";
    static constexpr const char* kMemberFunctions = "Member_Functions";
    static constexpr const char* kMembers = "Members";
    static constexpr const char* kOperators = "Operators";
    static constexpr const char* kOverview = "Overview";
    static constexpr const char* kRelatedFunctions = "Related_Functions";
    static constexpr const char* kStructs = "Structs";
    static constexpr const char* kTypedefs = "Typedefs";

    static const char* kGeneratedSubtopics[];
};

const char* SubtopicKeys::kGeneratedSubtopics[] = {
    kConstants, kDefines, kTypedefs, kMembers, kClasses, kStructs, kConstructors,
    kOperators, kMemberFunctions, kRelatedFunctions
};

const char* kConstTableStyle =
"<style>"                                                                                      "\n"
    ".td_const td, th { border: 2px solid #dddddd; text-align: left; padding: 8px; }"          "\n"
    ".tr_const tr:nth-child(even) { background-color: #f0f0f0; }"                              "\n"
    ".td2_const td:first-child + td { text-align: center; }"                                   "\n"
"</style>"                                                                                     "\n";

const char* kTableDeclaration = "<table style='border-collapse: collapse; width: 62.5em'>";

#define kTD_Base         "border: 2px solid #dddddd; padding: 8px; "
#define kTH_Left         "<th style='text-align: left; "   kTD_Base "'>"
#define kTH_Center       "<th style='text-align: center; " kTD_Base "'>"

string kTD_Left    = "    <td style='text-align: left; "   kTD_Base "'>";
string kTD_Center  = "    <td style='text-align: center; " kTD_Base "'>";
string kTR_Dark    =   "  <tr style='background-color: #f0f0f0; '>";

const char* kAllConstTableHeader =  "  <tr>" kTH_Left   "Const</th>"                            "\n"
                                             kTH_Center "Value</th>"                            "\n"
                                             kTH_Left   "Description</th>" "</tr>";
const char* kSubConstTableHeader =  "  <tr>" kTH_Left   "Const</th>"                            "\n"
                                             kTH_Center "Value</th>"                            "\n"
                                             kTH_Left   "Details</th>"                          "\n"
                                             kTH_Left   "Description</th>" "</tr>";
const char* kAllMemberTableHeader = "  <tr>" kTH_Left   "Type</th>"                             "\n"
                                             kTH_Left   "Member</th>"                           "\n"
                                             kTH_Left   "Description</th>" "</tr>";
const char* kSubMemberTableHeader = "  <tr>" kTH_Left   "Type</th>"                             "\n"
                                             kTH_Left   "Member</th>"                           "\n"
                                             kTH_Left   "Details</th>"                          "\n"
                                             kTH_Left   "Description</th>" "</tr>";
const char* kTopicsTableHeader    = "  <tr>" kTH_Left   "Topic</th>"                            "\n"
                                             kTH_Left   "Description</th>" "</tr>";

string MdOut::anchorDef(string str, string name) {
    if (fValidate) {
        string htmlName = ParserCommon::HtmlFileName(fFileName);
        vector<AnchorDef>& allDefs = fAllAnchorDefs[htmlName];
        if (!std::any_of(allDefs.begin(), allDefs.end(),
                [str](AnchorDef compare) { return compare.fDef == str; } )) {
            MarkType markType = fLastDef->fMarkType;
            if (MarkType::kMethod == markType && fLastDef->fClone) {
                SkASSERT(0);  // incomplete
            }
            allDefs.push_back( { str, markType } );
        }
    }
    return "<a name='" + str + "'>" + name + "</a>";
}

string MdOut::anchorRef(string ref, string name) {
    if (fValidate) {
        string htmlName;
        size_t hashIndex = ref.find('#');
        if (string::npos != hashIndex && "https://" != ref.substr(0, 8)) {
            if (0 == hashIndex) {
                htmlName = ParserCommon::HtmlFileName(fFileName);
            } else {
                htmlName = ref.substr(0, hashIndex);
            }
            vector<string>& allRefs = fAllAnchorRefs[htmlName];
            string refPart = ref.substr(hashIndex + 1);
            if (allRefs.end() == std::find(allRefs.begin(), allRefs.end(), refPart)) {
                allRefs.push_back(refPart);
            }
        }
    }
    SkASSERT(string::npos != ref.find('#') || string::npos != ref.find("https://"));
    return "<a href='" + ref + "'>" + name + "</a>";
}

string MdOut::anchorLocalRef(string ref, string name) {
    return this->anchorRef("#" + ref, name);
}

string MdOut::tableDataCodeRef(string ref, string name) {
    return kTD_Left + this->anchorRef(ref, "<code>" + name + "</code>") + "</td>";
}

string MdOut::tableDataCodeLocalRef(string ref, string name) {
    return this->tableDataCodeRef("#" + ref, name);
}

string MdOut::tableDataCodeLocalRef(string name) {
    return this->tableDataCodeLocalRef(name, name);
}

string MdOut::tableDataCodeRef(const Definition* ref) {
    return this->tableDataCodeLocalRef(ref->fFiddle, ref->fName);
}

string MdOut::tableDataCodeDef(string def, string name) {
    return kTD_Left + this->anchorDef(def, "<code>" + name + "</code>") + "</td>";
}

string MdOut::tableDataCodeDef(const Definition* def) {
    return this->tableDataCodeDef(def->fFiddle, def->fName);
}

static string table_data_const(const Definition* def, const char** textStartPtr) {
    TextParser parser(def);
    SkAssertResult(parser.skipToEndBracket('\n'));
    string constant = string(def->fContentStart, (int) (parser.fChar - def->fContentStart));
    if (textStartPtr) {
        *textStartPtr = parser.fChar;
    }
    return kTD_Center + constant + "</td>";
}

static string out_table_data_description_start() {
    return kTD_Left;
}

static string out_table_data_description(string str) {
    return kTD_Left + str + "</td>";
}

static string out_table_data_description(const Definition* def) {
    return out_table_data_description(string(def->fContentStart,
            (int) (def->fContentEnd - def->fContentStart)));
}

static string out_table_data_details(string details) {
    return kTD_Left + details + "</td>";
}

#undef kConstTDBase
#undef kTH_Center

static string preformat(string orig) {
    string result;
    for (auto c : orig) {
        if ('<' == c) {
          result += "&lt;";
        } else if ('>' == c) {
          result += "&gt;";
        } else {
            result += c;
        }
    }
    return result;
}

// from https://stackoverflow.com/questions/3418231/replace-part-of-a-string-with-another-string
void replace_all(string& str, const string& from, const string& to) {
    SkASSERT(!from.empty());
    size_t start_pos = 0;
    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
}

// detail strings are preceded by an example comment to check readability
void MdOut::addPopulators() {
    auto populator = [this](string key, string singular, string plural, string oneLiner,
            string details) -> void {
        fPopulators[key].fSingular = singular;
        fPopulators[key].fPlural = plural;
        fPopulators[key].fOneLiner = oneLiner;
        fPopulators[key].fDetails = details;
    };
    populator(SubtopicKeys::kClasses, "Class", "Class Declarations",
            "embedded class members",
            /* SkImageInfo */ "uses <code>class</code> to declare the public data structures"
                              " and interfaces.");
    populator(SubtopicKeys::kConstants, "Constant", "Constants",
            "enum and enum class, and their const values",
            /* SkImageInfo */ "defines related constants are using <code>enum</code>,"
                              " <code>enum class</code>,  <code>#define</code>,"
                              " <code>const</code>, and <code>constexpr</code>.");
    populator(SubtopicKeys::kConstructors, "Constructor", "Constructors",
            "functions that construct",
            /* SkImageInfo */ "can be constructed or initialized by these functions,"
                              " including <code>class</code> constructors.");
    populator(SubtopicKeys::kDefines, "Define", "Defines",
            "preprocessor definitions of functions, values",
            /* SkImageInfo */ "uses preprocessor definitions to inline code and constants,"
                              " and to abstract platform-specific functionality.");
    populator(SubtopicKeys::kMemberFunctions, "Member Function", "Member Functions",
            "static and local functions",
            /* SkImageInfo */ "uses member functions to read and modify structure properties.");
    populator(SubtopicKeys::kMembers, "Member", "Members",
            "member values",
            /* SkImageInfo */ "contains members that may be read and written directly without using"
                              " a member function.");
    populator(SubtopicKeys::kOperators, "Operator", "Operators",
            "operator overloading functions",
            /* SkImageInfo */ "defines member functions with arithmetic equivalents.");
    populator(SubtopicKeys::kRelatedFunctions, "Related Function", "Related Functions",
            "similar functions grouped together",
            /* SkImageInfo */ "defines related functions that share a topic.");
    populator(SubtopicKeys::kStructs, "Struct", "Struct Declarations",
            "embedded struct members",
            /* SkImageInfo */ "uses <code>struct</code> to declare the public data"
                              " structures and interfaces.");
    populator(SubtopicKeys::kTypedefs, "Typedef", "Typedef Declarations",
            "types defined in terms of other types",
            /* SkImageInfo */ "uses <code>typedef</code> to define a data type.");
}

Definition* MdOut::checkParentsForMatch(Definition* test, string ref) const {
    bool isSubtopic = MarkType::kSubtopic == test->fMarkType
            || MarkType::kTopic == test->fMarkType;
    do {
        if (!test->isRoot()) {
            continue;
        }
        bool localTopic = MarkType::kSubtopic == test->fMarkType
                || MarkType::kTopic == test->fMarkType;
        if (localTopic != isSubtopic) {
            continue;
        }
        string prefix(isSubtopic ? "_" : "::");
        RootDefinition* root = test->asRoot();
        string prefixed = root->fName + prefix + ref;
        if (Definition* def = root->find(prefixed, RootDefinition::AllowParens::kYes)) {
            return def;
        }
    } while ((test = test->fParent));
    return nullptr;
}

struct BraceState {
    BraceState(RootDefinition* root, string name, const char* ch, KeyWord last, KeyWord keyWord,
            int count)
        : fRoot(root)
        , fName(name)
        , fChar(ch)
        , fLastKey(last)
        , fKeyWord(keyWord)
        , fBraceCount(count) {
    }

    RootDefinition* fRoot;
    string fName;
    const char* fChar;
    KeyWord fLastKey;
    KeyWord fKeyWord;
    int fBraceCount;
};

bool MdOut::DefinedState::hasWordSpace(string wordSpace) const {
    if (!fNames->fRefMap.size()) {
        return false;
    }
    for (const NameMap* names = fNames; names; names = names->fParent) {
        if (names->fRefMap.end() != names->fRefMap.find(wordSpace)) {
            return true;
        }
    }
    return false;
}

bool MdOut::DefinedState::phraseContinues(string phrase, string* priorWord,
        string* priorLink) const {
    for (const NameMap* names = fNames; names; names = names->fParent) {
        if (names->fRefMap.end() != names->fRefMap.find(phrase + ' ')) {
            *priorWord = phrase;
            return true;
        }
        if (names->fRefMap.end() != names->fRefMap.find(phrase)) {
            *priorWord = phrase;
            auto linkIter = names->fLinkMap.find(phrase);
            *priorLink = names->fLinkMap.end() == linkIter ? "" : linkIter->second;
            return true;
        }
    }
    return false;
}

void MdOut::DefinedState::setLink() {
    fLink = "";
    fPriorDef = nullptr;
    // TODO: operators have complicated parsing possibilities; handle the easiest for now
    // TODO: constructors also have complicated parsing possibilities; handle the easiest
    bool isOperator = "operator" == fPriorWord;
    if (((fRoot && fRoot->isStructOrClass() && fRoot->fName == fPriorWord) || isOperator)
            && '(' == fSeparator.back()) {
        SkASSERT(fSubtopic);
        TextParser parser(fSubtopic->fFileName, fSeparatorStart, fRefEnd, fSubtopic->fLineCount);
        parser.skipToEndBracket('(');
        const char* parenStart = parser.fChar;
        parser.skipToBalancedEndBracket('(', ')');
        (void) parser.skipExact(" const");
        string methodName = fPriorWord + fSeparator
                + string(parenStart + 1, parser.fChar - parenStart - 1);
        string testLink;
        if (this->findLink(methodName, &testLink, false)) {
            // consume only if we find it
            if (isOperator) {
                fPriorWord += fSeparator.substr(0, fSeparator.length() - 1);  // strip paren
                fPriorSeparator = "(";
            }
            fWord = "";
            fPriorLink = testLink;
            fEnd = parenStart + 1;
            return;
        }
    }
    // look to see if text following ref is method qualifier
    else if ((Resolvable::kYes == fResolvable || Resolvable::kClone == fResolvable)
            && "(" == fSeparator && "" != fPriorLink) {
        TextParser parser(fLastDef->fFileName, fSeparatorStart, fRefEnd, fLastDef->fLineCount);
        parser.skipToBalancedEndBracket('(', ')');
        string fullMethod = fPriorWord + string(parser.fStart, parser.fChar - parser.fStart);
        string trimmed = trim_inline_spaces(fullMethod);
        string testLink;
        if (findLink(trimmed, &testLink, false)) {
            fMethodName = fullMethod;
            fWord = trimmed;
            fLink = testLink;
            fEnd = parser.fChar;
            this->backup();
            return;
        }
    }
    if ("." == fSeparator || "->" == fSeparator || "()." == fSeparator || "()->" == fSeparator) {
        bool foundField = fWord.length() >= 2 && (('f' == fWord[0] && isupper(fWord[1]))
                || "()" == fWord.substr(fWord.length() - 2)
                || (fEnd + 2 <= fRefEnd && "()" == string(fEnd, 2)));
        if (foundField) {
            if (fMethod && fNames->fRefMap.end() != fNames->fRefMap.find(fPriorWord)) {
        // find prior fWord's type in fMethod
                TextParser parser(fMethod);
                SkAssertResult(parser.containsWord(fPriorWord.c_str(), parser.fEnd,
                        &parser.fChar));
        // look up class or struct; trival lookup only class/struct [& * const]
                while (parser.back(" ") || parser.back("&") || parser.back("*")
                        || parser.back("const"))
                    ;
                const char* structEnd = parser.fChar;
                parser.backupWord();
                if (structEnd != parser.fChar) {
                    string structName(parser.fChar, structEnd - parser.fChar);
                    if ("SkVector" == structName) {
                        // TODO: populate global refmap with typedefs as well as structs
                        structName = "SkPoint";
                    } else if ("SkIVector" == structName) {
                        structName = "SkIPoint";
                    }
                    structName += "::" + fWord;
        // look for fWord as member of class or struct
                    auto defIter = fGlobals->fRefMap.find(structName);
                    if (fGlobals->fRefMap.end() == defIter) {
                        structName += "()";
                        defIter = fGlobals->fRefMap.find(structName);
                    }
                    if (fGlobals->fRefMap.end() != defIter) {
                        // example: dstInfo.width()
                        auto structIter = fGlobals->fLinkMap.find(structName);
                        SkASSERT(fGlobals->fLinkMap.end() != structIter);
                        fLink = structIter->second;
                        fPriorDef = defIter->second;
                        return;
                    } else {
                        SkDebugf("probably missing struct or class member in bmh: ");
                        SkDebugf("%s\n", structName.c_str());
                    }
                }
            }
            auto& parentRefMap = fNames->fParent->fRefMap;
            auto priorIter = parentRefMap.find(fPriorWord);
            if (parentRefMap.end() == priorIter) {
                priorIter = parentRefMap.find(fPriorWord + "()");
            }
            if (parentRefMap.end() != priorIter) {
                Definition* priorDef = priorIter->second;
                if (priorDef) {
                    TextParser parser(priorDef->fFileName, priorDef->fStart,
                            priorDef->fContentStart, priorDef->fLineCount);
                    parser.skipExact("#Method ");
                    parser.skipSpace();
                    parser.skipExact("const ");  // optional
                    parser.skipSpace();
                    const char* start = parser.fChar;
                    parser.skipToNonAlphaNum();
                    string structName(start, parser.fChar - start);
                    structName += "::" + fWord;
                    auto defIter = fGlobals->fRefMap.find(structName);
                    if (fGlobals->fRefMap.end() != defIter) {
                        // example: imageInfo().width()
                        auto globalIter = fGlobals->fLinkMap.find(structName);
                        SkASSERT(fGlobals->fLinkMap.end() != globalIter);
                        fLink = globalIter->second;
                        fPriorDef = defIter->second;
                        return;
                    }
                }
            }
        } else {
            string fullRef = fPriorWord + fSeparator + fWord;
            if (this->findLink(fullRef, &fLink, false)) {
                return;
            }
            if (Resolvable::kCode != fResolvable) {
                SkDebugf("probably missing () after function:");
                const char* debugStart = fEnd - 20 < fRefStart ? fRefStart : fEnd - 20;
                const char* debugEnd = fEnd + 10 > fRefEnd ? fRefEnd : fEnd + 10;
                SkDebugf("%.*s\n", debugEnd - debugStart, debugStart);
                SkDebugf(""); // convenient place to set a breakpoint
            }
        }
    }
    // example: SkCanvas::restoreToCount
    if ("::" == fSeparator) {
        string fullRef = fPriorWord + "::" + fWord;
        if (this->findLink(fullRef, &fLink, fAddParens)) {
            return;
        }
    }
    // look in parent fNames and above for match
    if (fNames) {
        if (this->findLink(fWord, &fLink, (Resolvable::kClone == fResolvable && fAddParens)
                || (Resolvable::kCode == fResolvable && '(' == fEnd[0]))) {
            return;
        }
    }
    // example : sqrt as in "sqrt(x * x + y * y)"
    // example : erase in seeAlso
    if (Resolvable::kClone == fResolvable || (fEnd + 1 < fRefEnd && '(' == fEnd[0])) {
        if ((fAddParens || '~' == fWord.front()) && this->findLink(fWord + "()", &fLink, false)) {
            return;
        }
    }
    // example: Color_Type
    if (this->findLink(fWord, &fLink, fBmhParser->fAliasMap)) {
        return;
    }
    if (Resolvable::kInclude != fResolvable && string::npos != fWord.find('_')) {
        // example: Blend_Mode
        if (this->findLink(fWord, &fLink, fBmhParser->fTopicMap)) {
            return;
        }
        if (fSubtopic) {
            // example: Fake_Bold
            if (fSubtopic->fName == fWord) {
                fLink = '#' + fSubtopic->fFiddle;
                fPriorDef = fSubtopic;
                return;
            }
            const Definition* rootTopic = fSubtopic->subtopicParent();
            if (rootTopic) {
                if (rootTopic->fFiddle == fWord) {
                    fLink = '#' + rootTopic->fFiddle;
                    fPriorDef = rootTopic;
                    return;
                }
                string globName = rootTopic->fFiddle + '_' + fWord;
                if (this->findLink(globName, &fLink, fBmhParser->fTopicMap)) {
                    return;
                }
            }
        }
        if (fRoot) {
            string test = fRoot->fName + "::" + fWord;
            auto rootIter = fRoot->fLeaves.find(test);
            // example: restoreToCount in subtopic State_Stack
            if (fRoot->fLeaves.end() != rootIter) {
                fLink = '#' + rootIter->second.fFiddle;
                fPriorDef = &rootIter->second;
                return;
            }
        }
    }
    if (isupper(fWord[0]) && string::npos != fWord.find('_')) {
        const Definition* topical = fSubtopic;
        do {
            string subtopic = topical->fName + '_' + fWord;
            // example: Stroke_Width
            if (this->findLink(subtopic, &fLink, fBmhParser->fTopicMap)) {
                return;
            }
        } while ((topical = topical->topicParent()));
    }
    // treat hex constants as known words
    if (fSeparator.size() > 0 && '0' == fSeparator.back() && 'x' == fWord[0]) {
        bool allHex = true;
        for (size_t index = 1; index < fWord.size(); ++index) {
            char c = fWord[index];
            if (('0' > c || '9' < c) && ('A' > c || 'F' < c)) {
                allHex = false;
                break;
            }
        }
        if (allHex) {
            return;
        }
    }
    // treat floating constants as known words
    if ("e" == fWord) {
        if (std::all_of(fSeparator.begin(), fSeparator.end(), [](char c) {
            return isdigit(c) || '.' == c || '-' == c || ' ' >= c;
        })) {
            return;
        }
    }
    // stop short of parsing example; just look to see if it contains fWord in description
    if (fLastDef && MarkType::kDescription == fLastDef->fMarkType) {
        Definition* example = fLastDef->fParent;
        if (MarkType::kExample == example->fMarkType) {
            // example text is blocked by last child before std out, if it exists
            const char* exStart = example->fChildren.back()->fContentEnd;
            const char* exEnd = example->fContentEnd;
            if (MarkType::kStdOut == example->fChildren.back()->fMarkType) {
                exStart = example->fChildren[example->fChildren.size() - 2]->fContentEnd;
                exEnd = example->fChildren.back()->fContentStart;
            }
            // maybe need a general function that searches block text excluding children
            TextParser exParse(example->fFileName, exStart, exEnd, example->fLineCount);
            if (exParse.containsWord(fWord.c_str(), exParse.fEnd, nullptr)) {
                return;
            }
        }
    }
    // example: (x1, y1) after arcTo(SkScalar x1, ...
    if (Resolvable::kYes == fResolvable && "" != fSeparator
            && ('(' == fSeparator.back() || ',' == fSeparator[0])
            && string::npos != fMethodName.find(fWord)) {
        return;
    }
    // example: <sup>  (skip html)
    if (Resolvable::kYes == fResolvable && fEnd + 1 < fRefEnd && '>' == fEnd[0] && "" != fSeparator
            && ('<' == fSeparator.back() || (fSeparator.size() >= 2
            && "</" == fSeparator.substr(fSeparator.size() - 2)))) {
        return;
    }
    bool paramName = islower(fWord[0]) && (Resolvable::kCode == fResolvable
            || Resolvable::kClone == fResolvable);
    // TODO: can probably resolve formulae, but need a way for formula to define new reference
    // for example: Given: #Formula # Sa ## as source Alpha,
    // for example: where #Formula # m = Da > 0 ? Dc / Da : 0 ##;
    if (!fInProgress && Resolvable::kSimple != fResolvable
            && !paramName && Resolvable::kFormula != fResolvable) {
        // example: Coons as in "Coons patch"
        bool withSpace = fEnd + 1 < fRefEnd && ' ' == fEnd[0]
                && fGlobals->fRefMap.end() != fGlobals->fRefMap.find(fWord + ' ');
        if (!withSpace && (Resolvable::kInclude == fResolvable ? !fInMatrix :
                '"' != fPriorSeparator.back() || '"' != fSeparator.back())) {
            SkDebugf("word %s not found\n", fWord.c_str());
            fBmhParser->fGlobalNames.fRefMap[fWord] = nullptr;
        }
    }
}


string MdOut::addReferences(const char* refStart, const char* refEnd, Resolvable resolvable) {
    DefinedState s(*this, refStart, refEnd, resolvable);
    string result;
    const char* start = refStart;
    do {
        s.fSeparatorStart = start;
        start = s.skipWhiteSpace();
        s.skipParens();
        string separator = s.nextSeparator(start);
        if (fDebugWriteCodeBlock) {
            SkDebugf("%s", separator.c_str());
        }
        result += separator;
        if (s.findEnd(start)) {
            break;
        }
        s.fWord = string(start, s.fEnd - start);
        if ("TODO" == s.fWord) {
            while('\n' != *s.fEnd++)
                ;
            start = s.fEnd;
            continue;
        }
        s.setLower();
        if (s.setPriorSpaceWord(&start)) {
            continue;
        }
        s.setLink();
        string link = "" == s.fPriorLink ? s.fPriorWord :
                this->anchorRef(s.fPriorLink, s.fPriorWord);
        if (fDebugWriteCodeBlock) {
            SkDebugf("%s", link.c_str());
        }
        result += link;
        start = s.nextWord();
    } while (true);
    string finalLink = "" == s.fPriorLink ? s.fPriorWord :
            this->anchorRef(s.fPriorLink, s.fPriorWord);
    if (fDebugWriteCodeBlock) {
        SkDebugf("%s", finalLink.c_str());
    }
    result += finalLink;
    if (fDebugWriteCodeBlock) {
        SkDebugf("%s", s.fPriorSeparator.c_str());
    }
    result += s.fPriorSeparator;
    return result;
}

bool MdOut::buildReferences(const char* docDir, const char* mdFileOrPath) {
    if (!sk_isdir(mdFileOrPath)) {
        SkDebugf("must pass directory %s\n", mdFileOrPath);
        SkDebugf("pass -i SkXXX.h to build references for a single include\n");
        return false;
    }
    fInProgress = true;
    SkOSFile::Iter it(docDir, ".bmh");
    for (SkString file; it.next(&file); ) {
        if (!fIncludeParser.references(file)) {
            continue;
        }
        SkString p = SkOSPath::Join(docDir, file.c_str());
        if (!this->buildRefFromFile(p.c_str(), mdFileOrPath)) {
            SkDebugf("failed to parse %s\n", p.c_str());
            return false;
        }
    }
    return true;
}

bool MdOut::buildStatus(const char* statusFile, const char* outDir) {
    StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
    StatusFilter filter;
    for (string file; iter.next(&file, &filter); ) {
        SkString p = SkOSPath::Join(iter.baseDir().c_str(), file.c_str());
        const char* hunk = p.c_str();
        fInProgress = StatusFilter::kInProgress == filter;
        if (!this->buildRefFromFile(hunk, outDir)) {
            SkDebugf("failed to parse %s\n", hunk);
            return false;
        }
    }
    return true;
}

bool MdOut::buildRefFromFile(const char* name, const char* outDir) {
    if (!SkStrEndsWith(name, ".bmh")) {
        return true;
    }
    if (SkStrEndsWith(name, "markup.bmh")) {  // don't look inside this for now
        return true;
    }
    if (SkStrEndsWith(name, "illustrations.bmh")) {  // don't look inside this for now
        return true;
    }
    if (SkStrEndsWith(name, "undocumented.bmh")) {  // don't look inside this for now
        return true;
    }
    fFileName = string(name);
    string filename(name);
    if (filename.substr(filename.length() - 4) == ".bmh") {
        filename = filename.substr(0, filename.length() - 4);
    }
    size_t start = filename.length();
    while (start > 0 && (isalnum(filename[start - 1]) || '_' == filename[start - 1])) {
        --start;
    }
    string match = filename.substr(start);
    string header = match;
    filename = match + ".md";
    match += ".bmh";
    fOut = nullptr;
    string fullName;

    vector<string> keys;
    keys.reserve(fBmhParser.fTopicMap.size());
    for (const auto& it : fBmhParser.fTopicMap) {
        keys.push_back(it.first);
    }
    std::sort(keys.begin(), keys.end());
    for (auto key : keys) {
        string s(key);
        auto topicDef = fBmhParser.fTopicMap.at(s);
        if (topicDef->fParent) {
            continue;
        }
        if (string::npos == topicDef->fFileName.rfind(match)) {
            continue;
        }
        if (!fOut) {
            fullName = outDir;
            if ('/' != fullName.back()) {
                fullName += '/';
            }
            fullName += filename;
            fOut = fopen(filename.c_str(), "wb");
            if (!fOut) {
                SkDebugf("could not open output file %s\n", fullName.c_str());
                return false;
            }
            if (false) {    // try inlining the style
                FPRINTF("%s", kConstTableStyle);
            }
            size_t underscorePos = header.find('_');
            if (string::npos != underscorePos) {
                header.replace(underscorePos, 1, " ");
            }
            SkASSERT(string::npos == header.find('_'));
            this->writeString(header);
            this->lfAlways(1);
            this->writeString("===");
            this->lfAlways(1);
        }
        const Definition* prior = nullptr;
        this->markTypeOut(topicDef, &prior);
    }
    if (fOut) {
        this->writePending();
        fclose(fOut);
        fflush(fOut);
        if (ParserCommon::WrittenFileDiffers(fullName, filename)) {
            ParserCommon::CopyToFile(fullName, filename);
            SkDebugf("wrote %s\n", fullName.c_str());
        } else {
            remove(filename.c_str());
        }
        fOut = nullptr;
    }
    return !fAddRefFailed;
}

static bool contains_referenced_child(const Definition* found, const vector<string>& refs) {
    for (auto child : found->fChildren) {
        if (refs.end() != std::find_if(refs.begin(), refs.end(),
                    [child](string def) { return child->fName == def; } )) {
            return true;
        }
        if (contains_referenced_child(child, refs)) {
            return true;
        }
    }
    return false;
}

void MdOut::checkAnchors() {
    int missing = 0;
    for (auto bmhFile : fAllAnchorRefs) {
        auto defIter = fAllAnchorDefs.find(bmhFile.first);
        SkASSERT(fAllAnchorDefs.end() != defIter);
        vector<AnchorDef>& allDefs = defIter->second;
        std::sort(allDefs.begin(), allDefs.end(),
                [](const AnchorDef& a, const AnchorDef& b) { return a.fDef < b.fDef; } );
        std::sort(bmhFile.second.begin(), bmhFile.second.end());
        auto allDefsIter = allDefs.begin();
        auto allRefsIter = bmhFile.second.begin();
        for (;;) {
            bool allDefsEnded = allDefsIter == allDefs.end();
            bool allRefsEnded = allRefsIter == bmhFile.second.end();
            if (allDefsEnded && allRefsEnded) {
                break;
            }
            if (allRefsEnded || (!allDefsEnded && allDefsIter->fDef < *allRefsIter)) {
                if (MarkType::kParam != allDefsIter->fMarkType) {
                    // If undocumented but parent or child is referred to: good enough for now
                    bool goodEnough = false;
                    if ("undocumented" == defIter->first) {
                        auto iter = fBmhParser.fTopicMap.find(allDefsIter->fDef);
                        if (fBmhParser.fTopicMap.end() != iter) {
                            const Definition* found = iter->second;
                            if (string::npos != found->fFileName.find("undocumented")) {
                                const Definition* parent = found;
                                while ((parent = parent->fParent)) {
                                    if (bmhFile.second.end() != std::find_if(bmhFile.second.begin(),
                                            bmhFile.second.end(),
                                            [parent](string def) {
                                            return parent->fName == def; } )) {
                                        goodEnough = true;
                                        break;
                                    }
                                }
                                if (!goodEnough) {
                                    goodEnough = contains_referenced_child(found, bmhFile.second);
                                }
                            }
                        }
                    }
                    if (!goodEnough) {
                        SkDebugf("missing ref %s %s\n", defIter->first.c_str(),
                                allDefsIter->fDef.c_str());
                        missing++;
                    }
                }
                allDefsIter++;
            } else if (allDefsEnded || (!allRefsEnded && allDefsIter->fDef > *allRefsIter)) {
                if (fBmhParser.fExternals.end() == std::find_if(fBmhParser.fExternals.begin(),
                        fBmhParser.fExternals.end(), [allRefsIter](const RootDefinition& root) {
                        return *allRefsIter != root.fName; } )) {
                    SkDebugf("missing def %s %s\n", bmhFile.first.c_str(), allRefsIter->c_str());
                    missing++;
                }
                allRefsIter++;
            } else {
                SkASSERT(!allDefsEnded);
                SkASSERT(!allRefsEnded);
                SkASSERT(allDefsIter->fDef == *allRefsIter);
                allDefsIter++;
                allRefsIter++;
            }
            if (missing >= 10) {
                missing = 0;
            }
        }
    }
}

bool MdOut::checkParamReturnBody(const Definition* def) {
    TextParser paramBody(def);
    const char* descriptionStart = paramBody.fChar;
    if (!islower(descriptionStart[0]) && !isdigit(descriptionStart[0])) {
        paramBody.skipToNonName();
        string ref = string(descriptionStart, paramBody.fChar - descriptionStart);
        if (!std::all_of(ref.begin(), ref.end(), [](char c) { return isupper(c); })
                && !this->isDefined(paramBody, Resolvable::kYes)) {
            string errorStr = MarkType::kReturn == def->fMarkType ? "return" : "param";
            errorStr += " description must start with lower case";
            paramBody.reportError(errorStr.c_str());
            fAddRefFailed = true;
            return false;
        }
    }
    if ('.' == paramBody.fEnd[-1]) {
        paramBody.reportError("make param description a phrase; should not end with period");
        fAddRefFailed = true;
        return false;
    }
    return true;
}

void MdOut::childrenOut(Definition* def, const char* start) {
    const char* end;
    fLineCount = def->fLineCount;
    if (MarkType::kEnumClass == def->fMarkType) {
        fEnumClass = def;
    }
    Resolvable resolvable = this->resolvable(def);
    const Definition* prior = nullptr;
    for (auto& child : def->fChildren) {
        if (MarkType::kPhraseParam == child->fMarkType) {
            continue;
        }
        end = child->fStart;
        if (Resolvable::kNo != resolvable) {
            if (def->isStructOrClass() || MarkType::kEnumClass == def->fMarkType) {
                fNames = &def->asRoot()->fNames;
            }
            this->resolveOut(start, end, resolvable);
        }
        this->markTypeOut(child, &prior);
        start = child->fTerminator;
    }
    if (Resolvable::kNo != resolvable) {
        end = def->fContentEnd;
        if (MarkType::kFormula == def->fMarkType && ' ' == start[0]) {
            this->writeSpace();
        }
        this->resolveOut(start, end, resolvable);
    }
    if (MarkType::kEnumClass == def->fMarkType) {
        fEnumClass = nullptr;
    }
}

// output header for subtopic for all consts: name, value, short descriptions (#Line)
// output link to in context #Const with moderate description
void MdOut::summaryOut(const Definition* def, MarkType markType, string name) {
    this->writePending();
    SkASSERT(TableState::kNone == fTableState);
    this->mdHeaderOut(3);
    FPRINTF("%s", name.c_str());
    this->lfAlways(2);
    FPRINTF("%s", kTableDeclaration);  // <table> with style info
    this->lfAlways(1);
    FPRINTF("%s", MarkType::kConst == markType ? kAllConstTableHeader : kAllMemberTableHeader);
    this->lfAlways(1);
    bool odd = true;
    for (auto child : def->fChildren) {
        if (markType != child->fMarkType) {
            continue;
        }
        auto oneLiner = std::find_if(child->fChildren.begin(), child->fChildren.end(),
                [](const Definition* test){ return MarkType::kLine == test->fMarkType; } );
        if (child->fChildren.end() == oneLiner) {
            child->reportError<void>("missing #Line");
            continue;
        }
        FPRINTF("%s", odd ? kTR_Dark.c_str() : "  <tr>");
        this->lfAlways(1);
        if (MarkType::kConst == markType) {
            FPRINTF("%s", tableDataCodeRef(child).c_str());
            this->lfAlways(1);
            FPRINTF("%s", table_data_const(child, nullptr).c_str());
        } else {
            string memberType;
            string memberName = this->getMemberTypeName(child, &memberType);
            SkASSERT(MarkType::kMember == markType);
            FPRINTF("%s", out_table_data_description(memberType).c_str());
            this->lfAlways(1);
            FPRINTF("%s", tableDataCodeLocalRef(memberName).c_str());
        }
        this->lfAlways(1);
        FPRINTF("%s", out_table_data_description(*oneLiner).c_str());
        this->lfAlways(1);
        FPRINTF("%s", "  </tr>");
        this->lfAlways(1);
        odd = !odd;
    }
    FPRINTF("</table>");
    this->lfAlways(1);
}

Definition* MdOut::csParent() {
    if (!fRoot) {
        return nullptr;
    }
    Definition* csParent = fRoot->csParent();
    if (!csParent) {
        const Definition* topic = fRoot;
        while (topic && MarkType::kTopic != topic->fMarkType) {
            topic = topic->fParent;
        }
        for (auto child : topic->fChildren) {
            if (child->isStructOrClass() || MarkType::kTypedef == child->fMarkType) {
                csParent = child;
                break;
            }
        }
        SkASSERT(csParent || string::npos == fRoot->fFileName.find("Sk")
                || string::npos != fRoot->fFileName.find("SkBlendMode_Reference.bmh"));
    }
    return csParent;
}

bool MdOut::DefinedState::findLink(string word, string* linkPtr, bool addParens) {
    const NameMap* names = fNames;
    do {
        auto localIter = names->fRefMap.find(word);
        if (names->fRefMap.end() != localIter) {
            if ((fPriorDef = localIter->second)) {
                auto linkIter = names->fLinkMap.find(word);
                SkAssertResult(names->fLinkMap.end() != linkIter);
                *linkPtr = linkIter->second;
            }
            return true;
        }
        if (!names->fParent && isupper(word[0])) {
            SkASSERT(names == &fBmhParser->fGlobalNames);
            string lower = (char) tolower(word[0]) + word.substr(1);
            auto globalIter = names->fRefMap.find(lower);
            if (names->fRefMap.end() != globalIter) {
                if ((fPriorDef = globalIter->second)) {
                    auto lowerIter = names->fLinkMap.find(lower);
                    SkAssertResult(names->fLinkMap.end() != lowerIter);
                    *linkPtr = lowerIter->second;
                }
                return true;
            }
        }
        if (addParens) {
            string parenWord = word + "()";
            auto paramIter = names->fRefMap.find(parenWord);
            if (names->fRefMap.end() != paramIter) {
                if ((fPriorDef = paramIter->second)) {
                    auto parenIter = names->fLinkMap.find(parenWord);
                    SkAssertResult(names->fLinkMap.end() != parenIter);
                    *linkPtr = parenIter->second;
                }
                return true;
            }
        }
    } while ((names = names->fParent));
    return false;
}

bool MdOut::DefinedState::findLink(string word, string* linkPtr,
        unordered_map<string, Definition*>& map) {
    auto mapIter = map.find(word);
    if (map.end() != mapIter) {
        if ((fPriorDef = mapIter->second)) {
            *linkPtr = '#' + mapIter->second->fFiddle;
        }
        return true;
    }
    return false;
}

const Definition* MdOut::findParamType() {
    SkASSERT(fMethod);
    TextParser parser(fMethod->fFileName, fMethod->fStart, fMethod->fContentStart,
            fMethod->fLineCount);
    string lastFull;
    do {
        parser.skipToAlpha();
        if (parser.eof()) {
            return nullptr;
        }
        const char* word = parser.fChar;
        parser.skipFullName();
        SkASSERT(!parser.eof());
        string name = string(word, parser.fChar - word);
        if (fLastParam->fName == name) {
            const Definition* paramType = this->isDefined(parser, Resolvable::kOut);
            return paramType;
        }
        if (isupper(name[0])) {
            lastFull = name;
        }
    } while (true);
    return nullptr;
}

string MdOut::getMemberTypeName(const Definition* def, string* memberType) {
    TextParser parser(def->fFileName, def->fStart, def->fContentStart,
            def->fLineCount);
    parser.skipExact("#Member");
    parser.skipWhiteSpace();
    const char* typeStart = parser.fChar;
    const char* typeEnd = nullptr;
    const char* nameStart = nullptr;
    const char* nameEnd = nullptr;
    do {
        parser.skipToWhiteSpace();
        if (nameStart) {
            nameEnd = parser.fChar;
        }
        if (parser.eof()) {
            break;
        }
        const char* spaceLoc = parser.fChar;
        if (parser.skipWhiteSpace()) {
            typeEnd = spaceLoc;
            nameStart = parser.fChar;
        }
    } while (!parser.eof());
    SkASSERT(typeEnd);
    *memberType = string(typeStart, (int) (typeEnd - typeStart));
    replace_all(*memberType, " ", "&nbsp;");
    SkASSERT(nameStart);
    SkASSERT(nameEnd);
    return string(nameStart, (int) (nameEnd - nameStart));
}

bool MdOut::HasDetails(const Definition* def) {
    for (auto child : def->fChildren) {
        if (MarkType::kDetails == child->fMarkType) {
            return true;
        }
        if (MdOut::HasDetails(child)) {
            return true;
        }
    }
    return false;
}

void MdOut::htmlOut(string s) {
    SkASSERT(string::npos != s.find('<'));
    FPRINTF("%s", s.c_str());
}

const Definition* MdOut::isDefined(const TextParser& parser, Resolvable resolvable) {
    DefinedState s(*this, parser.fStart, parser.fEnd, resolvable);
    const char* start = parser.fStart;
    do {
        s.fSeparatorStart = start;
        start = s.skipWhiteSpace();
        s.skipParens();
        (void) s.nextSeparator(start);
        if (s.findEnd(start)) {
            return nullptr;
        }
        s.fWord = string(start, s.fEnd - start);
        s.setLower();
    } while (s.setPriorSpaceWord(&start));
    s.setLink();
    return s.fPriorDef;
}

string MdOut::linkName(const Definition* ref) const {
    string result = ref->fName;
    size_t under = result.find('_');
    if (string::npos != under) {
        string classPart = result.substr(0, under);
        string namePart = result.substr(under + 1, result.length());
        if (fRoot && (fRoot->fName == classPart
                || (fRoot->fParent && fRoot->fParent->fName == classPart))) {
            result = namePart;
        }
    }
    replace_all(result, "::", "_");
    return result;
}

static bool writeTableEnd(MarkType markType, Definition* def, const Definition** prior) {
    return markType != def->fMarkType && *prior && markType == (*prior)->fMarkType;
}

// Recursively build string with declarative code. Skip structs, classes, that
// have been built directly.
void MdOut::addCodeBlock(const Definition* def, string& result) const {
    const Definition* last = nullptr;
    bool wroteFunction = false;
    for (auto member : def->fChildren) {
        const Definition* prior = last;
        const char* priorTerminator = nullptr;
        if (prior) {
            priorTerminator = prior->fTerminator ? prior->fTerminator : prior->fContentEnd;
        }
        last = member;
        if (KeyWord::kIfndef == member->fKeyWord) {
            this->addCodeBlock(member, result);
            continue;
        }
        if (KeyWord::kClass == member->fKeyWord || KeyWord::kStruct == member->fKeyWord
                || KeyWord::kTemplate == member->fKeyWord) {
            if (!member->fChildren.size()) {
                continue;
            }
            // todo: Make sure this was written non-elided somewhere else
            // todo: provide indent value?
            string block = fIncludeParser.elidedCodeBlock(*member);
            // add italic link for elided body
            size_t brace = block.find('{');
            if (string::npos != brace) {
                string name = member->fName;
                if ("" == name) {
                    for (auto child : member->fChildren) {
                        if ("" != (name = child->fName)) {
                            break;
                        }
                    }
                }
                SkASSERT("" != name);
                string body = "\n    // <i>" + name + " interface</i>";
                block = block.substr(0, brace + 1) + body + block.substr(brace + 1);
            }
            this->stringAppend(result, block);
            continue;
        }
        if (KeyWord::kEnum == member->fKeyWord) {
            if (member->fChildren.empty()) {
                continue;
            }
            auto tokenIter = member->fTokens.begin();
            if (KeyWord::kEnum == member->fKeyWord && KeyWord::kClass == tokenIter->fKeyWord) {
                tokenIter = tokenIter->fTokens.begin();
            }
            while (Definition::Type::kWord != tokenIter->fType) {
                std::advance(tokenIter, 1);
            }
            const auto& token = *tokenIter;
            string name = string(token.fContentStart, token.length());
            SkASSERT(name.length() > 0);
            MarkType markType = KeyWord::kClass == member->fKeyWord
                    || KeyWord::kStruct == member->fKeyWord ? MarkType::kClass : MarkType::kEnum;
            // find bmh def or just find name of class / struct / enum ? (what if enum is nameless?)
            if (wroteFunction) {
                this->stringAppend(result, '\n');
                wroteFunction = false;
            }
            this->stringAppend(result,
                    fIncludeParser.codeBlock(markType, name, fInProgress));
            this->stringAppend(result, '\n');
            continue;
        }
        // Global function declarations are not preparsed very well;
        // make do by using the prior position to find the start
        if (Bracket::kParen == member->fBracket && prior) {
            TextParser function(member->fFileName, priorTerminator, member->fTerminator + 1,
                    member->fLineCount);
            this->stringAppend(result,
                    fIncludeParser.writeCodeBlock(function, MarkType::kFunction, 0));
            this->stringAppend(result, ";\n");
            wroteFunction = true;
            continue;
        }
        if (KeyWord::kTypedef == member->fKeyWord) {
            this->stringAppend(result, member);
            this->stringAppend(result, ";\n");
            continue;
        }
        if (KeyWord::kDefine == member->fKeyWord) {
            string body(member->fContentStart, member->length());
            if (string::npos != body.find('(')) {
                this->stringAppend(result, body);
                this->stringAppend(result, '\n');
            }
            continue;
        }
        if (KeyWord::kConstExpr == member->fKeyWord) {
            this->stringAppend(result, member);
            auto nextMember = def->fTokens.begin();
            unsigned tokenPos = member->fParentIndex + 1;
            SkASSERT(tokenPos < def->fTokens.size());
            std::advance(nextMember, tokenPos);
            while (member->fContentEnd >= nextMember->fContentStart) {
                std::advance(nextMember, 1);
                SkASSERT(++tokenPos < def->fTokens.size());
            }
            while (Punctuation::kSemicolon != nextMember->fPunctuation) {
                std::advance(nextMember, 1);
                SkASSERT(++tokenPos < def->fTokens.size());
            }
            TextParser between(member->fFileName, member->fContentEnd,
                    nextMember->fContentStart, member->fLineCount);
            between.skipWhiteSpace();
            if ('=' == between.peek()) {
                this->stringAppend(result, ' ');
                string middle(between.fChar, nextMember->fContentStart);
                this->stringAppend(result, middle);
                last = nullptr;
            } else {
                SkAssertResult(';' == between.peek());
            }
            this->stringAppend(result, ';');
            this->stringAppend(result, '\n');
            continue;
        }
    }
}

void MdOut::markTypeOut(Definition* def, const Definition** prior) {
    string printable = def->printableName();
    const char* textStart = def->fContentStart;
    bool lookForOneLiner = false;
    // #Param and #Const don't have markers to say when the last is seen, so detect that by looking
    // for a change in type.
    if (writeTableEnd(MarkType::kParam, def, prior) || writeTableEnd(MarkType::kConst, def, prior)
                || writeTableEnd(MarkType::kMember, def, prior)) {
        this->writePending();
        FPRINTF("</table>");
        this->lf(2);
        fTableState = TableState::kNone;
    }
    fLastDef = def;
    NameMap paramMap;
    switch (def->fMarkType) {
        case MarkType::kAlias:
            break;
        case MarkType::kAnchor: {
            if (fColumn > 0) {
                this->writeSpace();
            }
            this->writePending();
            TextParser parser(def);
            const char* start = parser.fChar;
            parser.skipToEndBracket((string(" ") + def->fMC + " ").c_str());
            string anchorText(start, parser.fChar - start);
            parser.skipExact((string(" ") + def->fMC + " ").c_str());
            string anchorLink(parser.fChar, parser.fEnd - parser.fChar);
            this->htmlOut(anchorRef(anchorLink, anchorText));
            } break;
        case MarkType::kBug:
            break;
        case MarkType::kClass:
        case MarkType::kStruct:
            fRoot = def->asRoot();
            this->lfAlways(2);
            if (MarkType::kStruct == def->fMarkType) {
                this->htmlOut(anchorDef(def->fFiddle, ""));
            } else {
                this->htmlOut(anchorDef(this->linkName(def), ""));
            }
            this->lfAlways(2);
            FPRINTF("---");
            this->lf(2);
            break;
        case MarkType::kCode:
            this->lfAlways(2);
            FPRINTF("<pre style=\"padding: 1em 1em 1em 1em;"
                    "width: 62.5em; background-color: #f0f0f0\">");
            this->lf(1);
            fResolveAndIndent = true;
            break;
        case MarkType::kColumn:
            this->writePending();
            if (fInList) {
                FPRINTF("    <td>");
            } else {
                FPRINTF("| ");
            }
            break;
        case MarkType::kComment:
            break;
        case MarkType::kMember:
        case MarkType::kConst: {
            bool isConst = MarkType::kConst == def->fMarkType;
            lookForOneLiner = false;
            fWroteSomething = false;
        // output consts for one parent with moderate descriptions
        // optional link to subtopic with longer descriptions, examples
            if (TableState::kNone == fTableState) {
                SkASSERT(!*prior || (isConst && MarkType::kConst != (*prior)->fMarkType)
                        || (!isConst && MarkType::kMember != (*prior)->fMarkType));
                if (isConst) {
                    this->mdHeaderOut(3);
                    this->writeString(this->fPopulators[SubtopicKeys::kConstants].fPlural);
                    this->lfAlways(2);
                }
                FPRINTF("%s", kTableDeclaration);
                fTableState = TableState::kRow;
                fOddRow = true;
                this->lfAlways(1);
                // look ahead to see if the details column has data or not
                fHasDetails = MdOut::HasDetails(def->fParent);
                FPRINTF("%s", fHasDetails ? \
                        (isConst ? kSubConstTableHeader : kSubMemberTableHeader) : \
                        (isConst ? kAllConstTableHeader : kAllMemberTableHeader));
                this->lfAlways(1);
            }
            if (TableState::kRow == fTableState) {
                this->writePending();
                FPRINTF("%s", fOddRow ? kTR_Dark.c_str() : "  <tr>");
                fOddRow = !fOddRow;
                this->lfAlways(1);
                fTableState = TableState::kColumn;
            }
            this->writePending();
            if (isConst) {
                // TODO: if fHasDetails is true, could defer def and issue a ref instead
                // unclear if this is a good idea or not
                FPRINTF("%s", this->tableDataCodeDef(def).c_str());
                this->lfAlways(1);
                FPRINTF("%s", table_data_const(def, &textStart).c_str());
            } else {
                string memberType;
                string memberName = this->getMemberTypeName(def, &memberType);
                FPRINTF("%s", out_table_data_description(memberType).c_str());
                this->lfAlways(1);
                FPRINTF("%s", tableDataCodeDef(def->fFiddle, memberName).c_str());
            }
            this->lfAlways(1);
            if (fHasDetails) {
                string details;
                auto subtopic = std::find_if(def->fChildren.begin(), def->fChildren.end(),
                        [](const Definition* test){
                        return MarkType::kDetails == test->fMarkType; } );
                if (def->fChildren.end() != subtopic) {
                    string subtopicName = string((*subtopic)->fContentStart,
                            (int) ((*subtopic)->fContentEnd - (*subtopic)->fContentStart));
                    const Definition* parentSubtopic = def->subtopicParent();
                    SkASSERT(parentSubtopic);
                    string fullName = parentSubtopic->fFiddle + '_' + subtopicName;
                    if (fBmhParser.fTopicMap.end() == fBmhParser.fTopicMap.find(fullName)) {
                        (*subtopic)->reportError<void>("missing #Details subtopic");
                    }
             //       subtopicName = parentSubtopic->fName + '_' + subtopicName;
                    string noUnderscores = subtopicName;
                    replace_all(noUnderscores, "_", "&nbsp;");
                    details = this->anchorLocalRef(subtopicName, noUnderscores) + "&nbsp;";
                }
                FPRINTF("%s", out_table_data_details(details).c_str());
                this->lfAlways(1);
            }
            lookForOneLiner = true;  // if description is empty, use oneLiner data
            FPRINTF("%s", out_table_data_description_start().c_str()); // start of Description
            this->lfAlways(1);
        } break;
        case MarkType::kDescription:
            fInDescription = true;
            this->writePending();
            FPRINTF("%s", "<div>");
            break;
        case MarkType::kDetails:
            break;
        case MarkType::kDuration:
            break;
        case MarkType::kDefine:
        case MarkType::kEnum:
        case MarkType::kEnumClass:
            this->lfAlways(2);
            this->htmlOut(anchorDef(def->fFiddle, ""));
            this->lfAlways(2);
            FPRINTF("---");
            this->lf(2);
            break;
        case MarkType::kExample: {
            this->mdHeaderOut(3);
            FPRINTF("%s", "Example\n"
                            "\n");
            fHasFiddle = true;
            bool showGpu = false;
            bool gpuAndCpu = false;
            const Definition* platform = def->hasChild(MarkType::kPlatform);
            if (platform) {
                TextParser platParse(platform);
                fHasFiddle = !platParse.strnstr("!fiddle", platParse.fEnd);
                showGpu = platParse.strnstr("gpu", platParse.fEnd);
                if (showGpu) {
                    gpuAndCpu = platParse.strnstr("cpu", platParse.fEnd);
                }
            }
            if (fHasFiddle) {
                SkASSERT(def->fHash.length() > 0);
                FPRINTF("<div><fiddle-embed name=\"%s\"", def->fHash.c_str());
                if (showGpu) {
                    FPRINTF("%s", " gpu=\"true\"");
                    if (gpuAndCpu) {
                        FPRINTF("%s", " cpu=\"true\"");
                    }
                }
                FPRINTF("%s", ">");
            } else {
                SkASSERT(def->fHash.length() == 0);
                FPRINTF("%s", "<pre style=\"padding: 1em 1em 1em 1em; font-size: 13px"
                        " width: 62.5em; background-color: #f0f0f0\">");
                this->lfAlways(1);
                if (def->fWrapper.length() > 0) {
                    FPRINTF("%s", def->fWrapper.c_str());
                }
                fLiteralAndIndent = true;
            }
            } break;
        case MarkType::kExternal:
            break;
        case MarkType::kFile:
            break;
        case MarkType::kFilter:
            break;
        case MarkType::kFormula:
            break;
        case MarkType::kFunction:
            break;
        case MarkType::kHeight:
            break;
        case MarkType::kIllustration: {
            string illustName = "Illustrations_" + def->fParent->fFiddle;
            string number = string(def->fContentStart, def->length());
            if (number.length() && "1" != number) {
                illustName += "_" + number;
            }
            auto illustIter = fBmhParser.fTopicMap.find(illustName);
            SkASSERT(fBmhParser.fTopicMap.end() != illustIter);
            Definition* illustDef = illustIter->second;
            SkASSERT(MarkType::kSubtopic == illustDef->fMarkType);
            SkASSERT(1 == illustDef->fChildren.size());
            Definition* illustExample = illustDef->fChildren[0];
            SkASSERT(MarkType::kExample == illustExample->fMarkType);
            string hash = illustExample->fHash;
            SkASSERT("" != hash);
            string title;
            this->writePending();
            FPRINTF("![%s](https://fiddle.skia.org/i/%s_raster.png \"%s\")",
                    def->fName.c_str(), hash.c_str(), title.c_str());
            this->lf(2);
        } break;
        case MarkType::kImage:
            break;
        case MarkType::kIn:
            break;
        case MarkType::kLegend:
            break;
        case MarkType::kLine:
            break;
        case MarkType::kLink:
            break;
        case MarkType::kList:
            fInList = true;
            fTableState = TableState::kRow;
            this->lfAlways(2);
            FPRINTF("%s", "<table>");
            this->lf(1);
            break;
        case MarkType::kLiteral:
            break;
        case MarkType::kMarkChar:
            fBmhParser.fMC = def->fContentStart[0];
            break;
        case MarkType::kMethod: {
            this->lfAlways(2);
			if (false && !def->isClone()) {
                string method_name = def->methodName();
                this->mdHeaderOutLF(2, 1);
                this->htmlOut(this->anchorDef(def->fFiddle, method_name));
			} else {
                this->htmlOut(this->anchorDef(def->fFiddle, ""));
            }
            this->lfAlways(2);
            FPRINTF("---");
			this->lf(2);

            // TODO: put in css spec that we can define somewhere else (if markup supports that)
            // TODO: 50em below should match limit = 80 in formatFunction()
            this->writePending();
            string formattedStr = def->formatFunction(Definition::Format::kIncludeReturn);
            string preformattedStr = preformat(formattedStr);
            string references = this->addReferences(&preformattedStr.front(),
                    &preformattedStr.back() + 1, Resolvable::kSimple);
            preformattedStr = references;
            this->htmlOut("<pre style=\"padding: 1em 1em 1em 1em; width: 62.5em;"
                    "background-color: #f0f0f0\">\n" + preformattedStr + "\n" + "</pre>");
            this->lf(2);
            fTableState = TableState::kNone;
            fMethod = def;
            Definition* iMethod = fIncludeParser.findMethod(*def);
            if (iMethod) {
                fMethod = iMethod;
                paramMap.fParent = &fBmhParser.fGlobalNames;
                paramMap.setParams(def, iMethod);
                fNames = &paramMap;
            }
            } break;
        case MarkType::kNoExample:
            break;
        case MarkType::kNoJustify:
            break;
        case MarkType::kOutdent:
            break;
        case MarkType::kParam: {
            TextParser paramParser(def->fFileName, def->fStart, def->fContentStart,
                    def->fLineCount);
            paramParser.skipWhiteSpace();
            SkASSERT(paramParser.startsWith("#Param"));
            paramParser.next(); // skip hash
            paramParser.skipToNonName(); // skip Param
            this->parameterHeaderOut(paramParser, prior, def);
        } break;
        case MarkType::kPhraseDef:
            // skip text and children
            *prior = def;
            return;
        case MarkType::kPhraseParam:
            SkDebugf(""); // convenient place to set a breakpoint
            break;
        case MarkType::kPhraseRef:
            if (fPhraseParams.end() != fPhraseParams.find(def->fName)) {
                if (fColumn > 0) {
                    this->writeSpace();
                }
                this->writeString(fPhraseParams[def->fName]);
                if (isspace(def->fContentStart[0])) {
                    this->writeSpace();
                }
            } else if (fBmhParser.fPhraseMap.end() == fBmhParser.fPhraseMap.find(def->fName)) {
                def->reportError<void>("missing phrase definition");
                fAddRefFailed = true;
            } else {
                if (fColumn) {
                    SkASSERT(' ' >= def->fStart[0]);
                    this->writeSpace();
                }
                Definition* phraseRef = fBmhParser.fPhraseMap.find(def->fName)->second;
                // def->fChildren are parameters to substitute phraseRef->fChildren,
                // phraseRef->fChildren has both param defines and references
                // def->fChildren must have the same number of entries as phaseRef->fChildren
                // which are kPhraseParam, and substitute one for one
                // Then, each kPhraseRef in phaseRef looks up the key and value
                fPhraseParams.clear();
                auto refKidsIter = phraseRef->fChildren.begin();
                for (auto child : def->fChildren) {
                    if (MarkType::kPhraseParam != child->fMarkType) {
                        // more work to do to support other types
                        this->reportError("phrase ref child must be param");
                    }
                    do {
                        if (refKidsIter == phraseRef->fChildren.end()) {
                            this->reportError("phrase def missing param");
                            break;
                        }
                        if (MarkType::kPhraseRef == (*refKidsIter)->fMarkType) {
                            continue;
                        }
                        if (MarkType::kPhraseParam != (*refKidsIter)->fMarkType) {
                            this->reportError("unexpected type in phrase def children");
                            break;
                        }
                        fPhraseParams[(*refKidsIter)->fName] = child->fName;
                        break;
                    } while (true);
                }
                this->childrenOut(phraseRef, phraseRef->fContentStart);
                fPhraseParams.clear();
                if (' ' >= def->fContentStart[0] && !fPendingLF) {
                    this->writeSpace();
                }
            }
            break;
        case MarkType::kPlatform:
            break;
        case MarkType::kPopulate: {
            Definition* parent = def->fParent;
            SkASSERT(parent);
            if (MarkType::kCode == parent->fMarkType) {
                auto inDef = std::find_if(parent->fChildren.begin(), parent->fChildren.end(),
                        [](const Definition* child) { return MarkType::kIn == child->fMarkType; });
                if (parent->fChildren.end() != inDef) {
                    auto filterDef = std::find_if(parent->fChildren.begin(),
                            parent->fChildren.end(), [](const Definition* child) {
                            return MarkType::kFilter == child->fMarkType; });
                    SkASSERT(parent->fChildren.end() != filterDef);
                    string codeBlock = fIncludeParser.filteredBlock(
                            string((*inDef)->fContentStart, (*inDef)->length()),
                            string((*filterDef)->fContentStart, (*filterDef)->length()));
                    this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
                            this->resolvable(parent));
                    break;
                }
                // find include matching code parent
                Definition* grand = parent->fParent;
                SkASSERT(grand);
                if (MarkType::kClass == grand->fMarkType
                        || MarkType::kStruct == grand->fMarkType
                        || MarkType::kEnum == grand->fMarkType
                        || MarkType::kEnumClass == grand->fMarkType
                        || MarkType::kTypedef == grand->fMarkType
                        || MarkType::kDefine == grand->fMarkType) {
                    string codeBlock = fIncludeParser.codeBlock(*grand, fInProgress);
                    this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
                            this->resolvable(parent));
                } else if (MarkType::kTopic == grand->fMarkType) {
                    // use bmh file name to find include file name
                    size_t start = grand->fFileName.rfind("Sk");
                    SkASSERT(start != string::npos);
                    size_t end = grand->fFileName.rfind("_Reference");
                    SkASSERT(end != string::npos && end > start);
                    string incName(grand->fFileName.substr(start, end - start));
                    const Definition* includeDef = fIncludeParser.include(incName + ".h");
                    SkASSERT(includeDef);
                    string codeBlock;
                    this->addCodeBlock(includeDef, codeBlock);
                    this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
                            this->resolvable(parent));
                } else {
                    SkASSERT(MarkType::kSubtopic == grand->fMarkType);
                    auto inTag = std::find_if(grand->fChildren.begin(), grand->fChildren.end(),
                            [](Definition* child){return MarkType::kIn == child->fMarkType;});
                    SkASSERT(grand->fChildren.end() != inTag);
                    auto filterTag = std::find_if(grand->fChildren.begin(), grand->fChildren.end(),
                            [](Definition* child){return MarkType::kFilter == child->fMarkType;});
                    SkASSERT(grand->fChildren.end() != filterTag);
                    string inContents((*inTag)->fContentStart, (*inTag)->length());
                    string filterContents((*filterTag)->fContentStart, (*filterTag)->length());
                    string filteredBlock = fIncludeParser.filteredBlock(inContents, filterContents);
                    this->resolveOut(filteredBlock.c_str(), filteredBlock.c_str()
                            + filteredBlock.length(), this->resolvable(parent));
                }
            } else {
                SkASSERT(MarkType::kMethod == parent->fMarkType);
                // retrieve parameters, return, description from include
                Definition* iMethod = fIncludeParser.findMethod(*parent);
                if (!iMethod) {  // deprecated or 'in progress' functions should not include populate
                    SkDebugf("#Populate found in deprecated or missing method %s\n", def->fName.c_str());
                    def->fParent->reportError<void>("Remove #Method");
                }
                bool wroteParam = false;
                SkASSERT(fMethod == iMethod);
                for (auto& entry : iMethod->fTokens) {
                    if (MarkType::kComment != entry.fMarkType) {
                        continue;
                    }
                    TextParser parser(&entry);
                    if (parser.skipExact("@param ")) { // write parameters, if any
                        this->parameterHeaderOut(parser, prior, def);
                        this->resolveOut(parser.fChar, parser.fEnd,
                                Resolvable::kInclude);
                        this->parameterTrailerOut();
                        wroteParam = true;
                        continue;
                    }
                    if (wroteParam) {
                        this->writePending();
                        FPRINTF("</table>");
                        this->lf(2);
                        fTableState = TableState::kNone;
                        wroteParam = false;
                    }
                    if (parser.skipExact("@return ")) { // write return, if any
                        this->returnHeaderOut(prior, def);
                        this->resolveOut(parser.fChar, parser.fEnd,
                                Resolvable::kInclude);
                        this->lf(2);
                        continue;
                    }
                    if (1 == entry.length() && '/' == entry.fContentStart[0]) {
                        continue;
                    }
                    if ("/!< " == string(entry.fContentStart, entry.length()).substr(0, 4)) {
                        continue;
                    }
                    const char* backwards = entry.fContentStart;
                    while (' ' == *--backwards)
                        ;
                    if ('\n' == backwards[0] && '\n' == backwards[-1]) {
                        this->lf(2);
                    }
                    this->resolveOut(entry.fContentStart, entry.fContentEnd,
                            Resolvable::kInclude);  // write description
                    this->lf(1);
                }
            }
            } break;
        case MarkType::kReturn:
            this->returnHeaderOut(prior, def);
            break;
        case MarkType::kRow:
            if (fInList) {
                FPRINTF("  <tr>");
                this->lf(1);
            }
            break;
        case MarkType::kSeeAlso:
            this->mdHeaderOut(3);
            FPRINTF("See Also");
            this->lf(2);
            break;
        case MarkType::kSet:
            break;
        case MarkType::kStdOut: {
            TextParser code(def);
            this->mdHeaderOut(4);
            FPRINTF(
                    "Example Output\n"
                    "\n"
                    "~~~~");
            this->lfAlways(1);
            code.skipSpace();
            while (!code.eof()) {
                const char* end = code.trimmedLineEnd();
                FPRINTF("%.*s\n", (int) (end - code.fChar), code.fChar);
                code.skipToLineStart();
            }
            FPRINTF("~~~~");
            this->lf(2);
            } break;
        case MarkType::kSubstitute:
            break;
        case MarkType::kSubtopic:
            fSubtopic = def->asRoot();
            if (false && SubtopicKeys::kOverview == def->fName) {
                this->writeString(def->fName);
            } else {
                this->lfAlways(2);
                this->htmlOut(anchorDef(def->fName, ""));
            }
            if (std::any_of(def->fChildren.begin(), def->fChildren.end(),
                    [](Definition* child) {
                    return MarkType::kSeeAlso == child->fMarkType
                    || MarkType::kExample == child->fMarkType
                    || MarkType::kNoExample == child->fMarkType;
            })) {
                this->lfAlways(2);
                FPRINTF("---");
            }
            this->lf(2);
#if 0
            // if a subtopic child is const, generate short table of const name, value, line desc
            if (std::any_of(def->fChildren.begin(), def->fChildren.end(),
                    [](Definition* child){return MarkType::kConst == child->fMarkType;})) {
                this->summaryOut(def, MarkType::kConst, fPopulators[SubtopicKeys::kConstants].fPlural);
            }
#endif
            // if a subtopic child is member, generate short table of const name, value, line desc
            if (std::any_of(def->fChildren.begin(), def->fChildren.end(),
                    [](Definition* child){return MarkType::kMember == child->fMarkType;})) {
                this->summaryOut(def, MarkType::kMember, fPopulators[SubtopicKeys::kMembers].fPlural);
            }
            break;
        case MarkType::kTable:
            this->lf(2);
            break;
        case MarkType::kTemplate:
            break;
        case MarkType::kText:
            if (def->fParent && MarkType::kFormula == def->fParent->fMarkType) {
                if (fColumn > 0) {
                    this->writeSpace();
                }
                this->writePending();
                this->htmlOut("<code>");
                this->resolveOut(def->fContentStart, def->fContentEnd,
                        Resolvable::kFormula);
                this->htmlOut("</code>");
            }
            break;
        case MarkType::kToDo:
            break;
        case MarkType::kTopic: {
            auto found = std::find_if(def->fChildren.begin(), def->fChildren.end(),
                    [](Definition* test) { return test->isStructOrClass(); } );
            bool hasClassOrStruct = def->fChildren.end() != found;
            fRoot = hasClassOrStruct ? (*found)->asRoot() : def->asRoot();
            fSubtopic = def->asRoot();
            bool isUndocumented = string::npos != def->fFileName.find("undocumented");
            if (!isUndocumented) {
                this->populateTables(def, fRoot);
            }
//            this->mdHeaderOut(1);
//            this->htmlOut(anchorDef(this->linkName(def), printable));
//            this->lf(1);
            } break;
        case MarkType::kTypedef:
            this->lfAlways(2);
            this->htmlOut(anchorDef(def->fFiddle, ""));
            this->lfAlways(2);
            FPRINTF("---");
            this->lf(2);
            break;
        case MarkType::kUnion:
            break;
        case MarkType::kVolatile:
            break;
        case MarkType::kWidth:
            break;
        default:
            SkDebugf("fatal error: MarkType::k%s unhandled in %s()\n",
                    BmhParser::kMarkProps[(int) def->fMarkType].fName, __func__);
            SkASSERT(0); // handle everything
            break;
    }
    this->childrenOut(def, textStart);
    switch (def->fMarkType) {  // post child work, at least for tables
        case MarkType::kAnchor:
            if (fColumn > 0) {
                this->writeSpace();
            }
            break;
        case MarkType::kClass:
        case MarkType::kStruct:
            if (TableState::kNone != fTableState) {
                this->writePending();
                FPRINTF("</table>");
                this->lf(2);
                fTableState = TableState::kNone;
            }
            if (def->csParent()) {
                fRoot = def->csParent()->asRoot();
            }
            break;
        case MarkType::kCode:
            fIndent = 0;
            this->lf(1);
            this->writePending();
            FPRINTF("</pre>");
            this->lf(2);
            fResolveAndIndent = false;
            break;
        case MarkType::kColumn:
            if (fInList) {
                this->writePending();
                FPRINTF("</td>");
                this->lfAlways(1);
            } else {
                FPRINTF(" ");
            }
            break;
        case MarkType::kDescription:
            this->writePending();
            FPRINTF("</div>");
            fInDescription = false;
            break;
        case MarkType::kEnum:
        case MarkType::kEnumClass:
            if (TableState::kNone != fTableState) {
                this->writePending();
                FPRINTF("</table>");
                this->lf(2);
                fTableState = TableState::kNone;
            }
            break;
        case MarkType::kExample:
            this->writePending();
            if (fHasFiddle) {
                FPRINTF("</fiddle-embed></div>");
            } else {
                this->lfAlways(1);
                if (def->fWrapper.length() > 0) {
                    FPRINTF("}");
                    this->lfAlways(1);
                }
                FPRINTF("</pre>");
            }
            this->lf(2);
            fLiteralAndIndent = false;
            break;
        case MarkType::kLink:
            this->writeString("</a>");
            this->writeSpace();
            break;
        case MarkType::kList:
            fInList = false;
            this->writePending();
            SkASSERT(TableState::kNone != fTableState);
            FPRINTF("</table>");
            this->lf(2);
            fTableState = TableState::kNone;
            break;
        case MarkType::kLegend: {
            SkASSERT(def->fChildren.size() == 1);
            const Definition* row = def->fChildren[0];
            SkASSERT(MarkType::kRow == row->fMarkType);
            size_t columnCount = row->fChildren.size();
            SkASSERT(columnCount > 0);
            this->writePending();
            for (size_t index = 0; index < columnCount; ++index) {
                FPRINTF("| --- ");
            }
            FPRINTF(" |");
            this->lf(1);
            } break;
        case MarkType::kMethod:
            fMethod = nullptr;
            fNames = fNames->fParent;
            break;
        case MarkType::kConst:
        case MarkType::kMember:
            if (lookForOneLiner && !fWroteSomething) {
                auto oneLiner = std::find_if(def->fChildren.begin(), def->fChildren.end(),
                        [](const Definition* test){ return MarkType::kLine == test->fMarkType; } );
                if (def->fChildren.end() != oneLiner) {
                    TextParser parser(*oneLiner);
                    parser.skipWhiteSpace();
                    parser.trimEnd();
                    FPRINTF("%.*s", (int) (parser.fEnd - parser.fChar), parser.fChar);
                }
                lookForOneLiner = false;
            }
        case MarkType::kParam:
            this->parameterTrailerOut();
            break;
        case MarkType::kReturn:
        case MarkType::kSeeAlso:
            this->lf(2);
            break;
        case MarkType::kRow:
            if (fInList) {
                FPRINTF("  </tr>");
            } else {
                FPRINTF("|");
            }
            this->lf(1);
            break;
        case MarkType::kTable:
            this->lf(2);
            break;
        case MarkType::kPhraseDef:
            break;
        case MarkType::kSubtopic:
            SkASSERT(def);
            do {
                def = def->fParent;
            } while (def && MarkType::kTopic != def->fMarkType
                    && MarkType::kSubtopic != def->fMarkType);
            SkASSERT(def);
            fSubtopic = def->asRoot();
            break;
        case MarkType::kTopic:
            fSubtopic = nullptr;
            break;
        default:
            break;
    }
    *prior = def;
}

void MdOut::mdHeaderOutLF(int depth, int lf) {
    this->lfAlways(lf);
    for (int index = 0; index < depth; ++index) {
        FPRINTF("#");
    }
    FPRINTF(" ");
}

void MdOut::parameterHeaderOut(TextParser& paramParser, const Definition** prior, Definition* def) {
    if (TableState::kNone == fTableState) {
        SkASSERT(!*prior || MarkType::kParam != (*prior)->fMarkType);
        this->mdHeaderOut(3);
        this->htmlOut(
                "Parameters\n"
                "\n"
                "<table>"
                );
        this->lf(1);
        fTableState = TableState::kRow;
    }
    if (TableState::kRow == fTableState) {
        FPRINTF("  <tr>");
        this->lf(1);
        fTableState = TableState::kColumn;
    }
    paramParser.skipSpace();
    const char* paramName = paramParser.fChar;
    paramParser.skipToSpace();
    string paramNameStr(paramName, (int) (paramParser.fChar - paramName));
    if (MarkType::kPopulate != def->fMarkType && !this->checkParamReturnBody(def)) {
        *prior = def;
        return;
    }
    string refNameStr = def->fParent->fFiddle + "_" + paramNameStr;
    this->htmlOut("    <td>" + this->anchorDef(refNameStr,
            "<code><strong>" + paramNameStr + "</strong></code>") + "</td>");
    this->lfAlways(1);
    FPRINTF("    <td>");
}

void MdOut::parameterTrailerOut() {
    SkASSERT(TableState::kColumn == fTableState);
    fTableState = TableState::kRow;
    this->writePending();
    FPRINTF("</td>");
    this->lfAlways(1);
    FPRINTF("  </tr>");
    this->lfAlways(1);
}

void MdOut::populateOne(Definition* def,
        unordered_map<string, RootDefinition::SubtopicContents>& populator) {
    if (MarkType::kConst == def->fMarkType) {
        populator[SubtopicKeys::kConstants].fMembers.push_back(def);
        return;
    }
    if (MarkType::kEnum == def->fMarkType || MarkType::kEnumClass == def->fMarkType) {
        populator[SubtopicKeys::kConstants].fMembers.push_back(def);
        return;
    }
    if (MarkType::kDefine == def->fMarkType) {
        populator[SubtopicKeys::kDefines].fMembers.push_back(def);
        return;
    }
    if (MarkType::kMember == def->fMarkType) {
        populator[SubtopicKeys::kMembers].fMembers.push_back(def);
        return;
    }
    if (MarkType::kTypedef == def->fMarkType) {
        populator[SubtopicKeys::kTypedefs].fMembers.push_back(def);
        return;
    }
    if (MarkType::kMethod != def->fMarkType) {
        return;
    }
    if (def->fClone) {
        return;
    }
    if (Definition::MethodType::kConstructor == def->fMethodType
            || Definition::MethodType::kDestructor == def->fMethodType) {
        populator[SubtopicKeys::kConstructors].fMembers.push_back(def);
        return;
    }
    if (Definition::MethodType::kOperator == def->fMethodType) {
        populator[SubtopicKeys::kOperators].fMembers.push_back(def);
        return;
    }
    populator[SubtopicKeys::kMemberFunctions].fMembers.push_back(def);
    const Definition* csParent = this->csParent();
    if (csParent) {
        if (0 == def->fName.find(csParent->fName + "::Make")
                || 0 == def->fName.find(csParent->fName + "::make")) {
            populator[SubtopicKeys::kConstructors].fMembers.push_back(def);
            return;
        }
    }
    for (auto item : def->fChildren) {
        if (MarkType::kIn == item->fMarkType) {
            string name(item->fContentStart, item->fContentEnd - item->fContentStart);
            populator[name].fMembers.push_back(def);
            populator[name].fShowClones = true;
            break;
        }
    }
}

void MdOut::populateTables(const Definition* def, RootDefinition* root) {
    for (auto child : def->fChildren) {
        if (MarkType::kSubtopic == child->fMarkType) {
            string name = child->fName;
            bool builtInTopic = name == SubtopicKeys::kOverview;
            for (auto item : SubtopicKeys::kGeneratedSubtopics) {
                builtInTopic |= name == item;
            }
            if (!builtInTopic) {
                string subname;
                const Definition* subtopic = child->subtopicParent();
                if (subtopic) {
                    subname = subtopic->fName + '_';
                }
                builtInTopic = name == subname + SubtopicKeys::kOverview;
                for (auto item : SubtopicKeys::kGeneratedSubtopics) {
                    builtInTopic |= name == subname + item;
                }
                if (!builtInTopic) {
                    root->populator(SubtopicKeys::kRelatedFunctions).fMembers.push_back(child);
                }
            }
            this->populateTables(child, root);
            continue;
        }
        if (child->isStructOrClass()) {
            if (fClassStack.size() > 0) {
                root->populator(MarkType::kStruct != child->fMarkType ? SubtopicKeys::kClasses :
                        SubtopicKeys::kStructs).fMembers.push_back(child);
            }
            fClassStack.push_back(child);
            this->populateTables(child, child->asRoot());
            fClassStack.pop_back();
            continue;
        }
        if (MarkType::kEnum == child->fMarkType || MarkType::kEnumClass == child->fMarkType) {
            this->populateTables(child, root);
        }
        this->populateOne(child, root->fPopulators);
    }
}

void MdOut::resolveOut(const char* start, const char* end, Resolvable resolvable) {
    if ((Resolvable::kLiteral == resolvable || fLiteralAndIndent ||
            fResolveAndIndent) && end > start) {
        int linefeeds = 0;
        while ('\n' == *start) {
            ++linefeeds;
            ++start;
        }
        if (fResolveAndIndent && linefeeds) {
            this->lf(linefeeds);
        }
        const char* spaceStart = start;
        while (' ' == *start) {
            ++start;
        }
        if (start > spaceStart) {
            fIndent = start - spaceStart;
        }
    }
    if (Resolvable::kLiteral == resolvable || fLiteralAndIndent) {
        this->writeBlockTrim(end - start, start);
        if ('\n' == end[-1]) {
            this->lf(1);
        }
        fIndent = 0;
        return;
    }
    // FIXME: this needs the markdown character present when the def was defined,
    // not the last markdown character the parser would have seen...
    while (fBmhParser.fMC == end[-1]) {
        --end;
    }
    if (start >= end) {
        return;
    }
    string resolved = this->addReferences(start, end, resolvable);
    trim_end_spaces(resolved);
    if (resolved.length()) {
        TextParser paragraph(fFileName, &*resolved.begin(), &*resolved.end(), fLineCount);
        while (!paragraph.eof()) {
            while ('\n' == paragraph.peek()) {
                paragraph.next();
                if (paragraph.eof()) {
                    return;
                }
            }
            const char* lineStart = paragraph.fChar;
            paragraph.skipWhiteSpace();
            const char* contentStart = paragraph.fChar;
            if (fResolveAndIndent && contentStart > lineStart) {
                this->writePending();
                this->indentToColumn(contentStart - lineStart);
            }
            paragraph.skipToEndBracket('\n');
            ptrdiff_t lineLength = paragraph.fChar - contentStart;
            if (lineLength) {
                while (lineLength && contentStart[lineLength - 1] <= ' ') {
                    --lineLength;
                }
                string str(contentStart, lineLength);
                this->writeString(str.c_str());
                fWroteSomething = !!lineLength;
            }
            if (paragraph.eof()) {
                break;
            }
            if ('\n' == paragraph.next()) {
                int linefeeds = 1;
                if (!paragraph.eof() && '\n' == paragraph.peek()) {
                    linefeeds = 2;
                }
                this->lf(linefeeds);
            }
        }
    }
}

void MdOut::returnHeaderOut(const Definition** prior, Definition* def) {
    this->mdHeaderOut(3);
    FPRINTF("Return Value");
    if (MarkType::kPopulate != def->fMarkType && !this->checkParamReturnBody(def)) {
        *prior = def;
        return;
    }
    this->lf(2);
}

void MdOut::rowOut(string col1, const Definition* col2) {
    FPRINTF("%s", fOddRow ? kTR_Dark.c_str() : "  <tr>");
    this->lfAlways(1);
    FPRINTF("%s", kTD_Left.c_str());
    if ("" != col1) {
        this->writeString(col1);
    }
    FPRINTF("</td>");
    this->lfAlways(1);
    FPRINTF("%s", kTD_Left.c_str());
    TextParser parser(col2->fFileName, col2->fStart, col2->fContentStart, col2->fLineCount);
    parser.skipExact("#Method");
    parser.skipSpace();
    parser.trimEnd();
    string methodName(parser.fChar, parser.fEnd - parser.fChar);
    this->htmlOut(this->anchorRef("#" + col2->fFiddle, methodName));
    this->htmlOut("</td>");
    this->lfAlways(1);
    FPRINTF("  </tr>");
    this->lfAlways(1);
    fOddRow = !fOddRow;
}

void MdOut::rowOut(const char* name, string description, bool literalName) {
    FPRINTF("%s", fOddRow ? kTR_Dark.c_str() : "  <tr>");
    this->lfAlways(1);
    FPRINTF("%s", kTD_Left.c_str());
    if (literalName) {
        if (strlen(name)) {
            this->writeString(name);
        }
    } else {
        this->resolveOut(name, name + strlen(name), Resolvable::kYes);
    }
    FPRINTF("</td>");
    this->lfAlways(1);
    FPRINTF("%s", kTD_Left.c_str());
    this->resolveOut(&description.front(), &description.back() + 1, Resolvable::kYes);
    FPRINTF("</td>");
    this->lfAlways(1);
    FPRINTF("  </tr>");
    this->lfAlways(1);
    fOddRow = !fOddRow;
}

void MdOut::subtopicsOut(Definition* def) {
    Definition* csParent = def->csParent();
    const Definition* subtopicParent = def->subtopicParent();
    const Definition* topicParent = def->topicParent();
    SkASSERT(subtopicParent);
    this->lfAlways(1);
    FPRINTF("%s", kTableDeclaration);
    this->lfAlways(1);
    FPRINTF("%s", kTopicsTableHeader);
    this->lfAlways(1);
    fOddRow = true;
    for (auto item : SubtopicKeys::kGeneratedSubtopics) {
        if (SubtopicKeys::kMemberFunctions == item) {
            continue;
        }
        for (auto entry : fRoot->populator(item).fMembers) {
            if ((csParent && entry->csParent() == csParent)
                    || entry->subtopicParent() == subtopicParent) {
                if (SubtopicKeys::kRelatedFunctions == item) {
                    (void) subtopicRowOut(entry->fName, entry); // report all errors
                    continue;
                }
                auto popItem = fPopulators.find(item);
                string description = popItem->second.fOneLiner;
                if (SubtopicKeys::kConstructors == item) {
                    description += " " + fRoot->fName;
                }
                string subtopic;
                if (subtopicParent != topicParent) {
                    subtopic = subtopicParent->fName + '_';
                }
                string link = this->anchorLocalRef(subtopic + item, popItem->second.fPlural);
                this->rowOut(link.c_str(), description, true);
                break;
            }
        }
    }
    FPRINTF("</table>");
    this->lfAlways(1);
}

void MdOut::subtopicOut(string name) {
    const Definition* topicParent = fSubtopic ? fSubtopic->topicParent() : nullptr;
    Definition* csParent = fRoot && fRoot->isStructOrClass() ? fRoot : this->csParent();
    if (!csParent) {
        auto csIter = std::find_if(topicParent->fChildren.begin(), topicParent->fChildren.end(),
                [](const Definition* def){ return MarkType::kEnum == def->fMarkType
                || MarkType::kEnumClass == def->fMarkType; } );
        SkASSERT(topicParent->fChildren.end() != csIter);
        csParent = *csIter;
    }
    SkASSERT(csParent);
    this->lfAlways(1);
    if (fPopulators.end() != fPopulators.find(name)) {
        const SubtopicDescriptions& tableDescriptions = this->populator(name);
        this->anchorDef(name, tableDescriptions.fPlural);
        this->lfAlways(1);
        if (tableDescriptions.fDetails.length()) {
            string details = csParent->fName;
            details += " " + tableDescriptions.fDetails;
            this->writeString(details);
            this->lfAlways(1);
        }
    } else {
        this->anchorDef(name, name);
        this->lfAlways(1);
    }
    if (SubtopicKeys::kMembers == name) {
        return; // members output their own table
    }
    const RootDefinition::SubtopicContents& tableContents = fRoot->populator(name.c_str());
    if (SubtopicKeys::kTypedefs == name && fSubtopic && MarkType::kTopic == fSubtopic->fMarkType) {
        topicParent = fSubtopic;
    }
    this->subtopicOut(name, tableContents.fMembers, csParent, topicParent,
            tableContents.fShowClones);
}

void MdOut::subtopicOut(string key, const vector<Definition*>& data, const Definition* csParent,
        const Definition* topicParent, bool showClones) {
    this->writeString(kTableDeclaration);
    this->lfAlways(1);
    this->writeSubtopicTableHeader(key);
    this->lfAlways(1);
    fOddRow = true;
    std::map<string, const Definition*> items;
    for (auto entry : data) {
        if (!BmhParser::IsExemplary(entry)) {
            continue;
        }
        if (entry->csParent() != csParent && entry->topicParent() != topicParent) {
            continue;
        }
        size_t start = entry->fName.find_last_of("::");
        if (MarkType::kConst == entry->fMarkType && entry->fParent
                && MarkType::kEnumClass == entry->fParent->fMarkType
                && string::npos != start && start > 1) {
            start = entry->fName.substr(0, start - 1).rfind("::");
        }
        string entryName = entry->fName.substr(string::npos == start ? 0 : start + 1);
        items[entryName] = entry;
    }
    for (auto entry : items) {
        if (!this->subtopicRowOut(entry.first, entry.second)) {
            return;
        }
        if (showClones && entry.second->fCloned) {
            int cloneNo = 2;
            string builder = entry.second->fName;
            if ("()" == builder.substr(builder.length() - 2)) {
                builder = builder.substr(0, builder.length() - 2);
            }
            builder += '_';
            this->rowOut("overloads", entry.second);
            do {
                string match = builder + to_string(cloneNo);
                auto child = csParent->findClone(match);
                if (!child) {
                    break;
                }
                this->rowOut("", child);
            } while (++cloneNo);
        }
    }
    FPRINTF("</table>");
    this->lf(2);
}

bool MdOut::subtopicRowOut(string keyName, const Definition* entry) {
    const Definition* oneLiner = nullptr;
    for (auto child : entry->fChildren) {
        if (MarkType::kLine == child->fMarkType) {
            oneLiner = child;
            break;
        }
    }
    if (!oneLiner) {
        TextParser parser(entry->fFileName, entry->fStart,
                entry->fContentStart, entry->fLineCount);
        return parser.reportError<bool>("missing #Line");
    }
    TextParser dummy(entry); // for reporting errors, which we won't do
    if (!this->isDefined(dummy, Resolvable::kOut)) {
        keyName = entry->fName;
        size_t doubleColon = keyName.find("::");
        SkASSERT(string::npos != doubleColon);
        keyName = keyName.substr(doubleColon + 2);
    }
    this->rowOut(keyName.c_str(), string(oneLiner->fContentStart,
            oneLiner->fContentEnd - oneLiner->fContentStart), false);
    return true;
}

void MdOut::writeSubtopicTableHeader(string key) {
    this->htmlOut("<tr>");
    this->htmlOut(kTH_Left);
    if (fPopulators.end() != fPopulators.find(key)) {
        this->writeString(fPopulators[key].fSingular);
    } else {
        this->writeString("Function");
    }
    this->htmlOut("</th>");
    this->lf(1);
    this->htmlOut(kTH_Left);
    this->writeString("Description");
    this->htmlOut("</th>");
    this->htmlOut("</tr>");
}

#undef kTH_Left
