diff --git a/src/ext/yuni/src/tools/CMakeLists.txt b/src/ext/yuni/src/tools/CMakeLists.txt index 626318d9ea..94275110fa 100644 --- a/src/ext/yuni/src/tools/CMakeLists.txt +++ b/src/ext/yuni/src/tools/CMakeLists.txt @@ -6,8 +6,4 @@ endif(NOT YUNI_AUTO_COMPILE_YUNI_CONFIG) if (YUNI_MODULE_PARSER) add_subdirectory(parser-generator) -endif() - -if (YUNI_MODULE_DOCUMENTATION) - #add_subdirectory(yuni-docmake) -endif() +endif() \ No newline at end of file diff --git a/src/ext/yuni/src/tools/yuni-docmake/CMakeLists.txt b/src/ext/yuni/src/tools/yuni-docmake/CMakeLists.txt deleted file mode 100644 index 0a8277796d..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/CMakeLists.txt +++ /dev/null @@ -1,131 +0,0 @@ - -YMESSAGE("") -YMESSAGE_BOLD("edln-make") - -include("${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/common-settings.cmake") -include("${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules.cmake") - - -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../..") -include_directories(tinyxml) - - -# Writing index-db.hxx -file(STRINGS make/index-db.sql INDEX_DB) -set(HXX_FILE "\n\n") -set(HXX_FILE "${HXX_FILE}namespace DocIndex\n") -set(HXX_FILE "${HXX_FILE}{\n") -set(HXX_FILE "${HXX_FILE}namespace // anonymous\n") -set(HXX_FILE "${HXX_FILE}{\n") -set(HXX_FILE "${HXX_FILE}\n\ttemplate\n") -set(HXX_FILE "${HXX_FILE}\tstatic void PrepareSQLScript(StringT& out)\n") -set(HXX_FILE "${HXX_FILE}\t{\n") -set(HXX_FILE "${HXX_FILE}\t\tout.clear()\n") -foreach(l ${INDEX_DB}) - string(REPLACE "\"" "\\\"" sline "${l}") - set(HXX_FILE "${HXX_FILE}\t\t\t<< \"${sline}\\n\"\n") -endforeach() -set(HXX_FILE "${HXX_FILE}\t\t\t;\n") -set(HXX_FILE "${HXX_FILE}\t}\n\n\n") -set(HXX_FILE "${HXX_FILE}} // anonymous namespace\n") -set(HXX_FILE "${HXX_FILE}} // namespace DocIndex\n\n") -file(WRITE make/index-db.hxx "${HXX_FILE}") - -# Writing webpage.hxx -file(STRINGS make/webpage.html WEBPAGE_HTML) -set(HXX_FILE "\n\n") -set(HXX_FILE "${HXX_FILE}namespace // anonymous\n") -set(HXX_FILE "${HXX_FILE}{\n") -set(HXX_FILE "${HXX_FILE}\n\ttemplate\n") -set(HXX_FILE "${HXX_FILE}\tstatic void PrepareWebPageHtml(StringT& out)\n") -set(HXX_FILE "${HXX_FILE}\t{\n") -set(HXX_FILE "${HXX_FILE}\t\tout.clear()\n") -foreach(l ${WEBPAGE_HTML}) - string(REPLACE "\"" "\\\"" sline "${l}") - set(HXX_FILE "${HXX_FILE}\t\t\t<< \"${sline}\\n\"\n") -endforeach() -set(HXX_FILE "${HXX_FILE}\t\t\t;\n") -set(HXX_FILE "${HXX_FILE}\t}\n\n\n\n") - -set(HXX_FILE "${HXX_FILE}} // anonymous namespace\n") -set(HXX_FILE "${HXX_FILE}\n\n") -file(WRITE make/webpage.hxx "${HXX_FILE}") - - - -add_library(edln-make-static-tinyxml STATIC - tinyxml/tinystr.cpp - tinyxml/tinystr.h - tinyxml/tinyxml.cpp - tinyxml/tinyxml.h - tinyxml/tinyxmlerror.cpp - tinyxml/tinyxmlparser.cpp - ) - - -add_executable(edln-make - sqlite/sqlite3.c - sqlite/sqlite3.h - sqlite/sqlite3ext.h - make/article.h - make/article.cpp - make/dictionary.h - make/dictionary.cpp - make/program.h - make/program.cpp - make/program-find-all-source-files.cpp - make/job.h - make/job.cpp - make/job-writer.h - make/job-writer.cpp - logs.h - logs.cpp - make/main.cpp - make/indexes.h - make/indexes.cpp - make/index-db.hxx -) - -target_link_libraries(edln-make - yuni-static-core - edln-make-static-tinyxml) - -if(UNIX AND NOT APPLE) - # The DL library is required on Unixes for using SQlite - target_link_libraries(edln-make dl) -endif() - - - -# --- -# --- dox2article -# --- - -# Build the in-tree version of yuni-config. -add_executable(edln-dox2article - dox2article/main.cpp - dox2article/compound.h - dox2article/compound.hxx - dox2article/compound.cpp - dox2article/options.h - dox2article/options.cpp - dox2article/read-index.h - dox2article/read-index.cpp - dox2article/job.h - dox2article/job.cpp - dox2article/job-compound-explorer.h - dox2article/job-compound-explorer.cpp - dox2article/job-compound-writer.h - dox2article/job-compound-writer.cpp - dox2article/indexes.h - dox2article/indexes.cpp - dox2article/toolbox.h - logs.h - logs.cpp -) - -target_link_libraries(edln-dox2article - yuni-static-core - edln-make-static-tinyxml) - - diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.cpp deleted file mode 100644 index 4810caac23..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.cpp +++ /dev/null @@ -1,69 +0,0 @@ - -#include "compound.h" - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -Compound::Map allSymbolsByRefID; - -Compound::MapPerKind allSymbols = nullptr; - -Compound::MapPerKind allSymbolsByName = nullptr; - -Compound::Compound() : parent(nullptr) -{ -} - -Compound::~Compound() -{ -} - -void Compound::prepare() -{ - name.trim("\t\n "); - htdocs.clear(); - brief.clear(); - description.clear(); - switch (kind) - { - case kdFunction: - break; - case kdTypedef: - break; - case kdClass: - htdocs << "class/" << name; - break; - case kdNamespace: - htdocs << "namespace/" << name; - break; - case kdVariable: - break; - case kdEnum: - break; - case kdFile: - break; - case kdFolder: - break; - case kdGroup: - break; - case kdFriend: - break; - case kdUnknown: - break; - case kdMax: - break; - } - - if (!htdocs && parent) - htdocs = parent->htdocs; - - htdocs.replace("::", "/"); - htdocs.toLower(); -} - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.h deleted file mode 100644 index a48c87825c..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_COMPOUND_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_COMPOUND_H__ - -#include -#include -#include -#include -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -//! Any kind of compound -enum CompoundType -{ - kdUnknown = 0, - kdNamespace, - kdClass, - kdTypedef, - kdEnum, - kdFunction, - kdVariable, - kdFile, - kdFolder, - kdGroup, - kdFriend, - kdMax -}; - -class Parameter -{ -public: - typedef SmartPtr Ptr; - typedef std::vector Vector; - -public: - String name; - String type; -}; - -class Member -{ -public: - typedef SmartPtr Ptr; - typedef std::vector Vector; - -public: - CompoundType kind; - String id; - String htmlID; - String name; - String brief; - String detailedDescription; - CString<16, false> visibility; - String type; - bool isStatic; - bool isConst; - bool isExplicit; - bool isInline; - Parameter::Vector parameters; - Parameter::Vector templates; - -}; // class Member - -class Section -{ -public: - typedef SmartPtr
Ptr; - typedef std::deque Deque; - typedef std::vector Vector; - -public: - String caption; - CString<32, false> kind; - CString<16, false> visibility; - bool isStatic; - Member::Vector members; - -}; // class Section - -class Compound -{ -public: - //! Reference ID - typedef CString<256, false> RefID; - //! The most suitable smart ptr - typedef SmartPtr Ptr; - //! Map - typedef std::map Map; - //! Deque - typedef std::deque Deque; - - //! All symbols, ordered by their type - typedef Map* MapPerKind; - -public: - template - static CompoundType StringToKind(const StringT& str); - template - static void AppendKindToString(StreamT& out, CompoundType kind); - -public: - Compound(); - ~Compound(); - - void prepare(); - -public: - //! Kind of compound - CompoundType kind; - //! Reference ID - RefID refid; - //! - String name; - - String htdocs; - - //! Brief - String brief; - //! Detailed description - String description; - - Map members; - - //! The parent compound - Compound* parent; - //! All sections - Section::Vector sections; - -}; // class Compound - -//! All symbols ordered by their reference id -extern Compound::Map allSymbolsByRefID; - -//! All symbols, ordered by their type and their reference id -extern Compound::MapPerKind allSymbols; - -//! All symbols, ordered by their type and their name -extern Compound::MapPerKind allSymbolsByName; - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#include "compound.hxx" - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_COMPOUND_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.hxx b/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.hxx deleted file mode 100644 index 6b4699b930..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/compound.hxx +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_COMPOUND_HXX__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_COMPOUND_HXX__ - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -template -CompoundType Compound::StringToKind(const StringT& str) -{ - if (str == "function") - return kdFunction; - else if (str == "class") - return kdClass; - else if (str == "struct") - return kdClass; - else if (str == "variable") - return kdVariable; - else if (str == "typedef") - return kdTypedef; - else if (str == "enum") - return kdEnum; - else if (str == "file") - return kdFile; - else if (str == "namespace") - return kdNamespace; - else if (str == "dir") - return kdFolder; - else if (str == "group") - return kdGroup; - else if (str == "friend") - return kdFriend; - return kdUnknown; -} - -template -void Compound::AppendKindToString(StreamT& out, CompoundType kind) -{ - switch (kind) - { - case kdClass: - out << "class"; - break; - case kdNamespace: - out << "namespace"; - break; - case kdFunction: - out << "function"; - break; - case kdTypedef: - out << "typedef"; - break; - case kdEnum: - out << "enum"; - break; - case kdVariable: - out << "variable"; - break; - case kdFile: - out << "file"; - break; - case kdFolder: - out << "folder"; - break; - case kdGroup: - out << "group"; - break; - case kdFriend: - out << "friend"; - break; - case kdUnknown: - break; - case kdMax: - break; - } -} - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_COMPOUND_HXX__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/indexes.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/indexes.cpp deleted file mode 100644 index 401504a98e..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/indexes.cpp +++ /dev/null @@ -1,141 +0,0 @@ - -#include "indexes.h" -#include -#include "../logs.h" -#include "options.h" -#include "compound.h" - -#define SEP IO::Separator - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -void CreateIndex() -{ - String filename; - filename << Options::target << SEP << "article.xml"; - IO::File::Stream file; - if (file.openRW(filename)) - { - file << "Doxygen\n" - << "\n" - << "" - << "\n\n" - << "

API Reference

\n" - << "

Beware: THIS DOCUMENTATION IS INCOMPLETE AND WE'RE CURRENTLY WORKING ON " - "IT

\n" - << "\n"; - } -} - -void CreateNamespaceIndex() -{ - String filename; - filename << Options::target << SEP << "namespace"; - if (!IO::Directory::Create(filename)) - return; - filename << SEP << "article.xml"; - IO::File::Stream file; - if (file.openRW(filename)) - { - file << "Namespaces\n\n"; - file << "

All namespaces

\n"; - file << "

This is a list of all namespaces in Yuni.

\n"; - file << "\n"; - file << ""; - unsigned int total = 0; - - Compound::Map::iterator end = allSymbolsByName[kdNamespace].end(); - for (Compound::Map::iterator i = allSymbolsByName[kdNamespace].begin(); i != end; ++i) - { - const Compound::Ptr compoundptr = i->second; - const Compound& compound = *compoundptr; - if (compound.name.find_first_of("<@") != String::npos) - continue; - - file << "\n"; - ++total; - } - - file << "
NameDescription
\n"; - file << "" << compound.name - << "\n"; - file << "
\n"; - switch (total) - { - case 0: - file << "

(no namespace)

"; - break; - case 1: - file << "

(total: 1 namespace)

"; - break; - default: - file << "

(total: " << total << " namespaces)

"; - break; - } - file << "\n"; - - logs.info() << "index: " << total << " namespaces"; - } -} - -void CreateClassIndex() -{ - String filename; - filename << Options::target << SEP << "class"; - if (!IO::Directory::Create(filename)) - return; - filename << SEP << "article.xml"; - IO::File::Stream file; - if (file.openRW(filename)) - { - file << "Classes\n\n"; - file << "

All classes

\n"; - file << "

This is a list of all classes in Yuni.

\n"; - file << "\n"; - file << ""; - unsigned int total = 0; - - Compound::Map::iterator end = allSymbolsByName[kdClass].end(); - for (Compound::Map::iterator i = allSymbolsByName[kdClass].begin(); i != end; ++i) - { - const Compound::Ptr compoundptr = i->second; - const Compound& compound = *compoundptr; - if (compound.name.find_first_of("<@") != String::npos) - continue; - - file << "\n"; - ++total; - } - - file << "
NameDescription
\n"; - file << "" << compound.name - << "\n"; - file << "
\n"; - switch (total) - { - case 0: - file << "

(no class)

"; - break; - case 1: - file << "

(total: 1 class)

"; - break; - default: - file << "

(total: " << total << " classes)

