1
2
3
4
5
6 #include <gendoc/html/HtmlParserFileSourceGenerator.hpp>
7 #include <gendoc/html/ParserFileSourceLineParser.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 HtmlParserFileSourceGenerator::HtmlParserFileSourceGenerator(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 HtmlParserFileSourceGenerator::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 ParseParserFileSourceLine(line, writer);
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 HtmlParserFileSourceGenerator::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(currentSourceLineNumber, numDigits);
65 writer.WriteLineNumberKind(lineNumberText, WriteKind::line);
66 writer.WriteSpaceKind(1, WriteKind::line);
67 }
68
69 void HtmlParserFileSourceGenerator::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 } }