1 // =================================
 2 // Copyright (c) 2020 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 #include <gendoc/html/HtmlLexerFileSourceGenerator.hpp>
 7 #include <gendoc/html/LexerFileSourceLineParser.hpp>
 8 #include <sngxml/dom/CharacterData.hpp>
 9 #include <soulng/util/Path.hpp>
10 #include <soulng/util/Unicode.hpp>
11 #include <soulng/util/TextUtils.hpp>
12 #include <fstream>
13 
14 namespace gendoc { namespace html {
15 
16 using namespace soulng::util;
17 using namespace soulng::unicode;
18 
19 HtmlLexerFileSourceGenerator::HtmlLexerFileSourceGenerator(const std::u32string& projectName_const std::std::vector<std::u32string>&inputLines_intnumDigits_conststd::string&styleDirName_
20     const std::string& styleFileName_) :
21     projectName(projectName_)inputLines(inputLines_)numDigits(numDigits_)styleFilePath(Path::Combine(Path::Combine("../.."styleDirName_)styleFileName_))
22 {
23     htmlElement.reset(new sngxml::dom::Element(U"html"));
24 }
25 
26 void HtmlLexerFileSourceGenerator::Visit(SourceFileNode& sourceFileNode)
27 {
28     std::unique_ptr<sngxml::dom::Element> headElement(new sngxml::dom::Element(U"head"));
29     std::unique_ptr<sngxml::dom::Element> metaElement(new sngxml::dom::Element(U"meta"));
30     metaElement->SetAttribute(U"charset"U"utf-8");
31     headElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(metaElement.release()));
32     std::unique_ptr<sngxml::dom::Element> titleElement(new sngxml::dom::Element(U"title"));
33     titleElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(new sngxml::dom::Text(sourceFileNode.ProjectName() + U"/" + ToUtf32(sourceFileNode.RelativeSourceFilePath()))));
34     std::unique_ptr<sngxml::dom::Element> linkElement(new sngxml::dom::Element(U"link"));
35     linkElement->SetAttribute(U"rel"U"stylesheet");
36     linkElement->SetAttribute(U"type"U"text/css");
37     std::u32string relativeStyleFilePath = ToUtf32(styleFilePath);
38     linkElement->SetAttribute(U"href"relativeStyleFilePath);
39     headElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(linkElement.release()));
40     htmlElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(headElement.release()));
41     bodyElement.reset(new sngxml::dom::Element(U"body"));
42     currentSourceLineNumber = 1;
43     for (const auto& line : inputLines)
44     {
45         OpenLine();
46         ParseLexerFileSourceLine(linewriter);
47         CloseLine();
48     }
49     std::ofstream htmlFile(sourceFileNode.HtmlSourceFilePath());
50     CodeFormatter formatter(htmlFile);
51     formatter.SetIndentSize(1);
52     htmlElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(bodyElement.release()));
53     htmlSourceFileDocument.AppendChild(std::unique_ptr<sngxml::dom::Node>(htmlElement.release()));
54     htmlSourceFileDocument.Write(formatter);
55 }
56 
57 void HtmlLexerFileSourceGenerator::OpenLine()
58 {
59     lineElement.reset(new sngxml::dom::Element(U"span"));
60     writer.SetLineElement(lineElement.get());
61     lineElement->SetAttribute(U"class"U"code");
62     lineElement->SetAttribute(U"xml:space"U"preserve");
63     lineElement->SetAttribute(U"id"ToUtf32(std::to_string(currentSourceLineNumber)));
64     std::u32string lineNumberText = FormatNumber(currentSourceLineNumbernumDigits);
65     writer.WriteLineNumberKind(lineNumberTextWriteKind::line);
66     writer.WriteSpaceKind(1WriteKind::line);
67 }
68 
69 void HtmlLexerFileSourceGenerator::CloseLine()
70 {
71     bodyElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(lineElement.release()));
72     bodyElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(new sngxml::dom::Element(U"br")));
73     ++currentSourceLineNumber;
74 }
75 
76 } } // namespace gendoc::html