"; - break; - } - file << "\n"; - - logs.info() << "index: " << total << " classes"; - } -} - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/indexes.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/indexes.h deleted file mode 100644 index 5e21711961..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/indexes.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_INDEXES_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_INDEXES_H__ - -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -void CreateIndex(); - -void CreateNamespaceIndex(); - -void CreateClassIndex(); - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_INDEXES_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-explorer.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-explorer.cpp deleted file mode 100644 index d69b2191af..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-explorer.cpp +++ /dev/null @@ -1,670 +0,0 @@ - -#include "job-compound-explorer.h" -#include "../logs.h" -#include -#include "../tinyxml/tinyxml.h" -#include "options.h" -#include "toolbox.h" - -#define SEP Yuni::IO::Separator - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Job -{ -namespace // anonymous -{ -class XMLCompoundVisitor : public TiXmlVisitor -{ -public: - //! \name Constructor - //@{ - /*! - ** \brief Constructor - */ - XMLCompoundVisitor(Compound& compound, TiXmlDocument& document); - //! Destructor - virtual ~XMLCompoundVisitor(); - //@} - - virtual bool VisitEnter(const TiXmlDocument& /*doc*/); - - virtual bool VisitExit(const TiXmlDocument& /*doc*/); - - virtual bool VisitEnter(const TiXmlElement& element, const TiXmlAttribute* attr); - - virtual bool VisitExit(const TiXmlElement& element); - - virtual bool Visit(const TiXmlDeclaration& /*declaration*/); - virtual bool Visit(const TiXmlText& /*text*/); - virtual bool Visit(const TiXmlComment& /*comment*/); - virtual bool Visit(const TiXmlUnknown& /*unknown*/); - - Member::Ptr currentMember(); - - void startNewParagraph(String* text); - -private: - Compound& pCompound; - //! - bool pInCompoundDef; - bool pInSectionHeader; - bool pInMemberDef; - bool pInMemberDefName; - bool pInMemberDefinition; - bool pInMemberParam; - bool pInMemberBrief; - bool pInMemberDetailedDescription; - bool pInMemberTemplates; - //! XML document - TiXmlDocument& pDocument; - //! - Section::Deque pSections; - - //! \name Paragraph - //@{ - //! - String* pCurrentParagraph; - //! Temporary string - String pS; - //! Codeline - unsigned int pParagraphCodelineCount; - //@} - -}; // class XMLCompoundVisitor - -XMLCompoundVisitor::XMLCompoundVisitor(Compound& compound, TiXmlDocument& document) : - pCompound(compound), - pInCompoundDef(false), - pInSectionHeader(false), - pInMemberDef(false), - pInMemberDefName(false), - pInMemberParam(false), - pInMemberBrief(false), - pInMemberDetailedDescription(false), - pInMemberTemplates(false), - pDocument(document), - pCurrentParagraph(nullptr) -{ -} - -XMLCompoundVisitor::~XMLCompoundVisitor() -{ -} - -Member::Ptr XMLCompoundVisitor::currentMember() -{ - if (!pSections.empty()) - { - Section::Ptr section = pSections.front(); - if (!(!section) && !section->members.empty()) - return section->members[section->members.size() - 1]; - } - return nullptr; -} - -bool XMLCompoundVisitor::VisitEnter(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLCompoundVisitor::VisitExit(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLCompoundVisitor::VisitEnter(const TiXmlElement& element, const TiXmlAttribute* /*attr*/) -{ - const TIXML_STRING& strname = element.ValueTStr(); - - if (strname == "memberdef") - { - if (pSections.empty()) - return true; - - Section::Ptr section = pSections.front(); - Member* member = new Member(); - member->id = element.Attribute("id"); - IO::ExtractFileName(member->htmlID, member->id); - member->kind = Compound::StringToKind(AnyString(element.Attribute("kind"))); - if (member->kind == kdUnknown) - logs.warning() << "unknown type: " << AnyString(element.Attribute("kind")); - member->visibility = element.Attribute("prot"); - member->isStatic = AnyString(element.Attribute("static")).to(); - member->isConst = AnyString(element.Attribute("const")).to(); - member->isExplicit = AnyString(element.Attribute("explicit")).to(); - member->isInline = AnyString(element.Attribute("inline")).to(); - - section->members.push_back(member); - pInMemberDef = true; - pInMemberDefName = false; - pInMemberDefinition = false; - pInMemberParam = false; - pInMemberBrief = false; - pInMemberDetailedDescription = false; - pCurrentParagraph = nullptr; - return true; - } - if (strname == "name") - { - if (pInMemberDef) - pInMemberDefName = true; - return true; - } - if (strname == "declname") - { - if (pInMemberDef && pInMemberParam) - pInMemberDefName = true; - return true; - } - if (strname == "templateparamlist") - { - if (pInMemberDef) - pInMemberTemplates = true; - } - if (strname == "type") - { - if (pInMemberDef) - pInMemberDefinition = true; - return true; - } - if (strname == "briefdescription") - { - if (pInMemberDef) - { - Member::Ptr member = currentMember(); - startNewParagraph((!member) ? nullptr : &(member->brief)); - pInMemberBrief = true; - } - else - startNewParagraph(&(pCompound.brief)); - return true; - } - if (strname == "detaileddescription") - { - if (pInMemberDef) - { - Member::Ptr member = currentMember(); - startNewParagraph((!member) ? nullptr : &(member->detailedDescription)); - pInMemberDetailedDescription = true; - } - else - startNewParagraph(&(pCompound.description)); - return true; - } - if (strname == "parameterlist") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
Parameters :
    "; - return true; - } - if (strname == "parameteritem") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
  • "; - } - if (strname == "parameternamelist") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ""; - } - if (strname == "programlisting") - { - if (pCurrentParagraph) - { - if (!pParagraphCodelineCount) - (*pCurrentParagraph) += ""; - } - return true; - } - if (strname == "computeroutput") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ""; - return true; - } - if (strname == "itemizedlist") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
      "; - return true; - } - if (strname == "listitem") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
    • "; - return true; - } - if (strname == "simplesect") - { - if (pCurrentParagraph) - { - AnyString kind = element.Attribute("kind"); - if (kind == "return") - (*pCurrentParagraph) += "
      return "; - else if (kind == "warning") - (*pCurrentParagraph) += "
      warning : "; - else if (kind == "see") - (*pCurrentParagraph) += "
      see : "; - else if (kind == "note") - (*pCurrentParagraph) += "
      note : "; - else if (kind == "remark") - (*pCurrentParagraph) += "
      remark : "; - else if (kind == "attention") - (*pCurrentParagraph) += "
      attention : "; - else - { - logs.warning() << "unmanaged simplesect '" << kind; - (*pCurrentParagraph) += "
      "; - } - } - return true; - } - - if (strname == "param") - { - if (pInMemberDef && !pCurrentParagraph) - { - Member::Ptr member = currentMember(); - if (!(!member)) - { - if (pInMemberTemplates) - member->templates.push_back(new Parameter()); - else - member->parameters.push_back(new Parameter()); - pInMemberParam = true; - } - } - return true; - } - if (strname == "sectiondef") - { - const AnyString stat = element.Attribute("static"); - Section* section = new Section(); - const AnyString kind = element.Attribute("kind"); - section->kind = kind; - section->visibility = element.Attribute("prot"); - section->isStatic = AnyString(element.Attribute("static")).to(); - pSections.push_front(section); - pInSectionHeader = false; - pInMemberDef = false; - pInMemberDefName = false; - pInMemberDefinition = false; - pInMemberBrief = false; - pInMemberDetailedDescription = false; - pCurrentParagraph = nullptr; - return true; - } - if (strname == "header") - { - if (pSections.empty()) - return false; - pInSectionHeader = true; - return true; - } - if (strname == "compounddef") - { - const AnyString id = element.Attribute("id"); - if (pCompound.refid == id) - { - pInCompoundDef = true; - pInMemberDef = false; - pInMemberDefName = false; - pInMemberDefinition = false; - pInMemberBrief = false; - pInMemberDetailedDescription = false; - pCurrentParagraph = nullptr; - } - return true; - } - return true; -} - -bool XMLCompoundVisitor::Visit(const TiXmlText& text) -{ - if (pInMemberDef && pInMemberDefName) - { - if (!pSections.empty()) - { - Section::Ptr section = pSections.front(); - if (!(!section) && !section->members.empty()) - { - Member::Ptr member = section->members[section->members.size() - 1]; - const TIXML_STRING& name = text.ValueTStr(); - if (pInMemberParam) - { - if (pInMemberTemplates) - { - if (!member->templates.empty()) - { - Parameter::Ptr& param = member->templates[member->templates.size() - 1]; - if (not param->name.empty()) - param->name += ' '; - param->name.append(name.c_str(), (unsigned int)name.size()); - } - } - else - { - if (!member->parameters.empty()) - { - Parameter::Ptr& param - = member->parameters[member->parameters.size() - 1]; - if (not param->name.empty()) - param->name += ' '; - param->name.append(name.c_str(), (unsigned int)name.size()); - } - } - } - else - member->name.append(name.c_str(), (unsigned int)name.size()); - } - } - return true; - } - if (pInMemberDef && pInMemberDefinition) - { - if (!pSections.empty()) - { - Section::Ptr section = pSections.front(); - if (!(!section) && !section->members.empty()) - { - Member::Ptr member = section->members[section->members.size() - 1]; - const TIXML_STRING& name = text.ValueTStr(); - - if (pInMemberParam) - { - if (pInMemberTemplates) - { - if (!member->templates.empty()) - { - Parameter::Ptr& param = member->templates[member->templates.size() - 1]; - if (not param->type.empty()) - param->type += ' '; - param->type.append(name.c_str(), (unsigned int)name.size()); - } - } - else - { - if (!member->parameters.empty()) - { - Parameter::Ptr& param - = member->parameters[member->parameters.size() - 1]; - if (not param->type.empty()) - param->type += ' '; - param->type.append(name.c_str(), (unsigned int)name.size()); - } - } - } - else - { - if (not member->type.empty()) - member->type += ' '; - member->type.append(name.c_str(), (unsigned int)name.size()); - } - } - } - return true; - } - if (pInSectionHeader) - { - Section::Ptr section = pSections.front(); - if (!(!section)) - { - const TIXML_STRING& name = text.ValueTStr(); - section->caption.append(name.c_str(), (unsigned int)name.size()); - } - return true; - } - - if (pCurrentParagraph) - { - const TIXML_STRING& name = text.ValueTStr(); - if (not(*pCurrentParagraph).empty()) - (*pCurrentParagraph) += ' '; - HtmlEntities(pS, AnyString(name.c_str(), (unsigned int)name.size())); - (*pCurrentParagraph) += pS; - return true; - } - - return true; -} - -bool XMLCompoundVisitor::Visit(const TiXmlComment&) -{ - return true; -} - -bool XMLCompoundVisitor::Visit(const TiXmlDeclaration&) -{ - return true; -} - -bool XMLCompoundVisitor::Visit(const TiXmlUnknown&) -{ - return true; -} - -bool XMLCompoundVisitor::VisitExit(const TiXmlElement& element) -{ - const TIXML_STRING& strname = element.ValueTStr(); - - if (strname == "memberdef") - { - pInMemberDef = false; - return true; - } - if (strname == "name") - { - if (pInMemberDef) - pInMemberDefName = false; - } - if (strname == "declname") - { - if (pInMemberDef && pInMemberParam) - pInMemberDefName = false; - } - if (strname == "type") - { - if (pInMemberDef) - pInMemberDefinition = false; - } - if (strname == "briefdescription") - { - if (pCurrentParagraph) - (*pCurrentParagraph).trim(); - pInMemberBrief = false; - pCurrentParagraph = nullptr; - } - if (strname == "detaileddescription") - { - if (pCurrentParagraph) - (*pCurrentParagraph).trim(); - pInMemberDetailedDescription = false; - pCurrentParagraph = nullptr; - } - if (strname == "parameterlist") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
    "; - } - if (strname == "parameteritem") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
  • "; - } - if (strname == "parameternamelist") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ""; - } - if (strname == "programlisting") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "\n"; - return true; - } - if (strname == "computeroutput") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ""; - return true; - } - if (strname == "codeline") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += '\n'; - return true; - } - if (strname == "itemizedlist") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += "
"; - return true; - } - if (strname == "para") - { - if (pCurrentParagraph && !(*pCurrentParagraph).endsWith("
")) - (*pCurrentParagraph) += "
"; - return true; - } - - if (strname == "listitem") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ""; - return true; - } - - if (strname == "sp") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ' '; - return true; - } - if (strname == "simplesect") - { - if (pCurrentParagraph) - (*pCurrentParagraph) += ""; - return true; - } - - if (strname == "templateparamlist") - { - if (pInMemberDef) - pInMemberTemplates = false; - return true; - } - if (strname == "param") - { - if (pInMemberDef) - pInMemberParam = false; - return true; - } - if (strname == "sectiondef") - { - pCompound.sections.push_back(pSections.front()); - pSections.pop_front(); - return true; - } - if (strname == "header") - { - pInSectionHeader = false; - return true; - } - if (strname == "compounddef") - { - pInCompoundDef = false; - return true; - } - return true; -} - -} // anonymous namespace - -void CompoundExplorer::Dispatch() -{ - typedef Compound::Map::iterator iterator; - - logs.info() << "reading class/namespace members"; - - // Namespaces - { - const iterator end = allSymbols[kdNamespace].end(); - for (iterator i = allSymbols[kdNamespace].begin(); i != end; ++i) - { - Compound::Ptr& compound = i->second; - queueService += new CompoundExplorer(compound); - } - } - // Classes - { - const iterator end = allSymbols[kdClass].end(); - for (iterator i = allSymbols[kdClass].begin(); i != end; ++i) - { - Compound::Ptr& compound = i->second; - queueService += new CompoundExplorer(compound); - } - } - - queueService.wait(); -} - -CompoundExplorer::CompoundExplorer(const Compound::Ptr& compound) : pCompound(compound) -{ -} - -CompoundExplorer::~CompoundExplorer() -{ -} - -void CompoundExplorer::onExecute() -{ - if (!pCompound) - return; - - Compound& compound = *pCompound; - if (!compound.refid) - return; - - TiXmlDocument doc; - - // Parsing the XML - { - String filename; - filename << Options::doxygenXMLIndex << SEP << compound.refid << ".xml"; - - if (!doc.LoadFile(filename.c_str(), TIXML_ENCODING_UTF8)) - { - logs.error() << "impossible to read the compound index: " << filename; - return; - } - } - - // Analyze the XML document - { - XMLCompoundVisitor visitor(compound, doc); - if (!doc.Accept(&visitor)) - return; - } -} - -void XMLCompoundVisitor::startNewParagraph(String* text) -{ - if (text) - { - (*text).clear(); - pCurrentParagraph = text; - pParagraphCodelineCount = 0; - } - else - pCurrentParagraph = nullptr; -} - -} // namespace Job -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-explorer.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-explorer.h deleted file mode 100644 index 48d47aab5e..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-explorer.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_COMPOUND_EXPLORER_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_COMPOUND_EXPLORER_H__ - -#include -#include "job.h" -#include "compound.h" - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Job -{ -class CompoundExplorer : public Dox2Article::Job::IJob -{ -public: - /*! - ** \brief Explorer all known symbols - */ - static void Dispatch(); - -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Default constructor - ** - ** \param compound The compound to analyze - */ - CompoundExplorer(const Compound::Ptr& compound); - //! Destructor - virtual ~CompoundExplorer(); - //@} - -protected: - virtual void onExecute(); - -private: - //! Compound to analyze - Compound::Ptr pCompound; - -}; // class CompoundExplorer - -} // namespace Job -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_COMPOUND_EXPLORER_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-writer.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-writer.cpp deleted file mode 100644 index 7e90c8c44a..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-writer.cpp +++ /dev/null @@ -1,576 +0,0 @@ - -#include "job-compound-writer.h" -#include -#include -#include "../logs.h" -#include "options.h" -#include "toolbox.h" - -#define SEP IO::Separator - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Job -{ -namespace // anonymous -{ -static Atomic::Int<> GenerationNumericID; - -} // anonymous namespace - -void CompoundWriter::Dispatch() -{ - // Write articles - { - uint count = (uint)allSymbolsByRefID.size(); - switch (count) - { - case 0: - logs.info() << "No article"; - break; - case 1: - logs.info() << "writing 1 article"; - break; - default: - logs.info() << "writing " << count << " articles"; - break; - } - } - { - Compound::Map::iterator end = allSymbolsByRefID.end(); - for (Compound::Map::iterator i = allSymbolsByRefID.begin(); i != end; ++i) - { - Compound::Ptr& compound = i->second; - Edalene::Dox2Article::Job::queueService += new CompoundWriter(compound); - } - } - - queueService.wait(); -} - -CompoundWriter::CompoundWriter(Compound::Ptr& compound) : pCompound(compound) -{ -} - -CompoundWriter::~CompoundWriter() -{ -} - -void CompoundWriter::onExecute() -{ - if (!pCompound->name || pCompound->name.contains('@')) - return; - - switch (pCompound->kind) - { - case kdFunction: - break; - case kdTypedef: - break; - case kdClass: - buildClass(); - break; - case kdNamespace: - buildNamespace(); - break; - case kdVariable: - break; - case kdEnum: - break; - case kdFile: - break; - case kdFolder: - break; - case kdGroup: - break; - case kdFriend: - break; - case kdUnknown: - break; - case kdMax: - break; - } -} - -void CompoundWriter::buildClass() -{ - if (pCompound->name.find_first_of("<@") != String::npos) - return; - - String filename; - filename << Options::target << SEP << pCompound->htdocs; - if (!IO::Directory::Create(filename)) - return; - filename << SEP << "article.xml"; - - IO::File::Stream file; - if (file.openRW(filename)) - { - // Getting the name - const String& name = pCompound->name; - - fileOut.clear(); - - String pageTitle; - { - String tmp; - String::Size offset = name.find_last_of(":\\/"); - if (offset < name.size() && offset + 1 < name.size()) - pageTitle.append(name.c_str() + offset + 1, name.size() - (offset + 1)); - else - pageTitle << name; - PrepareTitle(tmp, pageTitle); - fileOut << "" << tmp << "\n"; - fileOut << "\n"; - fileOut << "\n"; - fileOut << "\n"; - fileOut << "\n"; - fileOut << "\n\n\n"; - - fileOut << "

"; - if (not pCompound->brief.empty()) - PrepareTitle(tmp, pCompound->brief); - else - PrepareTitle(tmp, pageTitle); - // in some cases, a final point is in the string, and it is not especially beautiful - fileOut << tmp; - fileOut << "

\n"; - } - - bool isAbstract = (pageTitle.first() == 'I'); - - OrderedSection sectionmap; - buildSectionMapping(sectionmap, isAbstract); - - if (!sectionmap.empty()) - { - // resetting temporary stream outputs - out.clear(); - for (uint i = 0; i != 2; ++i) - { - for (uint j = 0; j != (uint)kdMax; ++j) - outC[i][j].clear(); - } - - // Starting the table - out << "\n"; - - // iterating through all sections found - OrderedSection::const_iterator end = sectionmap.end(); - for (OrderedSection::const_iterator i = sectionmap.begin(); i != end; ++i) - { - // Append all sections found - Section::Vector::const_iterator send = i->second.end(); - for (Section::Vector::const_iterator j = i->second.begin(); j != send; ++j) - appendClassSection(/*section*/ *(*j), isAbstract); - } - - // End of table - out << "
\n\n\n"; - } - - // Writing the begining of the article (title...) - file << fileOut; - - // Preparing indexes from temporary buffers - fileOut.clear(); - for (uint i = 1; i < 2; --i) - { - for (uint j = 0; j != (uint)kdMax; ++j) - { - if (not outC[i][j].empty()) - appendClassIndex(fileOut, (i != 0) /*isPublic*/, (CompoundType)j, outC[i][j]); - } - } - - if (not fileOut.empty()) - fileOut << "

Detailed Description

"; - - if (not pCompound->description.empty()) - { - fileOut << "
" << pCompound->description - << "
\n"; - } - - // Writing indexes - file << fileOut; - // Writing detailed description - file << out; - } -} - -void CompoundWriter::buildNamespace() -{ - if (pCompound->name.find_first_of("<@") != String::npos) - return; - - String filename; - filename << Options::target << SEP << pCompound->htdocs; - if (!IO::Directory::Create(filename)) - return; - filename << SEP << "article.xml"; - - IO::File::Stream file; - if (file.openRW(filename)) - { - // Getting the name - const String& name = pCompound->name; - - file << ""; - String::Size offset = name.find_last_of(":\\/"); - if (offset < name.size() && offset + 1 < name.size()) - file.write(name.c_str() + offset + 1, name.size() - (offset + 1)); - else - file << name; - file << "\n"; - file << "\n"; - file << "\n"; - file << "\n"; - file << "\n\n"; - } -} - -void CompoundWriter::buildSectionMapping(OrderedSection& map, bool isAbstract) -{ - // just in case - map.clear(); - // Section ID - CString<48, false> id; - - uint count = (uint)pCompound->sections.size(); - for (uint i = 0; i != count; ++i) - { - const Section::Ptr& sectionptr = pCompound->sections[i]; - if (!sectionptr) // just in case - continue; - const Section& section = *sectionptr; - - if (section.kind.startsWith("public-")) - id = "0-public"; - else if (section.kind.startsWith("protected-")) - { - // Protected and private data should not be displayed when the class is not inherited - if (!isAbstract) - continue; - id = "1-protected"; - } - else if (section.kind.startsWith("private-")) - { - // Skipping all private members - continue; - } - else - id = "0-public"; - - // We will accept the fact that the first item is enough - // to determine the section order - // - // In the same time, this loop will filter empty sections - // (push_back will never be called) which may occur in some - // rare cases - uint memcount = (uint)section.members.size(); - for (uint j = 0; j != memcount; ++j) - { - const Member::Ptr& memberptr = section.members[j]; - const Member& member = *memberptr; - - // useless stuff - junk - if (member.name == "YUNI_STATIC_ASSERT") - continue; - if (member.kind == kdFriend) - continue; - - if (member.kind == kdFunction) - id += "-1-method"; - else if (member.kind == kdVariable) - id += "-2-vars"; - else - id += "-0-typedef-enum"; - - map[id].push_back(sectionptr); - break; - } - } -} - -void CompoundWriter::prepareClassSubtitle(const Section& section) -{ - subtitle = ""; - - if (not section.caption.empty()) - { - HtmlEntities(sectionName, section.caption); - subtitle << "

" << sectionName - << " " << visibility << "

\n"; - } - else - { - sectionName.clear(); - subtitle << "

" << visibility - << " " << visibility << "

\n"; - } - subtitle << "\n"; -} - -void CompoundWriter::appendClassSection(const Section& section, bool isAbstract) -{ - umlSymbol = '+'; - visibility.clear(); - bool isPublic = true; - - if (section.kind.startsWith("public-")) - visibility = "Public"; - else if (section.kind.startsWith("protected-")) - { - // Protected and private data should not be displayed when the class is not inherited - if (!isAbstract) - return; - visibility = "Protected"; - umlSymbol = '#'; - isPublic = false; - } - else if (section.kind.startsWith("private-")) - { - // Skipping all private members - return; - // visibility = "Private"; - // umlSymbol = '-'; - } - else - visibility = "Public"; - - // class subtitle - prepareClassSubtitle(section); - - bool subtitleAlreadyWritten = false; - bool firstIndexMember = true; - uint memcount = (uint)section.members.size(); - for (uint j = 0; j != memcount; ++j) - { - const Member::Ptr& memberptr = section.members[j]; - const Member& member = *memberptr; - if (member.name == "YUNI_STATIC_ASSERT") - continue; - if (member.kind == kdFriend) - continue; - - if (!subtitleAlreadyWritten) - { - out << subtitle; - subtitleAlreadyWritten = true; - } - - if (firstIndexMember && (member.kind == kdFunction || member.kind == kdTypedef)) - { - firstIndexMember = false; - Clob& outIx = outC[isPublic][member.kind]; - if (outIx.empty()) - { - outIx << ""; - outIx << "\n"; - } - - out << ""; - - id.clear() << member.name << '_' << (++GenerationNumericID) << DateTime::Now(); - id.replace('-', '_'); // prevent against int overflow - toggle.clear() << "toggleVisibility('" << id << "')"; - - HtmlEntities(name, member.name); - HtmlEntities(type, member.type); - ArrangeTypename(type); - - switch (member.kind) - { - case kdFunction: - out << ""; - - out << ""; - out << ""; - out << "\n"; - - } // each member -} - -void CompoundWriter::appendClassFunction(const Member& member, bool isPublic) -{ - Clob& outIx = outC[isPublic][kdFunction]; - if (outIx.empty()) - outIx << "

"; - } - else - outIx << "


"; - outIx << sectionName << "

"; - break; - case kdTypedef: - out << ""; - break; - case kdVariable: - out << ""; - break; - case kdEnum: - out << ""; - break; - default: - out << ""; - break; - } - out << "
"; - - if (not member.brief.empty()) - out << "" << member.brief << "
\n"; - out << ""; - - switch (member.kind) - { - case kdFunction: - appendClassFunction(member, isPublic); - break; - case kdTypedef: - appendClassTypedef(member, isPublic); - break; - case kdVariable: - appendClassVariable(); - break; - default: - out << "(unmanaged tag: " << (uint)member.kind << ")"; - break; - } - - out << "\n"; - - out << "
\n"; - out << "
\n
"; - - if (not member.detailedDescription.empty()) - out << member.detailedDescription; - - out << "\n
\n"; - out << "
"; - outIx << "\n"; -} - -void CompoundWriter::appendClassTypedef(const Member& member, bool isPublic) -{ - Clob& outIx = outC[isPublic][kdTypedef]; - if (outIx.empty()) - outIx << "
"; - if (member.isStatic) - outIx << "static "; - outIx << type << ' '; - outIx << ""; - - if (!member.templates.empty()) - { - out << "
"; - out << "template<"; - for (uint p = 0; p != member.templates.size(); ++p) - { - if (p) - out << ", "; - const Parameter::Ptr& paramstr = member.templates[p]; - const Parameter& param = *paramstr; - HtmlEntities(paramType, param.type); - HtmlEntities(paramName, param.name); - ArrangeTypename(paramType); - out << paramType << ' ' << paramName; - } - out << ">
\n"; - } - - if (name.first() == '~') - { - String t = name; - t.replace("~", " ~ "); - out << " " - << umlSymbol << ' ' << t << ""; - outIx << " " << t - << ""; - } - else - { - out << " " - << umlSymbol << ' ' << name << ""; - outIx << " " << name - << ""; - } - - out << ": "; - - if (member.isStatic) - out << "static "; - - out << type << " ("; - outIx << '('; - - for (uint p = 0; p != member.parameters.size(); ++p) - { - if (p) - { - out << ", "; - outIx << ", "; - } - const Parameter::Ptr& paramstr = member.parameters[p]; - const Parameter& param = *paramstr; - HtmlEntities(paramType, param.type); - HtmlEntities(paramName, param.name); - ArrangeTypename(paramType); - out << paramType << ' ' << paramName; - outIx << paramType << ' ' << paramName; - } - - out << ')'; - outIx << ')'; - - if (member.isConst) - { - out << " const"; - outIx << " const"; - } - out << ";\n"; - outIx << "
"; - out << "" << umlSymbol - << ' ' << name << "" - << ": typedef " << type << ";\n"; - outIx - << "" - << "\n"; -} - -void CompoundWriter::appendClassVariable() -{ - out << "" << umlSymbol << ' ' << name << ""; - out << ": " << type; - out << ';'; -} - -void CompoundWriter::appendClassIndex(Clob& output, - bool isPublic, - CompoundType compoundType, - const Clob& data) -{ - output << "

"; - if (isPublic) - output << "Public "; - else - output << "Protected "; - - Compound::AppendKindToString(output, compoundType); - output << "

\n"; - - output << "
"; - output << data; - output << "
typedef" << name << " : " << type << "
\n\n"; -} - -} // namespace Job -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-writer.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-writer.h deleted file mode 100644 index d597a6c9d5..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job-compound-writer.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_COMPOUND_WRITER_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_COMPOUND_WRITER_H__ - -#include -#include "job.h" -#include "compound.h" -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Job -{ -class CompoundWriter : public Yuni::Edalene::Dox2Article::Job::IJob -{ -public: - //! Ordered section - typedef std::map OrderedSection; - -public: - /*! - ** \brief Explorer all known symbols - */ - static void Dispatch(); - -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Constructor - */ - explicit CompoundWriter(Compound::Ptr& compound); - //! Destructor - virtual ~CompoundWriter(); - //@} - -protected: - virtual void onExecute(); - -private: - void buildClass(); - void buildNamespace(); - - //! Create the ordered list (Yuni Coding's style) of all sections - void buildSectionMapping(OrderedSection& map, bool isAbstract); - - void appendClassIndex(Clob& output, bool isPublic, CompoundType compoundType, const Clob& data); - void appendClassSection(const Section& section, bool isAbstract); - void prepareClassSubtitle(const Section& section); - void appendClassFunction(const Member& member, bool isPublic); - void appendClassTypedef(const Member& member, bool isPublic); - void appendClassVariable(); - -private: - Compound::Ptr pCompound; - - // Temporary buffer for stream output - Clob out; - //! Temporary stream output (protected / public | compound type) - Clob outC[2][kdMax]; - Clob fileOut; - - // Some temporary variables for class building - String lastVisibility; - String sectionName; - String name; - String type; - String paramType; - String paramName; - String id; - String toggle; - String subtitle; - String visibility; - char umlSymbol; - -}; // class CompoundWriter - -} // namespace Job -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_COMPOUND_WRITER_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/job.cpp deleted file mode 100644 index 1bcbbf2791..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -#include "job.h" - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Job -{ -Yuni::Job::QueueService<> queueService; - -} // namespace Job -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/job.h deleted file mode 100644 index a593cdc3cd..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/job.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_H__ - -#include -#include "job.h" -#include -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Job -{ -class IJob : public Yuni::Job::IJob -{ -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Default constructor - */ - IJob() - { - } - /*! - ** \brief Destructor - */ - virtual ~IJob() - { - } - //@} - -}; // class IJob - -//! The queue service -extern Yuni::Job::QueueService<> queueService; - -} // namespace Job -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_JOB_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/main.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/main.cpp deleted file mode 100644 index 1dcb002829..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -#include -#include "../logs.h" - -#include "compound.h" -#include "options.h" -#include "read-index.h" -#include "job-compound-explorer.h" -#include "job-compound-writer.h" -#include "indexes.h" - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -class Program -{ -public: - Program() - { - allSymbols = new Compound::Map[kdMax]; - allSymbolsByName = new Compound::Map[kdMax]; - } - - ~Program() - { - delete[] allSymbols; - delete[] allSymbolsByName; - } - - int operator()() const - { - logs.checkpoint() << "Edalene Doxygen to Article"; - - if (!ReadXMLCatalogIndex(Options::doxygenXMLIndex)) - return EXIT_FAILURE; - - // Start the queue service - Job::queueService.start(); - - // Analyze all symbols - Job::CompoundExplorer::Dispatch(); - - // Writing articles - Job::CompoundWriter::Dispatch(); - - Job::queueService.stop(); - - logs.info() << "writing index files"; - CreateNamespaceIndex(); - CreateClassIndex(); - CreateIndex(); - logs.info() << "done."; - - return 0; - } - -}; // class Program - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -int main(int /*argc*/, char** /*argv*/) -{ - logs.applicationName("edln-dox2article"); - Yuni::Edalene::Dox2Article::Program program; - return program(); -} diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/options.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/options.cpp deleted file mode 100644 index e9cd6fc764..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/options.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "options.h" - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Options -{ -String doxygenXMLIndex = "../../../docs/tmp/doxygen/xml"; - -String target = "../../../docs/src/001-en/200-documentation/002-v0.2/500-doxygen"; - -} // namespace Options -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/options.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/options.h deleted file mode 100644 index a666ed579f..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/options.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_OPTIONS_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_OPTIONS_H__ - -#include -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace Options -{ -extern String doxygenXMLIndex; - -extern String target; - -} // namespace Options -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_OPTIONS_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/read-index.cpp b/src/ext/yuni/src/tools/yuni-docmake/dox2article/read-index.cpp deleted file mode 100644 index ed09236658..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/read-index.cpp +++ /dev/null @@ -1,231 +0,0 @@ - -#include "read-index.h" -#include "compound.h" -#include "../logs.h" -// xml -#include "../tinyxml/tinyxml.h" - -#define SEP IO::Separator - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -namespace // anonymous -{ -class XMLIndexVisitor : public TiXmlVisitor -{ -public: - //! \name Constructor - //@{ - /*! - ** \brief Constructor - */ - XMLIndexVisitor(TiXmlDocument& document); - //! Destructor - virtual ~XMLIndexVisitor(); - //@} - - virtual bool VisitEnter(const TiXmlDocument& /*doc*/); - - virtual bool VisitExit(const TiXmlDocument& /*doc*/); - - virtual bool VisitEnter(const TiXmlElement& element, const TiXmlAttribute* attr); - - virtual bool VisitExit(const TiXmlElement& element); - - virtual bool Visit(const TiXmlDeclaration& /*declaration*/); - virtual bool Visit(const TiXmlText& /*text*/); - virtual bool Visit(const TiXmlComment& /*comment*/); - virtual bool Visit(const TiXmlUnknown& /*unknown*/); - -private: - //! XML document - TiXmlDocument& pDocument; - //! - Compound::Deque pStack; - //! Stats - unsigned int pStats[kdMax]; - //! - bool pInName; - //! - bool pTagMemberAlreadyEncountered; - -}; // class XMLIndexVisitor - -XMLIndexVisitor::XMLIndexVisitor(TiXmlDocument& document) : - pDocument(document), pInName(false), pTagMemberAlreadyEncountered(false) -{ - assert(&pDocument != NULL); - - for (unsigned int i = 0; i != kdMax; ++i) - pStats[i] = 0u; -} - -XMLIndexVisitor::~XMLIndexVisitor() -{ - CString<128, false> result; - CString<64, false> name; - - logs.info() << "Compound statistics from index"; - for (unsigned int i = 1; i != kdMax; ++i) - { - name.clear(); - Compound::AppendKindToString(name, (CompoundType)i); - - result.clear(); - result.resize(10, ' '); - result.overwriteRight(name); - - logs.info() << result << " : " << pStats[i]; - } -} - -bool XMLIndexVisitor::VisitEnter(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLIndexVisitor::VisitExit(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLIndexVisitor::VisitEnter(const TiXmlElement& element, const TiXmlAttribute* /*attr*/) -{ - const TIXML_STRING& strname = element.ValueTStr(); - - if (strname == "member" || strname == "compound") - { - pTagMemberAlreadyEncountered = false; - - const AnyString kind = element.Attribute("kind"); - const AnyString refid = element.Attribute("refid"); - - Compound::Ptr compound = new Compound(); - compound->kind = Compound::StringToKind(kind); - compound->refid = refid; - - ++pStats[compound->kind]; - allSymbolsByRefID[compound->refid] = compound; - allSymbols[compound->kind][compound->refid] = compound; - - if (!pStack.empty()) - { - Compound::Ptr parent = pStack.front(); - if (!(!parent)) - parent->members[compound->refid] = compound; - } - - pStack.push_front(compound); - pInName = false; - return true; - } - if (strname == "name") - { - if (!pTagMemberAlreadyEncountered && !pStack.empty()) - pInName = true; - return true; - } - - return true; -} - -bool XMLIndexVisitor::Visit(const TiXmlText& text) -{ - if (pInName && !pStack.empty()) - { - Compound::Ptr compound = pStack.front(); - assert(!(!compound)); - - const TIXML_STRING& name = text.ValueTStr(); - if (!name.empty()) - compound->name.append(name.c_str(), (unsigned int)name.size()); - } - return true; -} - -bool XMLIndexVisitor::Visit(const TiXmlComment&) -{ - return true; -} - -bool XMLIndexVisitor::Visit(const TiXmlDeclaration&) -{ - return true; -} - -bool XMLIndexVisitor::Visit(const TiXmlUnknown&) -{ - return true; -} - -bool XMLIndexVisitor::VisitExit(const TiXmlElement& element) -{ - const TIXML_STRING& strname = element.ValueTStr(); - - if (strname == "member" || strname == "compound") - { - // Reset in any case @pInName - pInName = false; - - if (pStack.empty()) // strange - should never happen - return true; - Compound::Ptr compound = pStack.front(); - assert(!(!compound) && "invalid compound"); - pStack.pop_front(); - - if (not compound->name.empty()) - allSymbolsByName[compound->kind][compound->name] = compound; - return true; - } - if (strname == "name") - { - pInName = false; - return true; - } - - return true; -} - -static void PrepareAllCompounds() -{ - const Compound::Map::iterator end = allSymbolsByRefID.end(); - for (Compound::Map::iterator i = allSymbolsByRefID.begin(); i != end; ++i) - (i->second)->prepare(); -} - -} // anonymous namespace - -bool ReadXMLCatalogIndex(const String& folder) -{ - TiXmlDocument doc; - - // Parsing the XML - { - String filename; - filename << folder << SEP << "index.xml"; - - if (!doc.LoadFile(filename.c_str(), TIXML_ENCODING_UTF8)) - { - logs.error() << "impossible to read the catalog index: " << filename; - return false; - } - } - - // Analyze the XML document - { - XMLIndexVisitor visitor(doc); - if (!doc.Accept(&visitor)) - return false; - } - - PrepareAllCompounds(); - return true; -} - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/read-index.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/read-index.h deleted file mode 100644 index 87869b38dc..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/read-index.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_READ_INDEX_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_READ_INDEX_H__ - -#include -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -/*! -** \brief Read the entire catalog index of a doxygen folder (index.xml) -*/ -bool ReadXMLCatalogIndex(const String& folder); - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_READ_INDEX_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/dox2article/toolbox.h b/src/ext/yuni/src/tools/yuni-docmake/dox2article/toolbox.h deleted file mode 100644 index 10cb83a4d0..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/dox2article/toolbox.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_TOOLBOX_H__ -#define __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_TOOLBOX_H__ - -#include -#include -#include -#include -#include - -namespace Yuni -{ -namespace Edalene -{ -namespace Dox2Article -{ -template -static void HtmlEntities(StringT& out, const AnyString& string) -{ - out = string; - out.replace("&", "&"); - out.replace("<", "<"); - out.replace(">", ">"); -} - -template -static void ArrangeTypename(StringT& string) -{ - string.replace(" *", "*"); - string.replace(" &", "&"); - string.replace(" < ", "<"); - string.replace(" > ", ">"); - string.replace(" >", ">"); - string.replace(" , ", ", "); -} - -template -static void PrepareTitle(StringT1& out, const StringT2& string) -{ - out = string; - out.replace("
", ""); - out.replace("
", ""); // should never happen - out.replace("", ""); - out.replace("", ""); - out.replace("", ""); - out.replace("", ""); - out.replace("
", ""); - out.replace("
", ""); - out.replace("

", ""); - out.replace("

", ""); - out.trim(" \t\r\n:.;"); -} - -} // namespace Dox2Article -} // namespace Edalene -} // namespace Yuni - -#endif // __YUNI_TOOL_DOCMAKE_DOXYGEN_2_ARTICLE_TOOLBOX_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/logs.cpp b/src/ext/yuni/src/tools/yuni-docmake/logs.cpp deleted file mode 100644 index b1bf8bba10..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/logs.cpp +++ /dev/null @@ -1,5 +0,0 @@ - - -#include "logs.h" - -DocMakeLogs logs; diff --git a/src/ext/yuni/src/tools/yuni-docmake/logs.h b/src/ext/yuni/src/tools/yuni-docmake/logs.h deleted file mode 100644 index ffa3d8c222..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/logs.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __YUNI_DOCMAKE_LOGS_H__ -#define __YUNI_DOCMAKE_LOGS_H__ - -#include -#include -#include - -typedef Yuni::Logs::StdCout<> DocMakeLogsHandlers; -typedef /*Yuni::Logs::Time<*/ - Yuni::Logs::ApplicationName>> /*>*/ - DocMakeLogsDecorators; - -typedef Yuni::Logs::Logger DocMakeLogs; - -extern DocMakeLogs logs; - -#endif // __YUNI_DOCMAKE_LOGS_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/article.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/article.cpp deleted file mode 100644 index 3522754c04..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/article.cpp +++ /dev/null @@ -1,157 +0,0 @@ - -#include "article.h" -#include "../logs.h" -#include "program.h" -#include "indexes.h" - -using namespace Yuni; -using namespace Yuni::Tool::DocMake; - -ArticleData::ArticleData() : error(true) -{ - allowedTagsInParagraph.insert("a"); - allowedTagsInParagraph.insert("b"); - allowedTagsInParagraph.insert("i"); - allowedTagsInParagraph.insert("u"); - allowedTagsInParagraph.insert("br"); - allowedTagsInParagraph.insert("code"); - allowedTagsInParagraph.insert("sub"); - allowedTagsInParagraph.insert("sup"); - allowedTagsInParagraph.insert("big"); - allowedTagsInParagraph.insert("button"); - allowedTagsInParagraph.insert("em"); - allowedTagsInParagraph.insert("img"); - allowedTagsInParagraph.insert("input"); - allowedTagsInParagraph.insert("kbd"); - allowedTagsInParagraph.insert("small"); - allowedTagsInParagraph.insert("span"); - allowedTagsInParagraph.insert("strong"); - allowedTagsInParagraph.insert("textarea"); -} - -ArticleData::~ArticleData() -{ -} - -void ArticleData::reset() -{ - assert(title.capacity() < 1024); - assert(accessPath.capacity() < 1024 * 1024); - - id = -1; - modificationTime = 0; - pageWeight = 1.0f; - coeff = 1.0f; - error = false; - order = (unsigned int)-1; - showTOC = true; - showHistory = true; - showQuickLinks = true; - directoryIndexContent = dicAll; - - language = "en"; - title.clear(); - tags.clear(); - directoryIndex.clear(); - accessPath.clear(); - tocItems.clear(); - wordCount.clear(); -} - -void ArticleData::tocAppend(unsigned int level, const String& caption) -{ - TOCItem* item = new TOCItem(); - String& itID = item->hrefID; - String& itCaption = item->caption; - - item->level = level; - itCaption = caption; - itCaption.trim(); - if (!itCaption) - itCaption = "Missing Header"; - - bool lastWasInvalid = true; - const String::const_utf8iterator end = itCaption.utf8end(); - for (String::const_utf8iterator i = itCaption.utf8begin(); i != end; ++i) - { - const char c = (char)*i; - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) - { - itID += c; - lastWasInvalid = false; - } - else - { - if (!lastWasInvalid) - itID += '_'; - lastWasInvalid = true; - } - } - itID.trim('_'); - itID.toLower(); - - // Adding line feed - itCaption.replace(". ", ".
"); - - // adding the new toc item - tocItems.push_back(item); -} - -void ArticleData::tocRefactoring() -{ - if (tocItems.size() <= 1) - { - tocItems.clear(); - showTOC = false; - } - else - { - typedef std::set Set; - Set set; - String tmp; - for (unsigned int i = 0; i != tocItems.size(); ++i) - { - TOCItem& item = *(tocItems[i]); - String& id = item.hrefID; - if (set.find(id) != set.end()) - { - for (unsigned int rank = 2; rank < 1000; ++rank) - { - tmp.clear() << id << '_' << rank; - if (set.find(tmp) == set.end()) - { - id << '_' << rank; - break; - } - } - } - set.insert(id); - - if (Program::debug) - logs.info() << " :: " << relativeFilename << ": h" << item.level << ' ' - << item.caption; - } - } -} - -void ArticleData::insertTags(const AnyString& text) -{ - if (!text) - return; - Dictionary::Tag::Vector list; - text.split(list, " ,;|\t\r\n/\\"); - if (!list.empty()) - { - const Dictionary::Tag::Vector::iterator end = list.end(); - for (Dictionary::Tag::Vector::iterator i = list.begin(); i != end; ++i) - { - (*i).toLower(); - tags.insert(*i); - } - } -} - -void ArticleData::reloadTagsFromDatabase() -{ - DocIndex::RetrieveTagList(*this); -} diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/article.h b/src/ext/yuni/src/tools/yuni-docmake/make/article.h deleted file mode 100644 index 4b8ec50afd..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/article.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef __YUNI_DOCMAKE_ARTICLE_H__ -#define __YUNI_DOCMAKE_ARTICLE_H__ - -#include -#include -#include "dictionary.h" -#include -#include - -class ArticleData -{ -public: - typedef std::deque CoeffStack; - - enum State - { - stNone = 0, - stTitle, - stTOCItem, - }; - - enum DirectoryIndexContent - { - //! The article won't appear in a directory index - dicNoIndex = 0, - //! Only the node will be added - dicNoFollow, - //! The node + all its children will be added - dicAll, - //! The maximum number of flags - dicMax, - }; - - class TOCItem - { - public: - typedef Yuni::SmartPtr Ptr; - typedef std::vector Vector; - - public: - //! Item level (1: h1, 2: h2) - unsigned int level; - //! ID - Yuni::String hrefID; - //! Caption - Yuni::String caption; - }; - -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Default constructor - */ - ArticleData(); - //! Destructor - ~ArticleData(); - //@} - - void reset(); - - void tocAppend(unsigned int level, const Yuni::String& caption); - void tocRefactoring(); - - /*! - ** \brief Insert a list of tags - ** - ** \param text A list of tags, separated by spaces or special characters - */ - void insertTags(const AnyString& text); - - void reloadTagsFromDatabase(); - -public: - //! Article ID - Yuni::sint64 id; - //! The original XML file - Yuni::String originalFilename; - //! Relative filename - Yuni::String relativeFilename; - //! The target filename within the htdocs folder - Yuni::String htdocsFilename; - - //! Language - Yuni::CString<16, false> language; - - //! Date of the last modification - Yuni::sint64 modificationTime; - - //! - Dictionary::TagSet allowedTagsInParagraph; - //! Page weight - float pageWeight; - //! The current coefficient - float coeff; - //! Title of the page - Yuni::String title; - - //! A non empty value to force the display of the access path - Yuni::String accessPath; - - //! An error has occured - bool error; - - //! Order - unsigned int order; - - //! Directory index - Yuni::String directoryIndex; - //! Flag to display the TOC (Table Of Content) - bool showTOC; - //! Flag to display quick links (on the left) - bool showQuickLinks; - //! Flag to display the page history - bool showHistory; - - //! SEO - Dictionary::WordsCount wordCount; - //! TOC items - TOCItem::Vector tocItems; - //! Tags - Dictionary::TagSet tags; - - //! Directory content index - DirectoryIndexContent directoryIndexContent; - -}; // class ArticleData - -#endif // __YUNI_DOCMAKE_ARTICLE_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/dictionary.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/dictionary.cpp deleted file mode 100644 index d39d9d5df3..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/dictionary.cpp +++ /dev/null @@ -1,61 +0,0 @@ - -#include "dictionary.h" -#include "../sqlite/sqlite3.h" -#include "indexes.h" -#include "../logs.h" -#include "program.h" - -using namespace Yuni; - -namespace Dictionary -{ -AllWords allWords; - -Yuni::Mutex mutex; - -WordID FindWordID(const Word& word) -{ - Yuni::MutexLocker locker(mutex); - const AllWords::const_iterator it = allWords.find(word); - if (it == allWords.end()) - return -1; - return it->second; -} - -void PreloadFromIndexDB() -{ - Yuni::MutexLocker locker(mutex); - allWords.clear(); - sqlite3* handle = (sqlite3*)DocIndex::DatabaseHandle(); - if (!handle) - return; - - char** result; - int rowCount, colCount; - if (SQLITE_OK - != sqlite3_get_table( - handle, "SELECT id,term FROM terms", &result, &rowCount, &colCount, NULL)) - return; - - if (rowCount) - { - if (!Tool::DocMake::Program::quiet) - { - if (rowCount == 1) - logs.info() << "Preloading 1 term from the index db"; - else - logs.info() << "Preloading " << rowCount << " terms from the index db"; - } - - unsigned int y = 2; - for (unsigned int row = 0; row < (unsigned int)rowCount; ++row) - { - const AnyString sid = result[y++]; - const Word term = result[y++]; - allWords[term] = sid.to(); - } - } - sqlite3_free_table(result); -} - -} // namespace Dictionary diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/dictionary.h b/src/ext/yuni/src/tools/yuni-docmake/make/dictionary.h deleted file mode 100644 index bc775670b3..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/dictionary.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __DICTIONARY_H__ -#define __DICTIONARY_H__ - -#include -#include -#include -#include - -namespace Dictionary -{ -//! A single word -typedef Yuni::CString<32, false> Word; -//! A single tag -typedef Yuni::CString<42, false> Tag; - -//! Word ID -typedef int WordID; - -/*! -** \brief Statistics for a single word -*/ -class WordStat -{ -public: - WordStat() : coeff(0.f), count(0) - { - } - float coeff; - unsigned int count; -}; - -//! Statistics for a set of words -typedef std::map WordsCount; - -//! Set of tags -typedef std::set TagSet; - -//! Association between a word and its ID -typedef std::map AllWords; - -extern Yuni::Mutex mutex; - -extern AllWords allWords; - -/*! -** \brief Preload data from the cache -*/ -void PreloadFromIndexDB(); - -/*! -** \brief -** \return -1 if not found -*/ -WordID FindWordID(const Word& word); - -} // namespace Dictionary - -#endif // __DICTIONARY_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/index-db.sql b/src/ext/yuni/src/tools/yuni-docmake/make/index-db.sql deleted file mode 100644 index c294852561..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/index-db.sql +++ /dev/null @@ -1,113 +0,0 @@ - --- --- Header --- -CREATE TABLE index_header ( - -- Version of the index cache - version INTEGER NOT NULL DEFAULT 1, - -- Flag to know if the whole index cache is marked as dirty - -- (means potentially invalid) - dirty INTEGER NOT NULL DEFAULT 0 -); - - - --- --- Articles --- -CREATE TABLE articles ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - -- Lang of the artcile - lang TEXT NOT NULL DEFAULT 'en', - -- original filename (absolute) - rel_path TEXT NOT NULL, - -- Target filename, relative to the htdocs - html_href TEXT NOT NULL UNIQUE, - -- Article's title - title TEXT NOT NULL, - -- SEO weight - weight REAL NOT NULL DEFAULT 1.0, - -- Order - parent_order INTEGER NOT NULL DEFAULT 1000, - -- Flag to know if the article should be rebuilt - dirty INTEGER NOT NULL DEFAULT 1, - -- The number of tags - tag_count INTEGER NOT NULL DEFAULT 0, - -- Flag to show the quick links - show_quick_links INTEGER NOT NULL DEFAULT 1, - -- Flag to show the history - show_history INTEGER NOT NULL DEFAULT 1, - -- Flag to show the table of content - show_toc INTEGER NOT NULL DEFAULT 1, - -- Timestamp of the last modification - modified INTEGER NOT NULL DEFAULT 0, - -- Flag to show the directory index - directory_index INTEGER NOT NULL DEFAULT 2, -- dicAll - -- The parent - parent TEXT NOT NULL, - force_access_path TEXT DEFAULT NULL, - dir_index TEXT DEFAULT NULL -); - -CREATE INDEX ix_art_relpath ON articles(rel_path); -CREATE INDEX ix_art_parent ON articles(parent); -CREATE INDEX ix_art_dirty ON articles(dirty); - - - --- --- Table of content --- -CREATE TABLE toc ( - html_href TEXT NOT NULL REFERENCES articles(html_href) ON DELETE CASCADE, - indx INTEGER NOT NULL, - lvl INTEGER NOT NULL, - href_id TEXT NOT NULL, - caption TEXT NOT NULL, - PRIMARY KEY (html_href,indx) -); - - --- --- SEO, terms --- -CREATE TABLE terms ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - weight_user REAL NOT NULL DEFAULT 1.0, - weight_rel_others REAL NOT NULL DEFAULT 1.0, - -- The total weight - weight REAL NOT NULL DEFAULT 1.0, - term TEXT NOT NULL UNIQUE -); - - --- --- SEO --- -CREATE TABLE terms_per_article ( - term_id INTEGER NOT NULL REFERENCES terms(id) ON DELETE CASCADE, - article_id INTEGER NOT NULL REFERENCES articles(id) ON DELETE CASCADE, - count_in_page INTEGER NOT NULL DEFAULT 0, - weight REAL NOT NULL DEFAULT 1.0 -); - - --- --- Tags per article --- -CREATE TABLE tags_per_article ( - article_id INTEGER NOT NULL REFERENCES articles(id) ON DELETE CASCADE, - tagname TEXT NOT NULL, - PRIMARY KEY (article_id, tagname) -); - - --- --- Dependencies --- -CREATE TABLE deps ( - input TEXT NOT NULL PRIMARY KEY, - html_href TEXT NOT NULL, - article_id INTEGER NOT NULL REFERENCES articles(id) ON DELETE CASCADE -); - diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/indexes.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/indexes.cpp deleted file mode 100644 index 594dd6767b..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/indexes.cpp +++ /dev/null @@ -1,985 +0,0 @@ - -#include "indexes.h" -#include "../sqlite/sqlite3.h" -#include -#include -#include -#include "../logs.h" -#include "index-db.hxx" -#include "program.h" -#ifndef YUNI_OS_WINDOWS -#include "stdlib.h" // man 3 system -#endif - -#define SEP IO::Separator - -using namespace Yuni; -using namespace Yuni::Tool::DocMake; - -namespace DocIndex -{ -namespace // anonymous -{ -enum -{ - dbVersion = 10, // arbitrary value -}; - -static sqlite3* gDB = nullptr; - -template -static sint64 RetrieveArticleID(const StringT& href) -{ - if (!gDB || !href) - return -1; - - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2(gDB, "SELECT id FROM articles WHERE html_href = $1", -1, &stmt, NULL)) - return -1; - sqlite3_bind_text(stmt, 1, href.c_str(), href.size(), NULL); - if (SQLITE_ROW != sqlite3_step(stmt)) - { - sqlite3_finalize(stmt); - return -1; - } - const AnyString id = (const char*)sqlite3_column_text(stmt, 0); - sint64 result; - if (!id.to(result)) - { - sqlite3_finalize(stmt); - return -1; - } - sqlite3_finalize(stmt); - return result; -} - -static bool ResetDBIndex(const String& filename) -{ - if (!Program::quiet) - logs.info() << "the index database needs to be rebuilt"; - - // Close the sqlite handle - Close(); - // Destroy the sqlite database - IO::File::Delete(filename); - // Try to reopen it - switch (sqlite3_open(filename.c_str(), &gDB)) - { - case SQLITE_OK: - break; - default: - logs.error() << "impossible to re-open the database after deletion."; - return false; - } - - Clob script; - char* message = nullptr; - - // Create tables - PrepareSQLScript(script); - if (SQLITE_OK != sqlite3_exec(gDB, script.c_str(), NULL, NULL, &message)) - { - logs.error() << "database: " << message; - sqlite3_free(message); - } - - script.clear() << "INSERT INTO index_header (version) VALUES (" << (unsigned int)dbVersion - << ");"; - if (SQLITE_OK != sqlite3_exec(gDB, script.c_str(), NULL, NULL, &message)) - { - logs.error() << "database: " << message; - sqlite3_free(message); - } - - return true; -} - -static bool UsePragma() -{ - // UTF-8 - if (SQLITE_OK != sqlite3_exec(gDB, "PRAGMA encoding = \"UTF-8\"; ", NULL, NULL, NULL)) - { - logs.error() << "impossible to use the UTF8 encoding"; - return false; - } - // Foreign keys - if (SQLITE_OK != sqlite3_exec(gDB, "PRAGMA foreign_keys = 1;", NULL, NULL, NULL)) - { - logs.error() << "impossible to enable foreign keys"; - return false; - } - return true; -} - -static bool CheckDatabaseIntegrity(const String& dbfilename) -{ - // prepare the SQL statement from the command line - static const char* const query = "SELECT version,dirty FROM index_header"; - - sqlite3_stmt* stmt; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query, -1, &stmt, 0)) - { - sqlite3_finalize(stmt); - if (!ResetDBIndex(dbfilename)) - return false; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query, -1, &stmt, 0)) - { - sqlite3_finalize(stmt); - stmt = nullptr; - if (!Program::quiet) - logs.info() << "The database index format needs update. Performing a full reindex"; - } - } - if (stmt && SQLITE_ROW == sqlite3_step(stmt)) - { - const AnyString version = (const char*)sqlite3_column_text(stmt, 0); - const AnyString dirty = (const char*)sqlite3_column_text(stmt, 1); - if (dirty.to()) - { - logs.info() << "The database index is marked as dirty. Performing a full reindex"; - } - else - { - if (version.to() == dbVersion) - { - sqlite3_finalize(stmt); - return true; - } - if (!Program::quiet) - logs.info() << "The database index format needs update. Performing a full reindex"; - } - } - sqlite3_finalize(stmt); - return ResetDBIndex(dbfilename); -} - -} // anonymous namespace - -void* DatabaseHandle() -{ - return gDB; -} - -bool Open() -{ - if (gDB) - { - sqlite3_close(gDB); - gDB = nullptr; - } - - if (Program::clean) - IO::File::Delete(Program::indexCacheFilename); - - switch (sqlite3_open(Program::indexCacheFilename.c_str(), &gDB)) - { - case SQLITE_OK: - { - if (!UsePragma() || !CheckDatabaseIntegrity(Program::indexCacheFilename)) - { - Close(); - return false; - } - break; - } - case SQLITE_PERM: - logs.error() << "not enough permissions to open " << Program::indexCacheFilename; - return false; - case SQLITE_BUSY: - logs.error() << "The index database is locked."; - return false; - case SQLITE_CORRUPT: - logs.error() << "The index database is malformed"; - return false; - case SQLITE_CANTOPEN: - logs.error() << "Unable to open " << Program::indexCacheFilename; - return false; - default: - return false; - } - - // Mark the database index as dirty - if (SQLITE_OK != sqlite3_exec(gDB, "UPDATE index_header SET dirty = 1", NULL, NULL, NULL)) - return false; - return true; -} - -void Close() -{ - if (gDB) - { - // Mark the database index as non-dirty - sqlite3_exec(gDB, "UPDATE index_header SET dirty = 0", NULL, NULL, NULL); - // Close the handle - sqlite3_close(gDB); - gDB = nullptr; - } -} - -void Vacuum() -{ - if (gDB) - sqlite3_exec(gDB, "VACUUM;", NULL, NULL, NULL); -} - -Yuni::sint64 ArticleLastModificationTimeFromCache(const String& filename) -{ - if (!filename) - return -1; - - // prepare the SQL statement from the command line - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2( - gDB, "SELECT modified FROM articles WHERE rel_path = $1", -1, &stmt, 0)) - return -1; - sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), NULL); - - if (SQLITE_ROW == sqlite3_step(stmt)) - { - const AnyString modified = (const char*)sqlite3_column_text(stmt, 0); - sint64 value; - if (!modified.to(value)) - value = -1; - sqlite3_finalize(stmt); - return value; - } - return -1; -} - -void Write(ArticleData& article) -{ - if (!gDB) - return; - - CString<256> query; - - // Delete the article, and all its data - query.clear() << "DELETE FROM articles WHERE rel_path = $1;"; - sqlite3_stmt* stmt = nullptr; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query.c_str(), -1, &stmt, NULL)) - logs.error() << "invalid SQL query " << query; - else - { - sqlite3_bind_text( - stmt, 1, article.relativeFilename.c_str(), article.relativeFilename.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - - String parent = article.htdocsFilename; - if (!parent) - parent = '/'; - else - { - String::Size offset = parent.find_last_of("/\\"); - if (offset < parent.size()) - { - if (!offset) - parent = '/'; - else - parent.resize(offset); - } - } - - // Insert the new article - { - query.clear() - << "INSERT INTO articles (parent_order, weight, show_quick_links" - << ", show_history" - << ", show_toc, modified, rel_path,html_href, title,parent,directory_index,lang)" - << " VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);"; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query.c_str(), -1, &stmt, NULL)) - { - logs.error() << "invalid SQL query: " << query; - return; - } - else - { - sqlite3_bind_int(stmt, 1, (int)article.order); - sqlite3_bind_double(stmt, 2, article.pageWeight); - sqlite3_bind_int(stmt, 3, (article.showQuickLinks ? 1 : 0)); - sqlite3_bind_int(stmt, 4, (article.showHistory ? 1 : 0)); // show history - sqlite3_bind_int(stmt, 5, (article.showTOC ? 1 : 0)); // show toc - sqlite3_bind_int64(stmt, 6, article.modificationTime); - sqlite3_bind_text( - stmt, 7, article.relativeFilename.c_str(), article.relativeFilename.size(), NULL); - sqlite3_bind_text( - stmt, 8, article.htdocsFilename.c_str(), article.htdocsFilename.size(), NULL); - sqlite3_bind_text(stmt, 9, article.title.c_str(), article.title.size(), NULL); - sqlite3_bind_text(stmt, 10, parent.c_str(), parent.size(), NULL); - sqlite3_bind_int(stmt, 11, (int)article.directoryIndexContent); - sqlite3_bind_text(stmt, 12, article.language.c_str(), article.language.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - } - - // Getting the article ID - article.id = RetrieveArticleID(article.htdocsFilename); - if (article.id < 0) - { - logs.error() << "Invalid article ID after inserting, " << article.htdocsFilename; - return; - } - - if (not article.accessPath.empty()) - { - query.clear() << "UPDATE articles SET force_access_path = $1 WHERE rel_path = $2;"; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query.c_str(), -1, &stmt, NULL)) - logs.error() << "invalid SQL query " << query; - else - { - sqlite3_bind_text(stmt, 1, article.accessPath.c_str(), article.accessPath.size(), NULL); - sqlite3_bind_text( - stmt, 2, article.relativeFilename.c_str(), article.relativeFilename.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - } - - if (not article.directoryIndex.empty()) - { -// We want UNIX-style paths -#ifdef YUNI_OS_WINDOWS - String directoryIndex = article.directoryIndex; - directoryIndex.replace('\\', '/'); -#else - const String& directoryIndex = article.directoryIndex; -#endif - query.clear() << "UPDATE articles SET dir_index = $1 WHERE rel_path = $2;"; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query.c_str(), -1, &stmt, NULL)) - logs.error() << "invalid SQL query " << query; - else - { - sqlite3_bind_text(stmt, 1, directoryIndex.c_str(), directoryIndex.size(), NULL); - sqlite3_bind_text( - stmt, 2, article.relativeFilename.c_str(), article.relativeFilename.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - } - - // TOC - if (!article.tocItems.empty()) - { - for (unsigned int i = 0; i != article.tocItems.size(); ++i) - { - // alias to the current TOC item - assert(article.tocItems[i] && "invalid toc item"); - const ArticleData::TOCItem& item = *(article.tocItems[i]); - - query.clear() << "INSERT INTO toc (html_href,indx,lvl,href_id,caption) VALUES ($1," << i - << ',' << item.level << ",$2,$3);"; - sqlite3_prepare_v2(gDB, query.c_str(), -1, &stmt, NULL); - sqlite3_bind_text( - stmt, 1, article.htdocsFilename.c_str(), article.htdocsFilename.size(), NULL); - sqlite3_bind_text(stmt, 2, item.hrefID.c_str(), item.hrefID.size(), NULL); - sqlite3_bind_text(stmt, 3, item.caption.c_str(), item.caption.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - } - - // Tags - if (!article.tags.empty()) - { - Dictionary::TagSet::const_iterator end = article.tags.end(); - for (Dictionary::TagSet::const_iterator i = article.tags.begin(); i != end; ++i) - { - const Dictionary::Tag& tagname = *i; - - query.clear() << "INSERT INTO tags_per_article (article_id,tagname) VALUES (" - << article.id << ",$1);"; - int error; - if (SQLITE_OK - == (error = sqlite3_prepare_v2(gDB, query.c_str(), query.size(), &stmt, NULL))) - { - sqlite3_bind_text(stmt, 1, tagname.c_str(), tagname.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - else - logs.error() << "impossible to register tag for " << article.htdocsFilename - << ", err." << error; - } - } -} - -void RemoveNonExistingEntries() -{ - if (!gDB) - return; - - if (!Program::quiet) - logs.info() << "Looking for deprecated entries in the database"; - - CString<512> s = "DELETE FROM articles WHERE rel_path = \"\";"; - { - sqlite3_stmt* stmt; - sqlite3_prepare_v2(gDB, s.c_str(), -1, &stmt, NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - - char** result; - int rowCount, colCount; - if (SQLITE_OK - != sqlite3_get_table( - gDB, "SELECT rel_path FROM articles", &result, &rowCount, &colCount, NULL)) - return; - - if (rowCount) - { - if (!Program::quiet) - { - if (rowCount == 1) - logs.info() << "1 article available in the index db"; - else - logs.info() << rowCount << " articles available in the index db"; - } - unsigned int y = 1; - for (unsigned int row = 0; row < (unsigned int)rowCount; ++row, ++y) - { - const AnyString relPath = result[y]; - s.clear() << Program::input << SEP << relPath; - if (!IO::File::Exists(s)) - { - if (!Program::quiet) - logs.info() << "The entry '" << relPath << "' is deprecated"; - - s.clear() << "DELETE FROM articles WHERE rel_path = $1;"; - sqlite3_stmt* stmt; - sqlite3_prepare_v2(gDB, s.c_str(), s.size(), &stmt, NULL); - sqlite3_bind_text(stmt, 1, relPath.c_str(), relPath.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - } - } - - sqlite3_free_table(result); -} - -bool AppendArticleTitleFromPath(String& out, const String& path) -{ - if (!gDB) - return false; - - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2( - gDB, "SELECT title FROM articles WHERE html_href = $1", -1, &stmt, NULL)) - return false; - sqlite3_bind_text(stmt, 1, path.c_str(), path.size(), NULL); - if (SQLITE_ROW != sqlite3_step(stmt)) - { - sqlite3_finalize(stmt); - return false; - } - const AnyString title = (const char*)sqlite3_column_text(stmt, 0); - if (!title) - { - sqlite3_finalize(stmt); - return false; - } - out += title; - sqlite3_finalize(stmt); - return true; -} - -namespace // anonymous -{ -static void InternalBuildDirectoryIndex(Clob& out, const String& path, unsigned int level) -{ -// We want UNIX-styles paths -#ifdef YUNI_OS_WINDOWS - String srcPath = path; - srcPath.replace('\\', '/'); -#else - const String& srcPath = path; -#endif - - char** result; - int rowCount, colCount; - String query = "SELECT title, html_href,directory_index FROM articles WHERE parent = \""; - query << srcPath << "\" AND directory_index > 0 ORDER BY parent_order ASC, title"; - if (SQLITE_OK != sqlite3_get_table(gDB, query.c_str(), &result, &rowCount, &colCount, NULL)) - return; - - if (!rowCount) - { - sqlite3_free_table(result); - return; - } - - if (!level) - { - for (unsigned int x = 0; x != level; ++x) - out << '\t'; - out << "
Directory Index
\n"; - } - for (unsigned int x = 0; x != level; ++x) - out << '\t'; - out << "
    \n"; - unsigned int y = 3; - for (unsigned int row = 0; row < (unsigned int)rowCount; ++row) - { - const AnyString title = result[y++]; - const String href = result[y++]; - unsigned int dic = AnyString(result[y++]).to(); - if (dic >= ArticleData::dicMax) - dic = ArticleData::dicAll; - - if (!href) // must not be empty - continue; - - for (unsigned int x = 0; x != level; ++x) - out << '\t'; - out << "
  • " << title << "
  • \n"; - - if (dic >= ArticleData::dicAll) - InternalBuildDirectoryIndex(out, href, level + 1); - } - - sqlite3_free_table(result); - - for (unsigned int x = 0; x != level; ++x) - out << '\t'; - out << "
\n"; - - if (!level) - { - for (unsigned int x = 0; x != level; ++x) - out << '\t'; - out << "
\n"; - } -} - -} // anonymous namespace - -void BuildDirectoryIndex(Clob& out, const String& path) -{ - out.clear(); - InternalBuildDirectoryIndex(out, path, 0); -} - -void BuildSitemap() -{ - String filename; - filename << Program::htdocs << SEP << "sitemap.xml"; - if (Program::verbose) - logs.info() << "writing " << filename; - - IO::File::Stream out; - if (!out.openRW(filename)) - { - logs.error() << "sitemap: impossible to write " << filename; - return; - } - - Clob dat; - // Begining of the sitemap - dat << "\n" - << "\n"; - - float weightMin = 0.f; - float weightMax = 0.f; - char** result; - int rowCount, colCount; - String href; - - // Looking for weights limits - { - const char* const query = "SELECT MIN(weight), MAX(weight) FROM articles WHERE weight > 0;"; - if (SQLITE_OK == sqlite3_get_table(gDB, query, &result, &rowCount, &colCount, NULL)) - { - if (rowCount == 1) - { - unsigned int y = 2; - const AnyString minW = result[y++]; - const AnyString maxW = result[y++]; - - weightMin = minW.to(); - weightMax = maxW.to(); - - if (Math::Equals(weightMin, weightMax)) - { - // The two values must not be equal to avoid a division by zero - weightMin -= 0.1f; - weightMax += 0.1f; - } - } - sqlite3_free_table(result); - } - } - - const char* const query - = "SELECT html_href,weight,modified FROM articles WHERE weight > 0.2 ORDER BY html_href"; - if (SQLITE_OK == sqlite3_get_table(gDB, query, &result, &rowCount, &colCount, NULL)) - { - String tmp; - - if (rowCount) - { - CString<64, false> formattedDate; - - unsigned int y = 3; - for (unsigned int row = 0; row < (unsigned int)rowCount; ++row) - { - href = result[y++]; - const AnyString weightStr = result[y++]; - const String modifiedStr = result[y++]; - - if (href.size() <= 1) // avoid invalid paths, such as '/' - continue; - - // Weight of the article - float weight = weightStr.to(); - - // Checking if the hef is less than 2048 chars - if (href.size() >= 2048) - { - logs.warning() << "sitemap: invalid href (> 2048 char), skipped : " << href; - continue; - } - - // Priority, for the sitemap (%) - float priority = ((weight - weightMin) / (weightMax - weightMin)); - if (priority < 0.1f) - priority = 0.1f; - else - { - if (priority > 1.f) - priority = 1.f; - } - - // Escaping - // TODO use a better routine for doing that - href.replace("&", "&"); - href.replace("'", "'"); - href.replace("\"", """); - href.replace("<", "<"); - href.replace("≤", "≤"); - href.replace(">", ">"); - href.replace("≥", "≥"); - href.replace("//", "/"); - - dat << "\n"; - tmp.clear() << Program::webroot << href; - dat << "\t" << tmp << "\n"; - // The default priority in a sitemap is 0.5 - if (!Math::Equals(priority, 0.5f)) - dat << "\t" << priority << "\n"; - dat << "\t"; - DateTime::TimestampToString(dat, "%Y-%m-%d", modifiedStr.to(), false); - dat << "\n"; - dat << "\n"; - } - } - sqlite3_free_table(result); - } - dat << "\n"; - out << dat; - - // trying gzip - out.close(); -#ifndef YUNI_OS_WINDOWS -// href.clear() << "gzip -f -9 \"" << filename << "\""; -// system(href.c_str()); -#endif -} - -static int TryToFindWordID(const Dictionary::Word& term) -{ - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2(gDB, "SELECT id FROM terms WHERE term = $1", -1, &stmt, NULL)) - return -1; - sqlite3_bind_text(stmt, 1, term.c_str(), term.size(), NULL); - if (SQLITE_ROW != sqlite3_step(stmt)) - { - sqlite3_finalize(stmt); - return -1; - } - const AnyString idstr = (const char*)sqlite3_column_text(stmt, 0); - int result = -1; - if (!(!idstr)) - { - if (!idstr.to(result)) - result = -1; - } - sqlite3_finalize(stmt); - return result; -} - -int RegisterWordReference(const Dictionary::Word& term) -{ - int id = TryToFindWordID(term); - if (id < 0) - { - sqlite3_stmt* stmt; - const char* const query = "INSERT INTO terms (term) VALUES ($1);"; - sqlite3_prepare_v2(gDB, query, -1, &stmt, NULL); - sqlite3_bind_text(stmt, 1, term.c_str(), term.size(), NULL); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - - // Try again - id = TryToFindWordID(term); - } - return id; -} - -int FindArticleID(const Yuni::String& href) -{ - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2(gDB, "SELECT id FROM articles WHERE html_href = $1", -1, &stmt, NULL)) - return -1; - sqlite3_bind_text(stmt, 1, href.c_str(), href.size(), NULL); - if (SQLITE_ROW != sqlite3_step(stmt)) - { - sqlite3_finalize(stmt); - return -1; - } - const AnyString idstr = (const char*)sqlite3_column_text(stmt, 0); - int result = -1; - if (!(!idstr)) - { - if (!idstr.to(result)) - result = -1; - } - sqlite3_finalize(stmt); - return result; -} - -void RegisterWordIDsForASingleArticle(ArticleID articleid, - const int* termid, - const int* countInArticle, - const float* weights, - unsigned int count) -{ - CString<1024> query; - query << "BEGIN;\n"; - query << "DELETE FROM terms_per_article WHERE article_id = " << articleid << ";\n"; - for (unsigned int i = 0; i != count; ++i) - { - query << "INSERT INTO terms_per_article (term_id,article_id,count_in_page,weight) VALUES (" - << termid[i] << ',' << articleid << ',' << countInArticle[i] << ',' << weights[i] - << ");\n"; - } - query << "COMMIT;\n"; - - sqlite3_exec(gDB, query.c_str(), NULL, NULL, NULL); -} - -static uint64 FindMaxOccurrenceForAnyTerm() -{ - const char* const query = "SELECT SUM(count_in_page) AS s from terms_per_article GROUP BY " - "term_id ORDER BY s DESC LIMIT 1;"; - sqlite3_stmt* stmt; - if (SQLITE_OK != sqlite3_prepare_v2(gDB, query, -1, &stmt, NULL)) - return 0; - - if (SQLITE_ROW != sqlite3_step(stmt)) - { - sqlite3_finalize(stmt); - return 0; - } - const AnyString rstr = (const char*)sqlite3_column_text(stmt, 0); - const uint64 r = rstr.to(); - sqlite3_finalize(stmt); - return r; -} - -static void UpdateAllRelativeTermWeight(uint64 maxO) -{ - char** result; - int rowCount, colCount; - const char* const query - = "SELECT term_id, SUM(count_in_page) FROM terms_per_article GROUP BY term_id;"; - if (SQLITE_OK != sqlite3_get_table(gDB, query, &result, &rowCount, &colCount, NULL)) - return; - - CString<128 * 1024> s; - s << "BEGIN;\n"; - if (rowCount) - { - unsigned int y = 1; - for (unsigned int row = 0; row < (unsigned int)rowCount; ++row) - { - const AnyString termID = result[++y]; - const AnyString scount = result[++y]; - if (!termID || !scount) - continue; - unsigned int count = scount.to(); - double d = 1. - (count * 0.5 / (double)maxO); - s << "UPDATE terms SET weight_rel_others = " << d << " WHERE id = " << termID << ";\n"; - } - } - - sqlite3_free_table(result); - - if (rowCount) - { - s << "COMMIT;\n"; - sqlite3_exec(gDB, s.c_str(), NULL, NULL, NULL); - } -} - -void UpdateAllSEOWeights() -{ - // Finding the maximum occurence of any term - { - uint64 maxO = FindMaxOccurrenceForAnyTerm(); - UpdateAllRelativeTermWeight(maxO); - } - // calculating the total weight for each term - { - const char* const query = "UPDATE terms SET weight = weight_user * weight_rel_others;"; - sqlite3_exec(gDB, query, NULL, NULL, NULL); - } -} - -void BuildSEOTermReference(Clob& data) -{ - char** result; - int rowCount, colCount; - CString<512, false> query; - query << "SELECT w.id,w.term, t.article_id,t.count_in_page,t.weight * w.weight" - << " FROM terms_per_article AS t, terms as w" - << " WHERE w.id = t.term_id ORDER BY term_id"; - if (SQLITE_OK != sqlite3_get_table(gDB, query.c_str(), &result, &rowCount, &colCount, NULL)) - return; - - if (rowCount) - { - sint64 oldTermID = -1; - unsigned int y = 5; - for (unsigned int row = 0; row < (unsigned int)rowCount; ++row) - { - const sint64 termid = AnyString(result[y++]).to(); - const AnyString term = result[y++]; - const AnyString articleID = result[y++]; - const AnyString scount = result[y++]; - const AnyString sweight = result[y++]; - if (termid < 0) - continue; - if (termid != oldTermID) - { - oldTermID = termid; - if (row) - data << "]);\n"; - data << "f(" << termid << ",'" << term << "',["; - } - else - data << ','; - - data << "{a:" << articleID // article ID - << ",c:" << scount // count - << ",w:" << sweight // weight - << '}'; - } - data << "]);\n"; - } - sqlite3_free_table(result); -} - -void BuildSEOArticlesReference() -{ - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2( - gDB, "SELECT id,html_href,title,weight FROM articles;", -1, &stmt, NULL)) - return; - - CString<1024 * 128> s("if (1) { var f=function(id,d) {SEO.articles[id] = d};"); - - while (SQLITE_ROW == sqlite3_step(stmt)) - { - const AnyString articleID = (const char*)sqlite3_column_text(stmt, 0); - const AnyString href = (const char*)sqlite3_column_text(stmt, 1); - const AnyString title = (const char*)sqlite3_column_text(stmt, 2); - const AnyString sweight = (const char*)sqlite3_column_text(stmt, 3); - s << "f(" << articleID << ",{" - << "t:\"" << title << '"' // article ID - << ",h:\"" << href << '"' // article ID - << ",w:" << sweight // weight - << "});"; - } - sqlite3_finalize(stmt); - - s << " }\n"; - - // Writing the JS file - String filename; - filename << Program::htdocs << SEP << "seo" << SEP << "data.js"; - IO::File::AppendContent(filename, s); -} - -void AppendChildrenList(Yuni::String& text, const String& path, const String& current) -{ - if (!path) - return; - - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2(gDB, - "SELECT title,html_href FROM articles WHERE parent = $1 ORDER BY " - "parent_order,LOWER(title)", - -1, - &stmt, - NULL)) - return; - sqlite3_bind_text(stmt, 1, path.c_str(), path.size(), NULL); - unsigned int count = 0; - while (SQLITE_ROW == sqlite3_step(stmt)) - { - if (!count++) - { - text << '\n'; - text << "\t
    \n"; - } - const AnyString title = (const char*)sqlite3_column_text(stmt, 0); - const AnyString href = (const char*)sqlite3_column_text(stmt, 1); - text << "\t
  • " << title << "
  • \n"; - } - if (count) - text << "\t
"; - - sqlite3_finalize(stmt); - return; -} - -void RetrieveTagList(ArticleData& article) -{ - article.tags.clear(); - if (article.id < 0) - return; - - sqlite3_stmt* stmt; - if (SQLITE_OK - != sqlite3_prepare_v2( - gDB, "SELECT tagname FROM tags_per_article WHERE article_id = $1", -1, &stmt, NULL)) - return; - sqlite3_bind_int64(stmt, 1, article.id); - while (SQLITE_ROW == sqlite3_step(stmt)) - { - const AnyString tagname = (const char*)sqlite3_column_text(stmt, 0); - article.tags.insert(tagname); - } - sqlite3_finalize(stmt); -} - -} // namespace DocIndex diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/indexes.h b/src/ext/yuni/src/tools/yuni-docmake/make/indexes.h deleted file mode 100644 index 605c2b5379..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/indexes.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef __YUNI_DOCMAKE_INDEXES_H__ -#define __YUNI_DOCMAKE_INDEXES_H__ - -#include -#include -#include -#include "article.h" -#include "dictionary.h" - -namespace DocIndex -{ -//! Article ID -typedef Yuni::sint64 ArticleID; - -bool Open(); - -void Close(); - -void Write(ArticleData& article); - -void RemoveNonExistingEntries(); - -void Vacuum(); - -bool AppendArticleTitleFromPath(Yuni::String& out, const Yuni::String& path); - -void BuildDirectoryIndex(Yuni::Clob& out, const Yuni::String& path); - -Yuni::sint64 ArticleLastModificationTimeFromCache(const Yuni::String& filename); - -/*! -** \brief Build a sitemap -** -** \see http://en.wikipedia.org/wiki/Site_map -** \see http://en.wikipedia.org/wiki/Google_Sitemaps -** -** This method must be ran from the main thread -*/ -void BuildSitemap(); - -/*! -** \brief Register a term in the database -** -** \return The ID in the database -*/ -int RegisterWordReference(const Dictionary::Word& term); - -void RegisterWordIDsForASingleArticle(Yuni::sint64 articleid, - const int* termid, - const int* countInArticle, - const float* weights, - unsigned int count); - -void UpdateAllSEOWeights(); - -int FindArticleID(const Yuni::String& href); - -void AppendChildrenList(Yuni::String& text, const Yuni::String& path, const Yuni::String& current); - -/*! -** \brief Retrieve the tag list of a single article -*/ -void RetrieveTagList(ArticleData& article); - -void BuildSEOTermReference(Yuni::Clob& data); - -void BuildSEOArticlesReference(); - -void* DatabaseHandle(); - -} // namespace DocIndex - -#endif // __YUNI_DOCMAKE_INDEXES_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/job-writer.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/job-writer.cpp deleted file mode 100644 index 89f0b443c8..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/job-writer.cpp +++ /dev/null @@ -1,909 +0,0 @@ - -#include "job-writer.h" -#include -#include -#include "job.h" -#include "../logs.h" -#include "../tinyxml/tinyxml.h" -#include -#include -#include "indexes.h" -#include "webpage.hxx" -#include "program.h" -#include "dictionary.h" - -using namespace Yuni; -using namespace Yuni::Tool::DocMake; - -#define SEP IO::Separator - -namespace // anonymous -{ -static Mutex gMutex; -static std::vector gJobList; -static String gTemplateContent; - -class Chart -{ -public: - typedef SmartPtr Ptr; - typedef std::vector Vector; - - class Curve - { - public: - typedef SmartPtr Ptr; - typedef std::vector Vector; - - public: - Curve() : showPoints(true), fill(true) - { - } - - public: - CString<16, false> type; - String caption; - String::Vector x; - String::Vector y; - bool showPoints; - bool fill; - }; - -public: - Chart(TiXmlElement* parentNode) : xmlNode(parentNode), legendPosition("ne") - { - } - - void generateJS(Clob& script, unsigned int id) const - { - script.clear(); - script << "$(function () {\n"; - script << "\t$.plot($(\"#dvchart_" << id << "\"), [\n"; - - for (unsigned int i = 0; i != curves.size(); ++i) - { - const Curve& curve = *(curves[i]); - if (i) - script << ",\n"; - script << "\t\t\{\n" - << "\t\t\tlabel: \"" << curve.caption << "\",\n" - << "\t\t\tdata: ["; - - unsigned int max = static_cast(Math::Max(curve.x.size(), curve.y.size())); - for (unsigned int pt = 0; pt != max; ++pt) - { - if (pt) - script << ", "; - script << '['; - if (pt < curve.x.size()) - script << curve.x[pt]; - else - script << '0'; - script << ','; - if (pt < curve.y.size()) - script << curve.y[pt]; - else - script << '0'; - script << ']'; - } - script << "],\n"; - script << "\t\t\t" << curve.type - << ": { show: true, fill: " << ((curve.fill) ? "true" : "false") << " }"; - if (curve.type == "lines" && curve.showPoints) - script << ",\n\t\t\tpoints: { show: true }"; - script << '\n'; - - script << "\t\t}"; - } - script << '\n'; - - script << "\t],\n" - << "\t{\n" - << "\t\txaxis: {\n" - << "\t\t},\n" - << "\t\tyaxis: {\n" - << "\t\t},\n" - << "\t\tseries: {\n" - << "\t\t},\n" - << "\t\tlegend: {\n" - << "\t\t\tposition: \"" << legendPosition << "\",\n" - << "\t\t},\n" - << "\t\tgrid: {\n" - << "\t\t\tborderWidth: 1,\n" - << "\t\t\tclickable: true,\n" - << "\t\t\thoverable: true,\n" - << "\t\t\tborderColor: \"rgb(190,190,190)\",\n" - << "\t\t\tautoHighlight: true\n" - << "\t\t}\n" - << "\t});\n" - << "});"; - } - -public: - //! The original XML node - TiXmlElement* xmlNode; - //! - Curve::Ptr currentCurve; - //! - Curve::Vector curves; - //! Legend position - CString<8, false> legendPosition; -}; - -class XMLVisitor : public TiXmlVisitor -{ -public: - //! \name Constructor - //@{ - /*! - ** \brief Constructor - */ - XMLVisitor(ArticleData& article, TiXmlDocument& document); - //! Destructor - virtual ~XMLVisitor(); - //@} - - virtual bool VisitEnter(const TiXmlDocument& /*doc*/); - - virtual bool VisitExit(const TiXmlDocument& /*doc*/); - - virtual bool VisitEnter(const TiXmlElement& element, const TiXmlAttribute* attr); - - virtual bool VisitExit(const TiXmlElement& element); - - virtual bool Visit(const TiXmlDeclaration& /*declaration*/); - virtual bool Visit(const TiXmlText& /*text*/); - virtual bool Visit(const TiXmlComment& /*comment*/); - virtual bool Visit(const TiXmlUnknown& /*unknown*/); - - void createAllCharts(); - void deleteUselessTags(); - -private: - //! XML document - TiXmlDocument& pDocument; - ArticleData& pArticle; - std::vector pToDelete; - - //! \name Charting - //@{ - Chart::Ptr pCurrentChart; - Chart::Vector pCharts; - //@} - - unsigned int pCurrentTOCItemIndex; - unsigned int pH2Index; - unsigned int pH3Index; - -}; // class XMLVisitor - -XMLVisitor::XMLVisitor(ArticleData& article, TiXmlDocument& document) : - pDocument(document), pArticle(article), pCurrentTOCItemIndex(0), pH2Index(0), pH3Index(0) -{ -} - -XMLVisitor::~XMLVisitor() -{ -} - -bool XMLVisitor::VisitEnter(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLVisitor::VisitExit(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLVisitor::VisitEnter(const TiXmlElement& element, const TiXmlAttribute* /*attr*/) -{ - const TIXML_STRING& name = element.ValueTStr(); - const Dictionary::Tag tag = name.c_str(); - TiXmlElement* e = const_cast(&element); - - // Attributes - TiXmlAttribute* attr = const_cast(element.FirstAttribute()); - for (; attr; attr = attr->Next()) - { - const AnyString e = attr->Value(); - if (e.contains("%%7B") || e.contains("%%7D")) - { - String s = e; - s.replace("%%7B", "{"); - s.replace("%%7D", "}"); - attr->SetValue(s.c_str()); - } - } - if (!(!pCurrentChart)) - { - if (tag == "curve") - { - pCurrentChart->currentCurve = new Chart::Curve(); - pCurrentChart->curves.push_back(pCurrentChart->currentCurve); - pCurrentChart->currentCurve->caption = element.Attribute("label"); - const AnyString type = element.Attribute("type"); - if (!type || (type != "lines" && type != "bars" && type != "points")) - { - if (not type.empty()) - logs.warning() - << pArticle.relativeFilename << ": invalid curve type, got '" << type << "'"; - pCurrentChart->currentCurve->type = "lines"; - } - else - pCurrentChart->currentCurve->type = type; - - const AnyString fill = element.Attribute("fill"); - if (not fill.empty()) - pCurrentChart->currentCurve->fill = fill.to(); - - return true; - } - if (tag == "legend") - { - const AnyString pos = element.Attribute("position"); - if (not pos.empty()) - { - if (pos != "ne" && pos != "nw" && pos != "se" && pos != "sw") - { - logs.warning() << pArticle.relativeFilename - << ": invalid legend position (valid values: ne, nw, se, sw)"; - return false; - } - pCurrentChart->legendPosition = pos; - } - return true; - } - - if (!pCurrentChart->currentCurve) - return false; - if (tag == "x") - { - const AnyString value = element.GetText(); - if (not value.empty()) - value.split(pCurrentChart->currentCurve->x, " ,;\t\r\n|"); - return true; - } - if (tag == "y") - { - const AnyString value = element.GetText(); - if (not value.empty()) - value.split(pCurrentChart->currentCurve->y, " ,;\t\r\n|"); - return true; - } - - // Invalid tag within a chart - return false; - } - if (tag == "chart") - { - // This node must be removed at the final end - pToDelete.push_back(const_cast(&element)); - pCurrentChart = new Chart(const_cast(&element)); - pCharts.push_back(pCurrentChart); - return true; - } - if (tag == "title" || tag == "tag" || tag.startsWith("pragma:")) - { - pToDelete.push_back(const_cast(&element)); - return true; - } - if (tag == "h2" || tag == "h3") - { - // Forcing the id - if (pCurrentTOCItemIndex < pArticle.tocItems.size()) - { - e->SetAttribute("id", pArticle.tocItems[pCurrentTOCItemIndex]->hrefID.c_str()); - ++pCurrentTOCItemIndex; - } - if (tag[1] == '2') - { - ++pH2Index; - pH3Index = 0; - } - else - ++pH3Index; - return true; - } - if (tag == "source") - { - CString<16, false> type = e->Attribute("type"); - e->SetValue("pre"); - e->RemoveAttribute("type"); - - type.toLower(); - if (type != "none") - { - if (!type || type == "cpp" || type == "c++") - e->SetAttribute("class", "cpp"); - else if (type == "lua") - e->SetAttribute("class", "lua"); - else if (type == "java") - e->SetAttribute("class", "java"); - } - } - return true; -} - -void XMLVisitor::deleteUselessTags() -{ - if (pToDelete.empty()) - return; - // start from the last item to delete - unsigned int i = (unsigned int)pToDelete.size(); - do - { - --i; - TiXmlElement* element = pToDelete[i]; - element->Parent()->RemoveChild(element); - } while (i); -} - -bool XMLVisitor::Visit(const TiXmlText&) -{ - /* - const TIXML_STRING& name = text.ValueTStr(); - String v = name.c_str(); - if (v.contains("rarr")) - std::cout << v << std::endl; - */ - return true; -} - -bool XMLVisitor::Visit(const TiXmlComment&) -{ - return true; -} - -bool XMLVisitor::Visit(const TiXmlDeclaration&) -{ - return true; -} - -bool XMLVisitor::Visit(const TiXmlUnknown&) -{ - return true; -} - -bool XMLVisitor::VisitExit(const TiXmlElement& element) -{ - const TIXML_STRING& name = element.ValueTStr(); - const Dictionary::Tag tag = name.c_str(); - - if (!(!pCurrentChart)) - { - if (tag == "chart") - { - pCurrentChart = nullptr; - return true; - } - if (tag == "curve") - { - if (!(!pCurrentChart)) - pCurrentChart->currentCurve = nullptr; - return true; - } - } - return true; -} - -void XMLVisitor::createAllCharts() -{ - if (pCharts.empty()) - return; - Clob script; - String id; - for (unsigned int i = 0; i != pCharts.size(); ++i) - { - id.clear() << "dvchart_" << i; - const Chart& chart = *(pCharts[i]); - chart.generateJS(script, i); - - TiXmlElement td("td"); - td.SetAttribute("id", id.c_str()); - td.SetAttribute("style", "width:600px;height:300px"); - - TiXmlElement emptytd("td"); - emptytd.InsertEndChild(TiXmlText(" ")); - - TiXmlElement tr("tr"); - tr.InsertEndChild(emptytd); - tr.InsertEndChild(td); - tr.InsertEndChild(emptytd); - - TiXmlElement table("table"); - table.SetAttribute("class", "nostyle"); - table.SetAttribute("style", "width:100%"); - table.InsertEndChild(tr); - chart.xmlNode->Parent()->InsertBeforeChild(chart.xmlNode, table); - - TiXmlElement js("script"); - js.SetAttribute("type", "text/javascript"); - TiXmlText text(script.c_str()); - js.InsertEndChild(text); - chart.xmlNode->Parent()->InsertBeforeChild(chart.xmlNode, js); - } -} - -} // anonymous namespace - -void JobWriter::SEOBuildAllTermReferences() -{ - String filename; - filename << Program::htdocs << SEP << "seo" << SEP << "data.js"; - IO::File::Stream file; - - if (file.openRW(filename)) - { - Clob data; - data << "if(1){var f=function(id,n,d) {SEO.termNames[n]=id;SEO.terms[id]=d};"; - DocIndex::BuildSEOTermReference(data); - data << " }\n"; - file << data; - } - else - logs.error() << "impossible to write " << filename; -} - -void JobWriter::Add(const String& input, const String& htdocs, const ArticleData& article) -{ - // Preparing a new job - // The article content will be copied - JobWriter* job = new JobWriter(input, htdocs, article); - // The new article - const ArticleData& newArticle = job->article(); - - // Keeping the new job in a safe place, for later use - gMutex.lock(); - gJobList.push_back(job); - gMutex.unlock(); - - // Preparing the global word dictionary - unsigned int registrationCount = 0; - if (!newArticle.wordCount.empty()) - { - // The article ID - int articleID = DocIndex::FindArticleID(newArticle.htdocsFilename); - - // All word ids for the page - Dictionary::WordID* wordIDs = new Dictionary::WordID[newArticle.wordCount.size()]; - float* weights = new float[newArticle.wordCount.size()]; - int* countInArticle = new int[newArticle.wordCount.size()]; - - // Registering all new terms - unsigned int wIx = 0; - const Dictionary::WordsCount::const_iterator end = newArticle.wordCount.end(); - Dictionary::WordsCount::const_iterator i = newArticle.wordCount.begin(); - for (; i != end; ++i, ++wIx) - { - // The word itself - const Dictionary::Word& word = i->first; - const Dictionary::WordStat& stats = i->second; - - countInArticle[wIx] = stats.count; - weights[wIx] = stats.coeff; - - Dictionary::WordID newWordID = Dictionary::FindWordID(word); - if (newWordID < 0) - { - Yuni::MutexLocker locker(Dictionary::mutex); - ++registrationCount; - newWordID = DocIndex::RegisterWordReference(word); - Dictionary::allWords[word] = newWordID; - wordIDs[wIx] = newWordID; - } - else - wordIDs[wIx] = newWordID; - } - - DocIndex::RegisterWordIDsForASingleArticle( - articleID, wordIDs, countInArticle, weights, wIx); - - delete[] weights; - delete[] countInArticle; - delete[] wordIDs; - } - - if (registrationCount && Program::debug) - logs.info() << " :: registered " << registrationCount << " terms"; -} - -void JobWriter::PushAllInQueue() -{ - gMutex.lock(); - for (unsigned int i = 0; i != gJobList.size(); ++i) - queueService += gJobList[i]; - gJobList.clear(); - gMutex.unlock(); -} - -bool JobWriter::ReadTemplateIndex() -{ - PrepareWebPageHtml(gTemplateContent); - return true; -} - -JobWriter::JobWriter(const String& input, const String& htdocs, const ArticleData& article) : - pInput(input), pHtdocs(htdocs), pArticle(article), pArticleID(-1) -{ -} - -JobWriter::~JobWriter() -{ -} - -void JobWriter::prepareVariables(const String& filenameInHtdocs) -{ - String tmp; - pVars.clear(); - - //! @{MODIFIED} - { - pVars["MODIFIED_TIMESTAMP"] = pArticle.modificationTime; - DateTime::TimestampToString(pVars["MODIFIED"], "%A, %B %e, %Y", pArticle.modificationTime); - } - //! @{MODIFIED_ISO8601} - { - DateTime::TimestampToString( - pVars["MODIFIED_ISO8601"], "%Y-%m-%d", pArticle.modificationTime); - } - - // @{LANG} - pVars["LANG"] = pArticle.language; - - // @{INDEX} - if (Program::shortUrl) - pVars["INDEX"] = nullptr; - else - pVars["INDEX"] = Program::indexFilename; - - // @{TITLE} - pVars["TITLE"] = pArticle.title; - - // @{DESCRIPTION} - pVars["DESCRIPTION"] = ""; - - TiXmlDocument doc; - doc.SetTabSize(4); - - if (not pArticle.originalFilename.empty()) - { - if (!doc.LoadFile(pArticle.originalFilename.c_str(), TIXML_ENCODING_UTF8)) - { - logs.error() << pArticle.relativeFilename << ", l" << doc.ErrorRow() << ": " - << doc.ErrorDesc(); - return; - } - { - XMLVisitor visitor(pArticle, doc); - doc.Accept(&visitor); - visitor.createAllCharts(); - visitor.deleteUselessTags(); - } - } - - // @{ROOT} - String& root = pVars["ROOT"]; - { - unsigned int c = pArticle.htdocsFilename.countChar('/'); - if (!c) - root = "."; - else - { - tmp.clear() << ".."; - for (unsigned int i = 1; i != c; ++i) - tmp << "/.."; - root = tmp; - } - } - - // @{URL} - pVars["URL"] = pArticle.htdocsFilename; - - // @{URL_PARTS} - { - String address; - if (pArticle.accessPath.empty()) - { - String::Vector list; - pArticle.htdocsFilename.split(list, "/"); - tmp.clear(); - String path; - String caption; - if (!list.empty()) - { - for (unsigned int i = 0; i < list.size(); ++i) - { - tmp << '/' << list[i]; - path.clear() << root << tmp; - if (!i) - continue; - address << "
  • "; - caption.clear(); - if (!DocIndex::AppendArticleTitleFromPath(caption, tmp)) - caption << list[i]; - address << caption << ""; - - IO::ExtractFilePath(path, tmp); - DocIndex::AppendChildrenList(address, path, caption); - address << "
  • \n"; - } - } - } - else - { - if (pArticle.accessPath == "quicklinks") - { - address << "
  • Documentation
  • \n"; - address << "
  • Downloads
  • \n"; - address << "
  • Developers
  • \n"; - address << "
  • Links
  • \n"; - address << "
  • Contacts
  • \n"; - } - } - pVars["URL_PARTS"] = address; - } - - // @{TAGS_BEGIN,...} - // The tags may have been changed because of the dependancies - pArticle.reloadTagsFromDatabase(); - if (pArticle.tags.empty()) - { - pVars["TAGS_BEGIN"] = ""; - pVars["TAGS_LIST"] = nullptr; - pVars["KEYWORDS"] = nullptr; - } - else - { - pVars["TAGS_BEGIN"] = nullptr; - pVars["TAGS_END"] = nullptr; - String& list = pVars["TAGS_LIST"]; - String& keywords = pVars["KEYWORDS"]; - list << "\n\n\n\n\t
    \n"; - switch (pArticle.tags.size()) - { - case 0: - list << "0 tag : "; - break; - case 1: - list << "1 tag : "; - break; - default: - list << pArticle.tags.size() << " tags : "; - break; - } - - Dictionary::TagSet::const_iterator end = pArticle.tags.end(); - bool first = true; - for (Dictionary::TagSet::const_iterator i = pArticle.tags.begin(); i != end; ++i) - { - if (!first) - { - list += "\t\t, "; - keywords += ", "; - } - else - list += "\t\t"; - list << "" << *i << "\n"; - keywords += *i; - first = false; - } - list << "\t
    \n\n"; - } - - // @{TOC_...} - if (pArticle.showTOC && pArticle.tocItems.size() > 1) - { - pVars["TOC_BEGIN"] = nullptr; - pVars["TOC_END"] = nullptr; - } - else - { - pVars["TOC_BEGIN"] = ""; - } - - // @{TOC_CONTENT} - if (pArticle.tocItems.size() != 0 && pArticle.showTOC) - { - tmp.clear(); - tmp << "
      \n"; - bool hasOL = false; - for (unsigned int i = 0; i != pArticle.tocItems.size(); ++i) - { - const ArticleData::TOCItem& item = *pArticle.tocItems[i]; - if (item.level == 2) - { - if (!hasOL) - { - hasOL = true; - tmp << "\t
        \n"; - } - tmp << "\t\t
      1. " << item.caption - << "
      2. \n"; - if (i + 1 == pArticle.tocItems.size()) - tmp << "\t
      \n\t\n"; - } - else - { - if (i) - { - if (hasOL) - tmp << "\t
    \n"; - tmp << "\t\n"; - } - tmp << "\t
  • " << item.caption << "\n"; - hasOL = false; - if (i + 1 == pArticle.tocItems.size()) - tmp << "\t
  • \n"; - } - } - tmp << "\n"; - pVars["TOC_CONTENT"] = tmp; - } - else - pVars["TOC_CONTENT"].clear(); - - // Quick links - if (pArticle.showQuickLinks) - { - pVars["QUICKLINKS_BEGIN"] = ""; - pVars["QUICKLINKS_END"] = ""; - } - else - { - pVars["QUICKLINKS_BEGIN"] = ""; - } - - // @{CONTENT} - if (not pArticle.originalFilename.empty()) - { - if (IO::Directory::System::Temporary(tmp)) - { - tmp << SEP << "yuni-doc-tmp-"; - Hash::Checksum::MD5 md5; - tmp << md5[filenameInHtdocs]; - if (Program::debug) - logs.info() << " :: writing " << tmp; - doc.SaveFile(tmp.c_str()); - String srcContent; - IO::File::LoadFromFile(srcContent, tmp); - IO::File::Delete(tmp); - - pVars["CONTENT"] = srcContent; - } - else - { - pVars["CONTENT"] = nullptr; - logs.error() << "impossible to retrieve the temporary folder location"; - } - } - else - pVars["CONTENT"] = nullptr; - - // @{DIRECTORY_INPUT} - if (not pArticle.directoryIndex.empty()) - { - Clob data; - DocIndex::BuildDirectoryIndex(data, pArticle.directoryIndex); - pVars["DIRECTORY_INDEX"] = data; - } - else - pVars["DIRECTORY_INDEX"] = ""; -} - -bool JobWriter::articleIDIndatabase() -{ - pArticleID = DocIndex::FindArticleID(pArticle.htdocsFilename); - return (pArticleID >= 0); -} - -void JobWriter::onExecute() -{ - if (!articleIDIndatabase()) - return; - - // temporary string - String key; - - // Looking for the target filename - String filenameInHtdocs; - { - key = pHtdocs; - if (pArticle.htdocsFilename != "/") - { - key << SEP << pArticle.htdocsFilename; -#ifdef YUNI_OS_WINDOWS - key.replace('/', '\\'); -#endif - if (!IO::Directory::Create(key)) - { - logs.error() << "impossible to create the directory " << key; - return; - } - } - - key << SEP << Program::indexFilename; - IO::Normalize(filenameInHtdocs, key); - } - - // Console verbose / debug - { - if (Program::debug) - logs.info() << "generating " << pArticle.htdocsFilename << " -> " << filenameInHtdocs; - else - { - if (Program::verbose) - logs.info() << "generating " << pArticle.htdocsFilename; - } - } - - // Prepare all variables - prepareVariables(filenameInHtdocs); - - CString<8192> content = gTemplateContent; - - String::Size offset = 0; - do - { - offset = content.find("@{", offset); - if (offset < content.size()) - { - String::Size end = content.find('}', offset + 2); - if (end < content.size()) - { - if (end - offset < 64) - { - unsigned int length = end - offset + 1; - if (length < 4) - { - offset += 2; - logs.warning() << pArticle.relativeFilename << ": empty variable name"; - continue; - } - key.assign(content.c_str() + offset + 2, length - 3); - Variables::const_iterator i = pVars.find(key); - if (i != pVars.end()) - { - content.erase(offset, length); - content.insert(offset, i->second); - } - else - { - offset += 2; - logs.warning() - << pArticle.relativeFilename << ": unknown variable '" << key << "'"; - } - continue; - } - else - { - logs.warning() << pArticle.relativeFilename << ": variable name too long"; - offset += 2; - continue; - } - } - else - logs.warning() << pArticle.relativeFilename << ": invalid variable definition"; - } - break; - } while (true); - - // Replace all pseudo linefeed - content.replace(" ", "\n"); - content.replace(" ", "\t"); - content.replace(""", "\""); - - if (!IO::File::SetContent(filenameInHtdocs, content)) - { - logs.error() << "impossible to generate '" << pArticle.htdocsFilename << "' into '" - << filenameInHtdocs << "'"; - } -} diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/job-writer.h b/src/ext/yuni/src/tools/yuni-docmake/make/job-writer.h deleted file mode 100644 index 056be52e02..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/job-writer.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __YUNI_DOCMAKE_JOB_WRITER_H__ -#define __YUNI_DOCMAKE_JOB_WRITER_H__ - -#include -#include -#include -#include -#include -#include "article.h" - -class JobWriter : public Yuni::Job::IJob -{ -public: - static void SEOBuildAllTermReferences(); - -public: - static void Add(const Yuni::String& input, - const Yuni::String& htdocs, - const ArticleData& article); - - static void PushAllInQueue(); - - static bool ReadTemplateIndex(); - -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Constructor - */ - JobWriter(const Yuni::String& input, const Yuni::String& htdocs, const ArticleData& article); - //! Destructor - virtual ~JobWriter(); - //@} - - const ArticleData& article() const - { - return pArticle; - } - -private: - virtual void onExecute(); - - bool articleIDIndatabase(); - void prepareVariables(const Yuni::String& filenameInHtdocs); - -private: - typedef std::map Variables; - -private: - const Yuni::String& pInput; - const Yuni::String& pHtdocs; - ArticleData pArticle; - Variables pVars; - //! Article ID in database - int pArticleID; - -}; // class CompileJob - -#endif // __YUNI_DOCMAKE_JOB_WRITER_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/job.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/job.cpp deleted file mode 100644 index 37b079a571..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/job.cpp +++ /dev/null @@ -1,644 +0,0 @@ - -#include "job.h" -#include "../logs.h" -#include -#include "../tinyxml/tinyxml.h" -#include -#include -#include "indexes.h" -#include "job-writer.h" -#include "program.h" - -#define SEP IO::Separator - -using namespace Yuni; -using namespace Yuni::Tool::DocMake; - -Yuni::Job::QueueService<> queueService; - -namespace // anonymous -{ -class XMLVisitor : public TiXmlVisitor -{ -public: - //! \name Constructor - //@{ - /*! - ** \brief Constructor - */ - XMLVisitor(ArticleData& article, TiXmlDocument& document); - //! Destructor - virtual ~XMLVisitor(); - //@} - - virtual bool VisitEnter(const TiXmlDocument& /*doc*/); - - virtual bool VisitExit(const TiXmlDocument& /*doc*/); - - virtual bool VisitEnter(const TiXmlElement& element, const TiXmlAttribute* attr); - - virtual bool VisitExit(const TiXmlElement& element); - - virtual bool Visit(const TiXmlDeclaration& /*declaration*/); - virtual bool Visit(const TiXmlText& /*text*/); - virtual bool Visit(const TiXmlComment& /*comment*/); - virtual bool Visit(const TiXmlUnknown& /*unknown*/); - - bool error() const - { - return pArticle.error; - } - -private: - void pushCoeff(float coeff); - - void popCoeff(); - - void pushCoeffFromString(const TIXML_STRING& name); - - void seo(const AnyString& string); - -private: - //! - float pCoeff; - - //! Within a paragraph - bool pWithinParagraph; - //! XML document - TiXmlDocument& pDocument; - //! XML Filename - const String& pFilename; - //! Current state - ArticleData::State pState; - ArticleData& pArticle; - - //! Last TOC level (1: h2, 2: h3...) - unsigned int pLastTOCLevel; - String pTOCCaption; - - enum - { - coeffStackMax = 256 - }; - float pCoeffStack[coeffStackMax]; - unsigned int pCoeffStackIndex; -}; // class XMLVisitor - -XMLVisitor::XMLVisitor(ArticleData& article, TiXmlDocument& document) : - pCoeff(1.f), - pWithinParagraph(false), - pDocument(document), - pFilename(article.relativeFilename), - pState(ArticleData::stNone), - pArticle(article), - pLastTOCLevel(0), - pCoeffStackIndex(0) -{ - memset(pCoeffStack, 0, sizeof(pCoeffStack)); -} - -XMLVisitor::~XMLVisitor() -{ -} - -bool XMLVisitor::VisitEnter(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLVisitor::VisitExit(const TiXmlDocument& /*doc*/) -{ - return true; -} - -bool XMLVisitor::VisitEnter(const TiXmlElement& element, const TiXmlAttribute* /*attr*/) -{ - const TIXML_STRING name = element.ValueTStr(); - const Dictionary::Tag tag = name.c_str(); - - pushCoeffFromString(name); - switch (pState) - { - case ArticleData::stNone: - { - if (tag.startsWith("pragma:")) - { - bool value; - if (tag == "pragma:tag") - { - const AnyString string1 = element.Attribute("value"); - pArticle.insertTags(string1); - const AnyString string2 = element.Attribute("name"); - pArticle.insertTags(string2); - } - else if (tag == "pragma:toc") - { - if (TIXML_SUCCESS == element.QueryBoolAttribute("value", &value)) - logs.warning() << pFilename << ": pragma:toc: the field value is deprecated"; - if (TIXML_SUCCESS == element.QueryBoolAttribute("visible", &value)) - pArticle.showTOC = value; - } - else if (tag == "pragma:lang") - { - // see http://www.seoconsultants.com/meta-tags/language - const AnyString string = element.Attribute("value"); - pArticle.language = string; - pArticle.language.trim(); - pArticle.language.toLower(); - } - else if (tag == "pragma:quicklinks") - { - if (TIXML_SUCCESS == element.QueryBoolAttribute("value", &value)) - pArticle.showQuickLinks = value; - else - logs.error() << pFilename << ": invalid value for pragma:quicklinks"; - } - else if (tag == "pragma:history") - { - if (TIXML_SUCCESS == element.QueryBoolAttribute("value", &value)) - pArticle.showHistory = value; - else - logs.error() << pFilename << ": invalid value for pragma:history"; - } - else if (tag == "pragma:directoryindex") - { - const AnyString string = element.Attribute("src"); - if (not string.empty()) - { - String src = pArticle.htdocsFilename; - src << SEP << string; - IO::Normalize(pArticle.directoryIndex, src); - } - else - { - String src = pArticle.htdocsFilename; - src << SEP << "."; - IO::Normalize(pArticle.directoryIndex, src); - } - - const CString<42, false> content = element.Attribute("content"); - if (not content.empty()) - { - if (content == "nofollow") - pArticle.directoryIndexContent = ArticleData::dicNoFollow; - else if (content == "noindex") - pArticle.directoryIndexContent = ArticleData::dicNoIndex; - else if (content == "all") - pArticle.directoryIndexContent = ArticleData::dicAll; - else - logs.error() << "invalid directory index content flag (expected: 'all', " - "'nofollow' or 'noindex')"; - } - - if (!string && !content) - logs.warning() - << pFilename - << ": pragma:directoryindex: missing attribute 'src' or 'content'"; - } - else if (tag == "pragma:accesspath") - { - CString<32, false> string = element.Attribute("value"); - string.toLower(); - if (string != "quicklinks") - logs.error() << pFilename << ": invalid access path overlay"; - else - pArticle.accessPath = string; - } - else if (tag == "pragma:weight") - { - CString<32, false> string = element.Attribute("value"); - float weight; - if (!string.to(weight) || weight < 0.f || weight > 10.f) - logs.error() << pFilename << ": invalid page weight (decimal, range 0..10)"; - else - pArticle.pageWeight = weight; - } - else - logs.warning() << pFilename << ": unknown setting: " << tag; - } - else - { - if (tag == "title") - { - pState = ArticleData::stTitle; - pArticle.title.clear(); - } - else if (tag == "h2") - { - pLastTOCLevel = 1; - pTOCCaption.clear(); - pState = ArticleData::stTOCItem; - } - else if (tag == "h3") - { - pTOCCaption.clear(); - if (!pLastTOCLevel) - { - logs.error() << "found h3 without h2. Adding an empty h2"; - pArticle.tocAppend(1, pTOCCaption); - } - pLastTOCLevel = 2; - pState = ArticleData::stTOCItem; - } - else if (tag == "h1") - { - logs.error() << "The tag h1 is reserved for the page title"; - return false; - } - else if (tag == "tag") - { - const AnyString string1 = element.Attribute("value"); - pArticle.insertTags(string1); - const AnyString string2 = element.Attribute("name"); - pArticle.insertTags(string2); - } - } - if (pWithinParagraph - && pArticle.allowedTagsInParagraph.find(tag) == pArticle.allowedTagsInParagraph.end()) - { - logs.error() << pFilename << ": invalid tag within a paragraph"; - pArticle.error = true; - return false; - } - if (tag == "p") - pWithinParagraph = true; - break; - } - case ArticleData::stTitle: - { - logs.error() << pFilename << ": invalid nested tag for 'title'"; - pArticle.error = true; - return false; - } - case ArticleData::stTOCItem: - { - if (tag == "h2" || tag == "h3") - { - logs.error() << "invalid nested header (h2,h3)"; - return false; - } - break; - } - default: - break; - } - return true; -} - -bool XMLVisitor::Visit(const TiXmlText& node) -{ - const TIXML_STRING& text = node.ValueTStr(); - - switch (pState) - { - case ArticleData::stTitle: - { - assert(pArticle.title.capacity() < 1024); - if (pArticle.title.size() + (unsigned int)text.size() > 512) - logs.error() << "invalid title length (> 512)"; - else - { - if (!pArticle.title.empty() && pArticle.title.last() != ' ') - pArticle.title += ' '; - pArticle.title.append(text.c_str(), (unsigned int)text.size()); - pArticle.title.trim(); - } - break; - } - case ArticleData::stTOCItem: - { - assert(pTOCCaption.capacity() < 1024); - if (pTOCCaption.size() + text.size() > 512) - logs.error() << "invalid caption length (>512)"; - else - { - if (!pTOCCaption.empty() && pTOCCaption.last() != ' ') - pTOCCaption += ' '; - pTOCCaption.append(text.c_str(), (unsigned int)text.size()); - pTOCCaption.trim(); - } - break; - } - default: - if (!text.empty()) - { - AnyString adapter; - adapter.adapt(text.c_str(), (unsigned int)text.size()); - seo(adapter); - } - break; - } - return true; -} - -bool XMLVisitor::Visit(const TiXmlComment&) -{ - return true; -} - -bool XMLVisitor::Visit(const TiXmlDeclaration&) -{ - return true; -} - -bool XMLVisitor::Visit(const TiXmlUnknown&) -{ - return true; -} - -bool XMLVisitor::VisitExit(const TiXmlElement& element) -{ - const TIXML_STRING& name = element.ValueTStr(); - - switch (pState) - { - case ArticleData::stNone: - { - if (name == "p") - pWithinParagraph = false; - } - case ArticleData::stTitle: - { - if (name == "title") - { - pState = ArticleData::stNone; - AnyString s = pArticle.title; - - float oldCoeff = pCoeff; - pCoeff = 5.f; - seo(s); - pCoeff = oldCoeff; - } - break; - } - case ArticleData::stTOCItem: - { - if (name == "h2" || name == "h3") - { - pState = ArticleData::stNone; - float oldCoeff = pCoeff; - pCoeff = (pLastTOCLevel == 1) ? 3.f : 2.f; - AnyString s = pTOCCaption; - seo(s); - pCoeff = oldCoeff; - pArticle.tocAppend(pLastTOCLevel, pTOCCaption); - pTOCCaption.clear(); - } - break; - } - default: - break; - } - - popCoeff(); - return true; -} - -void XMLVisitor::pushCoeff(float coeff) -{ - if (pCoeffStackIndex < coeffStackMax) - pCoeffStack[pCoeffStackIndex] = coeff; - ++pCoeffStackIndex; - pCoeff *= coeff; -} - -void XMLVisitor::popCoeff() -{ - if (pCoeffStack) - { - pCoeff = 1.f; - for (unsigned int i = 0; i != pCoeffStackIndex; ++i) - pCoeff *= pCoeffStack[i]; - --pCoeffStackIndex; - } - else - { - pCoeff = 1.f; - pCoeffStackIndex = 0; - } -} - -void XMLVisitor::pushCoeffFromString(const TIXML_STRING& name) -{ - if (name.empty()) - { - pushCoeff(1.f); - return; - } - if (name == "h2") - { - pushCoeff(3.f); - return; - } - if (name == "h3") - { - pushCoeff(2.0f); - return; - } - if (name == "h4") - { - pushCoeff(1.7f); - return; - } - if (name == "h5") - { - pushCoeff(1.60f); - return; - } - if (name == "h6") - { - pushCoeff(1.55f); - return; - } - if (name == "b") - { - pushCoeff(1.1f); - return; - } - if (name == "i") - { - pushCoeff(1.05f); - return; - } - if (name == "var") - { - pushCoeff(0.f); - return; - } - if (name == "pre") - { - pushCoeff(0.95f); - return; - } - if (name == "code") - { - pushCoeff(0.95f); - return; - } - pushCoeff(1.f); -} - -void XMLVisitor::seo(const AnyString& string) -{ - if (pCoeff < 0.1f) - return; - typedef Yuni::LinkedList List; - List list; - string.split(list, " \r\n\t:;!@#$%^&*()_+{}[]|\"'\\/.,?><=-"); - if (list.empty()) - return; - - Dictionary::Word word; - const List::const_iterator end = list.end(); - for (List::const_iterator i = list.begin(); i != end; ++i) - { - word = *i; - word.toLower(); - - Dictionary::WordStat& stat = pArticle.wordCount[word]; - ++stat.count; - if (pCoeff > stat.coeff) - stat.coeff = pCoeff; - } -} - -} // namespace - -CompileJob::CompileJob(const Yuni::String& input, const Yuni::String& htdocs) : - pInput(input), pHtdocs(htdocs) -{ -} - -CompileJob::~CompileJob() -{ -} - -bool CompileJob::extractOrder(const String& path) -{ - // Getting the raw folder name - // For the following URL : - // /Users/milipili/projects/yuni/sources/docs/docs/src/001-en/300-developers/100-recommended-softwares/article.xml - // We will get - // /Users/milipili/projects/yuni/sources/docs/docs/src/001-en/300-developers/100-recommended-softwares - IO::ExtractFilePath(pTmp, path); - - // Looking for the final slash - const String::Size offset = pTmp.find_last_of("/\\"); - if (offset == String::npos || offset + 4 >= pTmp.size()) - return false; - // We only want to match string like /XXX-xxxxxx... - if (pTmp[offset + 4] != '-') - return false; - - // We are optimistic. The first 3 chars should be a number most of the time - CString<8, false> s; - s.resize(3); - s[2] = pTmp[offset + 3]; - s[1] = pTmp[offset + 2]; - s[0] = pTmp[offset + 1]; - if (!s.to(pArticle.order)) - return false; - return (pArticle.order < 1000u); -} - -void CompileJob::onExecute() -{ - String target; - unsigned int sourceCount = (unsigned int)pSources.size(); - for (unsigned int i = 0; i != sourceCount; ++i) - { - assert(i < pSources.size()); - const String& entry = pSources[i]; - - // Resetting data related to the article - pArticle.reset(); - // The original filename (absolute) - pArticle.originalFilename = entry; - // The relative filename, from the source folder - pArticle.relativeFilename.assign(entry.c_str() + pInput.size() + 1, - entry.size() - pInput.size() - 1); - - // Last modification time - pArticle.modificationTime = IO::File::LastModificationTime(entry); - - // The final filename within the htdocs folder - pArticle.htdocsFilename.clear() << '/' << pArticle.relativeFilename; - pArticle.htdocsFilename.replace('\\', '/'); - { - String::Size offset = pArticle.htdocsFilename.find_last_of('/'); - if (offset != String::npos) - pArticle.htdocsFilename.resize(offset); - } - if (!pArticle.htdocsFilename) - pArticle.htdocsFilename = "/"; - - String::Size offset = 0; - do - { - offset = pArticle.htdocsFilename.find('/', offset); - if (pArticle.htdocsFilename.size() < 4 || offset > pArticle.htdocsFilename.size() - 4) - break; - ++offset; - if (pArticle.htdocsFilename[offset + 3] != '-') - break; - - bool isDigit = true; - for (unsigned int j = offset; j < offset + 3; ++j) - { - if (!String::IsDigit(pArticle.htdocsFilename[j])) - { - isDigit = false; - break; - } - } - if (isDigit) - pArticle.htdocsFilename.erase(offset, 4); - } while (true); - - // Post analyzis about the article - if (!analyzeArticle() || pArticle.error) - continue; - - // Writing the article in the database - DocIndex::Write(pArticle); - // Preparing a new job, with a copy of the data related to the article - JobWriter::Add(pInput, pHtdocs, pArticle); - } -} - -bool CompileJob::analyzeArticle() -{ - if (Program::verbose) - logs.info() << "reading " << pArticle.relativeFilename; - - // Article order - { - if (!extractOrder(pArticle.originalFilename)) - pArticle.order = 1000u; - if (Program::debug) - logs.info() << " :: " << pArticle.relativeFilename << ", order = " << pArticle.order; - } - - TiXmlDocument doc; - if (!doc.LoadFile(pArticle.originalFilename.c_str(), TIXML_ENCODING_UTF8)) - { - logs.error() << pArticle.relativeFilename << ", l" << doc.ErrorRow() << ": " - << doc.ErrorDesc(); - return false; - } - - // Analyze the XML document - XMLVisitor visitor(pArticle, doc); - if (!doc.Accept(&visitor) || visitor.error()) - { - pArticle.error = true; - return false; - } - if (!pArticle.title) - IO::ExtractFileName(pArticle.title, pArticle.htdocsFilename, false); - - // TOC refactoring - pArticle.tocRefactoring(); - - return true; -} diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/job.h b/src/ext/yuni/src/tools/yuni-docmake/make/job.h deleted file mode 100644 index 616f4b3465..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/job.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __YUNI_DOCMAKE_JOB_H__ -#define __YUNI_DOCMAKE_JOB_H__ - -#include -#include -#include -#include -#include -#include "article.h" - -class CompileJob : public Yuni::Job::IJob -{ -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Constructor - */ - CompileJob(const Yuni::String& input, const Yuni::String& htdocs); - //! Destructor - virtual ~CompileJob(); - //@} - - void add(const Yuni::String& filename) - { - pSources.push_back(filename); - } - -private: - virtual void onExecute(); - - /*! - ** \brief - ** - */ - bool analyzeArticle(); - - /*! - ** \brief Try to extract the order contained within a given path - */ - bool extractOrder(const Yuni::String& path); - -private: - const Yuni::String& pInput; - const Yuni::String& pHtdocs; - Yuni::String::Vector pSources; - - ArticleData pArticle; - //! Temporary string - Yuni::String pTmp; - -}; // class CompileJob - -extern Yuni::Job::QueueService<> queueService; - -#endif // __YUNI_DOCMAKE_JOB_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/main.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/main.cpp deleted file mode 100644 index 4bfe26a37b..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ - -#include -#include "../logs.h" -#include "program.h" -#include "job.h" -#include "job-writer.h" -#include "indexes.h" -#include "../tinyxml/tinyxml.h" -#include - -int main(int argc, char** argv) -{ - using namespace Yuni::Tool::DocMake; - - logs.applicationName("edln-make"); - Program program; - if (!program.parseCommandLine(argc, argv)) - return EXIT_FAILURE; - - if (!Program::quiet) - { - logs.checkpoint() << "Edalene Make"; - program.printInformations(); - } - if (!DocIndex::Open()) - return EXIT_FAILURE; - - // The condensed mode of tinyxml may removed all linefeed - TiXmlBase::SetCondenseWhiteSpace(false); - - // Preload all terms from the index db - Dictionary::PreloadFromIndexDB(); - - // Remove all entries within the database which are no longer - // available - DocIndex::RemoveNonExistingEntries(); - - // Find all articles - program.findAllSourceFiles(); - - // Extract information from all those articles - { - if (!Program::quiet) - logs.info() << "reading articles..."; - queueService.start(); - queueService.wait(); - queueService.stop(); - } - - if (!Program::quiet) - logs.info() << "building SEO data"; - DocIndex::UpdateAllSEOWeights(); - JobWriter::SEOBuildAllTermReferences(); - DocIndex::BuildSEOArticlesReference(); - - if (!Program::quiet) - logs.info() << "generating HTML files into htdocs"; - if (JobWriter::ReadTemplateIndex()) - { - JobWriter::PushAllInQueue(); - queueService.start(); - queueService.wait(); - queueService.stop(); - - if (!Program::quiet) - logs.info() << "Generating sitemap"; - DocIndex::BuildSitemap(); - } - - DocIndex::Vacuum(); - DocIndex::Close(); - - if (!Program::quiet) - logs.info() << "Done."; - return 0; -} diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/program-find-all-source-files.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/program-find-all-source-files.cpp deleted file mode 100644 index ad2a55e73a..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/program-find-all-source-files.cpp +++ /dev/null @@ -1,139 +0,0 @@ - -#include "program.h" -#include -#include "job.h" -#include "../logs.h" -#include "indexes.h" - -#define SEP IO::Separator - -namespace Yuni -{ -namespace Tool -{ -namespace DocMake -{ -void Program::findAllSourceFiles() -{ - if (!Program::quiet) - logs.notice() << "Looking for articles..."; - - unsigned int upToDateCount = 0; - std::vector jobs; - jobs.resize(nbJobs); - for (unsigned int i = 0; i != jobs.size(); ++i) - jobs[i] = new CompileJob(input, htdocs); - - IO::Directory::Info info(input); - String tmp; - unsigned int slotIndex = 0; - unsigned int count = 0; - String relative; - - for (IO::Directory::Info::recursive_iterator i = info.recursive_begin(); - i != info.recursive_end(); - ++i) - { - // assert - assert(!(!(*i))); - // aliases - const String& name = *i; - const String& filename = i.filename(); - - // The current element is either a folder, either a file - if (i.isFolder()) - { - // Detecting pseudo folders from source controls tools, such as - // subversion or git - if (filename.contains(".svn") || filename.contains(".git")) - continue; - - // Ok, the folder interrests us - // checking if th default article file is present - tmp.clear() << filename << SEP << "article.xml"; - if (!IO::File::Exists(tmp)) - { - logs.warning() << "missing article.xml in " << filename; - String content; - content << "\n"; - content << "\n"; - IO::File::SetContent(tmp, content); - } - } - else - { - // This should be a file - // In this phase, the only files which interrest us are all - // named 'article.xml' - if (!i.isFile() || name != "article.xml") - continue; - // A few asserts... - assert(filename.size() > input.size()); - assert(slotIndex < jobs.size()); - - // Checking for local modifications - if (!Program::clean) - { - // The relative filename - relative.assign(filename.c_str() + input.size() + 1, - filename.size() - input.size() - 1); - sint64 lastWriteFromCache - = DocIndex::ArticleLastModificationTimeFromCache(relative); - if (lastWriteFromCache > 0) - { - sint64 lastWrite = IO::File::LastModificationTime(filename); - // Trying to check if we really have to perform an analyzis - if (lastWriteFromCache == lastWrite) - { - ++upToDateCount; - continue; - } - } - } - - // Creating a new job for generating this article - jobs[slotIndex]->add(filename); - if (++slotIndex >= jobs.size()) - slotIndex = 0; - ++count; - } - } // for, all files and folders, recursively - - // Statistics about the articles to generate - if (count) - { - if (!Program::quiet) - { - logs.info() << count << (count > 1 ? " articles, " : " article, ") << nbJobs - << (nbJobs > 1 ? " threads" : " thread"); - logs.info(); - } - for (unsigned int i = 0; i != jobs.size(); ++i) - queueService += jobs[i]; - } - else - { - // Actually there is nothing to do (??). Destroying all - // useless jobs - for (unsigned int i = 0; i != jobs.size(); ++i) - delete jobs[i]; - } - - if (!Program::quiet) - { - switch (upToDateCount) - { - case 0: - break; - case 1: - logs.info() << "1 article up-to-date"; - break; - default: - logs.info() << upToDateCount << " articles already up to date"; - } - } -} - -} // namespace DocMake -} // namespace Tool -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/program.cpp b/src/ext/yuni/src/tools/yuni-docmake/make/program.cpp deleted file mode 100644 index 9ab6ccd6ce..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/program.cpp +++ /dev/null @@ -1,243 +0,0 @@ - -#include -#include "program.h" -#include -#include -#include -#include "../logs.h" - -#define SEP IO::Separator - -namespace Yuni -{ -namespace Tool -{ -namespace DocMake -{ -unsigned int Program::nbJobs = 1; -bool Program::debug = false; -bool Program::verbose = false; -bool Program::clean = false; -bool Program::shortUrl = false; -bool Program::quiet = false; - -String Program::input; -String Program::htdocs; -String Program::indexFilename = "index.html"; -String Program::webroot = "/"; -String Program::target; -String Program::profile; -String Program::indexCacheFilename; - -Program::Program() : printVersion(false) -{ -} - -Program::~Program() -{ - if (pProfileFile.opened()) - { - pProfileFile.unlock(); - pProfileFile.close(); - } -} - -bool Program::parseCommandLine(int argc, char** argv) -{ - // The total number of CPU - const unsigned int cpuCount = System::CPU::Count(); - // The most appropriate number of simultaneous jobs - nbJobs = (cpuCount > 4) ? 4 : cpuCount; - - // The Command line parser - GetOpt::Parser opts; - - // Compiler - opts.addParagraph("\nOptions:"); - opts.remainingArguments(profile); - opts.add(profile, 'p', "profile", "The profile"); - opts.add(target, 't', "target", "target"); - opts.addFlag(clean, 'c', "clean", "Clean the index db"); - opts.addFlag(shortUrl, 's', "short-url", "Use short url"); - opts.add( - nbJobs, - 'j', - "jobs", - String() << "Number of concurrent jobs (default: " << nbJobs << ", max: " << cpuCount << ')'); - - // Help - opts.addParagraph("\nHelp"); - opts.addFlag(quiet, 'q', "quiet", "Do not print any message, only warnings and errors"); - opts.addFlag(verbose, ' ', "verbose", "Print any error message"); - opts.addFlag(debug, ' ', "debug", "Print debug messages"); - opts.addFlag(printVersion, 'v', "version", "Print the version and exit"); - - if (!opts(argc, argv)) - { - int status = opts.errors() ? EXIT_FAILURE /*error*/ : 0; - if (verbose || debug) - logs.error() << "Error when parsing the command line"; - exit(status); - return false; - } - - if (!profile || !IO::File::Exists(profile)) - { - if (!profile) - logs.error() << "Please provide a profile"; - else - logs.error() << "Profile not found : " << profile; - return false; - } - - // Read the profile - // The profile will be locked for prevent any concurrent use - if (!readProfile(profile)) - return false; - - if (!input) - { - logs.error() - << "Please specify an input folder (--input, see --help for more informations)"; - return false; - } - if (!htdocs) - { - logs.error() - << "Please specify a htdocs folder (--htdocs, see --help for more informations)"; - return false; - } - - // Normalize the input / htdocs - { - String tmp; - IO::MakeAbsolute(tmp, input); - IO::Normalize(input, tmp); - IO::MakeAbsolute(tmp, htdocs); - IO::Normalize(htdocs, tmp); - if (!indexCacheFilename) - indexCacheFilename << htdocs << SEP << ".edalene-cache.edlndb"; - IO::MakeAbsolute(tmp, indexCacheFilename); - IO::Normalize(indexCacheFilename, tmp); - - if (!IO::Directory::Exists(input)) - { - logs.error() << "IO Error: Directory does not exist: " << input; - return false; - } - if (!IO::Directory::Exists(htdocs)) - { - logs.error() << "IO Error: Directory does not exist: " << htdocs; - return false; - } - } - - nbJobs = Math::MinMax(nbJobs, 1, cpuCount); - return true; -} - -void Program::printInformations() const -{ - logs.info() << "profile : " << profile; - if (!target) - logs.info() << "target : no-target"; - else - logs.info() << "target : [" << target << ']'; - - logs.info() << " source : " << input; - logs.info() << " htdocs : " << htdocs; - logs.info() << " cache : " << indexCacheFilename; - logs.info() << " directory-index : " << indexFilename; - logs.info() << " short-url : " << (shortUrl ? "true" : "false"); - logs.info(); -} - -bool Program::readProfile(const String& filename) -{ - if (pProfileFile.opened()) - { - pProfileFile.unlock(); - pProfileFile.close(); - } - if (!pProfileFile.open(filename)) - { - logs.error() << "impossible to read the profile : " << filename; - return false; - } - - pProfileFile.lockExclusive(); - - target.toLower(); - Clob buffer; - String key; - String value; - String currentProfile; - bool skip = true; - while (pProfileFile.readline(buffer)) - { - if (!buffer) - continue; - buffer.extractKeyValue(key, value, true); - if (!key) - continue; - - if (key == "[") - { - if (!currentProfile && value != "global") - { - logs.error() - << "invalid profile : the first section must be 'global' for global options"; - return false; - } - currentProfile = value; - if (value == "global") - skip = false; - else - skip = (value != target); - continue; - } - - if (skip) - continue; - - if (key == "source") - { - input = value; - continue; - } - if (key == "htdocs") - { - htdocs = value; - continue; - } - if (key == "default") - { - if (!target) - target = value; - continue; - } - if (key == "short-url") - { - shortUrl = value.to(); - continue; - } - if (key == "directory-index") - { - indexFilename = value; - continue; - } - if (key == "cache") - { - indexCacheFilename = value; - continue; - } - - logs.warning() << "profile " << profile << ": unknown key '" << key << "'"; - } - - return true; -} - -} // namespace DocMake -} // namespace Tool -} // namespace Yuni diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/program.h b/src/ext/yuni/src/tools/yuni-docmake/make/program.h deleted file mode 100644 index ba07254a94..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/program.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef __YUNI_DOCMAKE_MAKE_H__ -#define __YUNI_DOCMAKE_MAKE_H__ - -#include -#include -#include - -namespace Yuni -{ -namespace Tool -{ -namespace DocMake -{ -class Program -{ -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Default constructor - */ - Program(); - //! Destructor - ~Program(); - //@} - - bool parseCommandLine(int argc, char** argv); - - void findAllSourceFiles(); - - bool readProfile(const String& filename); - - void printInformations() const; - -public: - //! The input folder - static String input; - //! The htdocs folder - static String htdocs; - //! The index filename - static String indexFilename; - //! The web root (ex: http://www.libyuni.org) - static String webroot; - //! The profile - static String profile; - //! The target - static String target; - static String indexCacheFilename; - - static unsigned int nbJobs; - bool printVersion; - static bool debug; - static bool verbose; - static bool clean; - static bool shortUrl; - static bool quiet; - -private: - //! Profile file - Yuni::IO::File::Stream pProfileFile; - -}; // class Make - -} // namespace DocMake -} // namespace Tool -} // namespace Yuni - -#endif // __YUNI_DOCMAKE_MAKE_H__ diff --git a/src/ext/yuni/src/tools/yuni-docmake/make/webpage.html b/src/ext/yuni/src/tools/yuni-docmake/make/webpage.html deleted file mode 100644 index 08dcd6435e..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/make/webpage.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - -@{TITLE} - Yuni Framework - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -

    @{TITLE}

    -
    -
      -
    •  
    • -@{URL_PARTS} -
    -
    -
    - - -
    - - - -@{TOC_BEGIN} -
    -
    - Table of Contents [ Show ] - -
    -
    -@{TOC_END} - - - - -
    - -@{CONTENT} -@{DIRECTORY_INDEX} -@{TAGS_LIST} - -
    - - -
    -Last modified : @{MODIFIED} -
    - - -
    - - - -
    - -
    -Yuni Framework -
    - - - - -
    - - - -
    - - - - diff --git a/src/ext/yuni/src/tools/yuni-docmake/www.libyuni.org.profile b/src/ext/yuni/src/tools/yuni-docmake/www.libyuni.org.profile deleted file mode 100644 index e925ef2cfa..0000000000 --- a/src/ext/yuni/src/tools/yuni-docmake/www.libyuni.org.profile +++ /dev/null @@ -1,15 +0,0 @@ -[global] -source = "../../../docs/src" -htdocs = "../../../docs/html" -cache = "../../../docs/edalene-cache.edlndb" -default = local -directory-index = index.html - - -[local] - - -[production] -webroot = "http://www.libyuni.org" -short-url = true -