diff --git a/docs/doxyrest/frame/cfamily/crefdb.py.in b/docs/doxyrest/frame/cfamily/crefdb.py.in index b72bfb1aa..79597255b 100644 --- a/docs/doxyrest/frame/cfamily/crefdb.py.in +++ b/docs/doxyrest/frame/cfamily/crefdb.py.in @@ -13,5 +13,6 @@ crefdb = { %{ includeFile("crefdb_groups.py.in", g_groupArray) includeFile("crefdb_members.py.in", g_globalNamespace) + includeFile("crefdb_external.py.in") } } diff --git a/docs/doxyrest/frame/cfamily/crefdb_enums.py.in b/docs/doxyrest/frame/cfamily/crefdb_enums.py.in index 1afcc5406..b590de767 100644 --- a/docs/doxyrest/frame/cfamily/crefdb_enums.py.in +++ b/docs/doxyrest/frame/cfamily/crefdb_enums.py.in @@ -13,23 +13,43 @@ local argArray = table.pack(...) local itemArray = argArray[1] +local function addEnumValues(enum, rootEnum) + if LANGUAGE == "jancy" and not enum.baseType.isEmpty then + baseEnum = findLinkedTextEnum(enum.baseType) + if baseEnum ~= nil then + if not rootEnum then + rootEnum = enum + end + addEnumValues(baseEnum, rootEnum) + end + end + + for i = 1, #enum.enumValueArray do + local enumValue = enum.enumValueArray[i] + local enumValueName + + if rootEnum then + enumValueName = getItemQualifiedName(rootEnum) .. g_nameDelimiter .. enumValue.name + else + enumValueName = getItemQualifiedName(enumValue) + + -- remove parent enum name (C++ only) + enumValueName = string.gsub(enumValueName, "([%w_]+)::([%w_]+)$", "%2") + end +} + '$enumValueName' : 'doxid-$(enumValue.id)', +%{ + end -- for +end + for i = 1, #itemArray do local item = itemArray[i] if not isUnnamedItem(item) then } '$(getItemQualifiedName(item))' : 'doxid-$(item.id)', %{ - end + end -- if - for j = 1, #item.enumValueArray do - local enumValue = item.enumValueArray[j] - local enumValueName = getItemQualifiedName(enumValue) - - -- remove parent enum name (C++ only) - enumValueName = string.gsub(enumValueName, "([%w_]+)::([%w_]+)$", "%2") -} - '$enumValueName' : 'doxid-$(enumValue.id)', -%{ - end -- for + addEnumValues(item) end -- for } diff --git a/docs/doxyrest/frame/cfamily/enum.rst.in b/docs/doxyrest/frame/cfamily/enum.rst.in index 3bcfc40c8..8919f81b7 100644 --- a/docs/doxyrest/frame/cfamily/enum.rst.in +++ b/docs/doxyrest/frame/cfamily/enum.rst.in @@ -51,8 +51,17 @@ end -- if :class: doxyrest-overview-code-block $(getEnumImportString(enum)) +%{ +if enum.baseType.isEmpty then +} $enumKind $(enum.name)$g_preBodySpace{ %{ +else +} + $enumKind $(enum.name): ${getLinkedTextString(enum.baseType, true)}$g_preBodySpace{ +%{ +end --if + for i = 1, #enum.enumValueArray do local item = enum.enumValueArray[i] local initializer = getLinkedTextString(item.initializer, true) diff --git a/docs/doxyrest/frame/cfamily/utils.lua b/docs/doxyrest/frame/cfamily/utils.lua index 3f38b080c..9d6fa8f63 100644 --- a/docs/doxyrest/frame/cfamily/utils.lua +++ b/docs/doxyrest/frame/cfamily/utils.lua @@ -29,8 +29,8 @@ if not EXTRA_PAGE_LIST then EXTRA_PAGE_LIST = {} end -if not IMPORT_URL_MAP then - IMPORT_URL_MAP = {} +if not EXTERNAL_CREF_DB then + EXTERNAL_CREF_DB = {} end if ML_PARAM_LIST_COUNT_THRESHOLD then @@ -142,6 +142,20 @@ function getLinkedTextString(text, isRef) return s end +function findLinkedTextEnum(text) + for i = 1, #text.refTextArray do + local refText = text.refTextArray[i] + if refText.id ~= "" then + local member = findMemberById(refText.id) + if member ~= nil and member.memberKind == "enum" then + return member + end + end + end + + return nil +end + ------------------------------------------------------------------------------- -- param array formatting @@ -207,18 +221,19 @@ function getParamArrayString_ml(paramArray, isRef, lbrace, rbrace, indent, nl) elseif count == 1 then s = lbrace .. getParamString(paramArray[1], isRef) .. rbrace else - s = lbrace .. nl .. indent .. "\t" + s = lbrace .. nl for i = 1, count do - s = s .. getParamString(paramArray[i], isRef) + s = s .. indent .. "\t" .. getParamString(paramArray[i], isRef) if i ~= count then s = s .. "," end - s = s .. nl .. indent .. "\t" + s = s .. nl end - s = s .. rbrace + + s = s .. indent .. rbrace end return s @@ -256,9 +271,7 @@ function getParamArrayString(prefix, paramArray, isRef, lbrace, rbrace, indent, if ML_PARAM_LIST_LENGTH_THRESHOLD then local decl = prefix .. space .. s - if isRef then - decl = string.gsub(decl, ":ref:`[^`]*`", "") - end + decl = replaceRolesWithPlainText(decl) if string.len(decl) > ML_PARAM_LIST_LENGTH_THRESHOLD then s = getParamArrayString_ml(paramArray, isRef, lbrace, rbrace, indent, nl) @@ -382,7 +395,7 @@ function getPropertyDeclString(item, nameTemplate, indent) local s = getLinkedTextString(item.returnType, true) if item.modifiers ~= "" then - s = string.gsub(s, "property", item.modifiers .. " property") + s = string.gsub(s, "property$", item.modifiers .. " property") end s = s .. getFunctionModifierDelimiter(indent) @@ -558,7 +571,7 @@ function getBaseClassString(class, protection) else -- class without id (imported) - local url = IMPORT_URL_MAP[class.importId] + local url = EXTERNAL_CREF_DB[class.name] if url then s = s .. ":ref:`" .. class.name .. "<" .. url .. ">`" else @@ -785,8 +798,9 @@ function filterDefineArray(defineArray) local isExcluded = isItemExcludedByLocationFilter(item) or - EXCLUDE_EMPTY_DEFINES and item.initializer.isEmpty or - EXCLUDE_DEFINE_PATTERN and string.match(item.name, EXCLUDE_DEFINE_PATTERN) + EXCLUDE_DEFINE_PATTERN and string.match(item.name, EXCLUDE_DEFINE_PATTERN) or + EXCLUDE_EMPTY_DEFINES and item.initializer.isEmpty and + item.briefDescription.isEmpty and item.detailedDescription.isEmpty if isExcluded then table.remove(defineArray, i) diff --git a/docs/doxyrest/frame/cmake/compound.rst.in b/docs/doxyrest/frame/cmake/compound.rst.in new file mode 100644 index 000000000..a0ad61770 --- /dev/null +++ b/docs/doxyrest/frame/cmake/compound.rst.in @@ -0,0 +1,91 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local compoundStats = prepareCompound(compound) +} + +$(getCompoundTocTree(compound)) + +%{ +local hasDetails = + compoundStats.hasDocumentedItems or + compoundStats.hasBriefDocumentation and compoundStats.hasDetailedDocumentation + +if hasDetails then +} +Overview +~~~~~~~~ + +$(getItemBriefDocumentation(compound)) + +%{ +else +} +$(getItemDetailedDocumentation(compound)) + +%{ +end -- if + +if #compound.groupArray > 0 or compound.hasGlobalNamespace then + local groupTree = "" + + for i = 1, #compound.groupArray do + local item = compound.groupArray[i] + local targetFileName = getItemFileName(item) + + generateFile(targetFileName, "group.rst.in", item) + groupTree = groupTree .. getGroupTree(item) + end -- for + + if compound.hasGlobalNamespace then + groupTree = groupTree .. getGroupTree(g_globalNamespace) + end +} +$groupTree + +%{ +end -- if + +if compoundStats.hasItems then + includeFile("overview_compound.rst.in", compound) +end + +if hasDetails then +} +.. _details-$(compound.id): + +Detailed Documentation +~~~~~~~~~~~~~~~~~~~~~~ + +$(getItemDetailedDocumentation(compound)) + +%{ +end -- if + +if compoundStats.hasDocumentedVariables then + includeFile("details_variables.rst.in", compound, "Variables") +end + +if compoundStats.hasDocumentedFunctions then + includeFile("details_functions.rst.in", compound, compound.functionArray, "Functions") +end + +if compoundStats.hasDocumentedDefines then + includeFile("details_functions.rst.in", compound, compound.defineArray, "Macros") +end + +if #compound.footnoteArray > 0 then + includeFile("footnotes.rst.in", compound) +end +} diff --git a/docs/doxyrest/frame/cmake/crefdb.py.in b/docs/doxyrest/frame/cmake/crefdb.py.in new file mode 100644 index 000000000..b19e8a78f --- /dev/null +++ b/docs/doxyrest/frame/cmake/crefdb.py.in @@ -0,0 +1,19 @@ +#............................................................................... +# +# This file is part of the Doxyrest toolkit. +# +# Doxyrest is distributed under the MIT license. +# For details see accompanying license.txt file, +# the public copy of which is also available at: +# http://tibbo.com/downloads/archive/doxyrest/license.txt +# +#............................................................................... + +crefdb = { +%{ + includeFile("crefdb_groups.py.in", g_groupArray) + includeFile("crefdb_items.py.in", g_globalNamespace.variableArray) + includeFile("crefdb_items.py.in", g_globalNamespace.functionArray) + includeFile("crefdb_external.py.in") +} +} diff --git a/docs/doxyrest/frame/cmake/details_functions.rst.in b/docs/doxyrest/frame/cmake/details_functions.rst.in new file mode 100644 index 000000000..b4d41a374 --- /dev/null +++ b/docs/doxyrest/frame/cmake/details_functions.rst.in @@ -0,0 +1,25 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local functionArray = argArray[2] +local sectionName = argArray[3] + +includeFile( + "details.rst.in", + compound, + functionArray, + getFunctionDeclString, + sectionName + ) +} diff --git a/docs/doxyrest/frame/cmake/details_variables.rst.in b/docs/doxyrest/frame/cmake/details_variables.rst.in new file mode 100644 index 000000000..3e9ac3af3 --- /dev/null +++ b/docs/doxyrest/frame/cmake/details_variables.rst.in @@ -0,0 +1,26 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local sectionName = argArray[2] + +includeFile( + "details.rst.in", + compound, + compound.variableArray, + function (item) + return item.name + end, + sectionName + ) +} diff --git a/docs/doxyrest/frame/cmake/global.rst.in b/docs/doxyrest/frame/cmake/global.rst.in new file mode 100644 index 000000000..d5d336d84 --- /dev/null +++ b/docs/doxyrest/frame/cmake/global.rst.in @@ -0,0 +1,29 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +if not g_cmakeUtilsIncluded then + dofile(g_frameDir .. "/utils.lua") +end + +if FORCE_INCLUDE_FILE then +} +.. include:: $FORCE_INCLUDE_FILE +%{ +end -- if +} +.. _global: + +$(getTitle(g_globalNamespace.title, 1)) + +%{ +includeFile("compound.rst.in", g_globalNamespace) +} diff --git a/docs/doxyrest/frame/cmake/index.rst.in b/docs/doxyrest/frame/cmake/index.rst.in new file mode 100644 index 000000000..7a17fa074 --- /dev/null +++ b/docs/doxyrest/frame/cmake/index.rst.in @@ -0,0 +1,19 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +dofile(g_frameDir .. "/utils.lua") +includeFile("index_main.rst.in") + +if CREF_DB then + generateFile("crefdb.py", "crefdb.py.in") +end +} diff --git a/docs/doxyrest/frame/cmake/overview_compound.rst.in b/docs/doxyrest/frame/cmake/overview_compound.rst.in new file mode 100644 index 000000000..d4ee59473 --- /dev/null +++ b/docs/doxyrest/frame/cmake/overview_compound.rst.in @@ -0,0 +1,34 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +} +.. ref-code-block:: cmake + :class: doxyrest-overview-code-block + +%{ +if #compound.variableArray > 0 then + includeFile("overview_variables.rst.in", compound) + emit("\n") +end -- if + +if #compound.functionArray > 0 then + includeFile("overview_functions.rst.in", compound, compound.functionArray, "functions") + emit("\n") +end + +if #compound.defineArray > 0 then + includeFile("overview_functions.rst.in", compound, compound.defineArray, "macros") + emit("\n") +end +} diff --git a/docs/doxyrest/frame/cmake/overview_functions.rst.in b/docs/doxyrest/frame/cmake/overview_functions.rst.in new file mode 100644 index 000000000..1a54c6cc9 --- /dev/null +++ b/docs/doxyrest/frame/cmake/overview_functions.rst.in @@ -0,0 +1,38 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local functionArray = argArray[2] +local sectionName = argArray[3] +} + # $sectionName + +%{ +local isPrevMl = false + +for i = 1, #functionArray do + local item = functionArray[i] + local decl = getFunctionDeclString(item, getItemNameTemplate(item), "\t") + local isMl = string.find(decl, "\n") + local extraNl = "" + + if i > 1 and (isMl or isPrevMl) then + extraNl = "\n" + end + + isPrevMl = isMl +} +$extraNl $decl +%{ +end -- for +} diff --git a/docs/doxyrest/frame/cmake/overview_variables.rst.in b/docs/doxyrest/frame/cmake/overview_variables.rst.in new file mode 100644 index 000000000..3863390e6 --- /dev/null +++ b/docs/doxyrest/frame/cmake/overview_variables.rst.in @@ -0,0 +1,27 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +} + # variables + +%{ +for i = 1, #compound.variableArray do + local item = compound.variableArray[i] + local nameTemplate = getItemNameTemplate(item) + local name = fillItemNameTemplate(nameTemplate, item.name, item.id) +} + set$g_preParamSpace$name +%{ +end -- for +} diff --git a/docs/doxyrest/frame/cmake/utils.lua b/docs/doxyrest/frame/cmake/utils.lua new file mode 100644 index 000000000..a3e2db7b8 --- /dev/null +++ b/docs/doxyrest/frame/cmake/utils.lua @@ -0,0 +1,178 @@ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +g_cmakeUtilsIncluded = true + +dofile(g_frameDir .. "/../common/string.lua") +dofile(g_frameDir .. "/../common/table.lua") +dofile(g_frameDir .. "/../common/item.lua") +dofile(g_frameDir .. "/../common/doc.lua") +dofile(g_frameDir .. "/../common/toc.lua") + +LANGUAGE = "cmake" + +if not INDEX_TITLE then + INDEX_TITLE = "My Project Documentation" +end + +if not EXTRA_PAGE_LIST then + EXTRA_PAGE_LIST = {} +end + +if not EXTERNAL_CREF_DB then + EXTERNAL_CREF_DB = {} +end + +if PRE_PARAM_LIST_SPACE then + g_preParamSpace = " " +else + g_preParamSpace = "" +end + +if not g_globalNamespace.title then + g_globalNamespace.title = "Global Scope" +end + +------------------------------------------------------------------------------- + +-- formatting of function declarations + +function getParamName(param) + if param.declarationName ~= "" then + return param.declarationName + elseif param.definitionName ~= "" then + return param.definitionName + else + return param.type.plainText + end +end + +function getParamArrayString_sl(paramArray) + local s = "" + + local count = #paramArray + if count > 0 then + s = " " .. getParamName(paramArray[1]) + + for i = 2, count do + s = s .. " " .. getParamName(paramArray[i]) + end + end + + return s .. ")" +end + +function getParamArrayString_ml(paramArray, indent) + if not indent then + indent = "" + end + + local s = "" + local nl = "\n" .. indent .. "\t" + + local count = #paramArray + if count > 0 then + s = nl .. getParamName(paramArray[1]) + + for i = 2, count do + s = s .. nl .. getParamName(paramArray[i]) + end + end + + return s .. nl .. ")" +end + +function getFunctionDeclString(func, nameTemplate, indent) + local functionKind + if func.memberKind == "define" then + functionKind = "macro" + else + functionKind = "function" + end + + local s = functionKind .. g_preParamSpace .. "(" + local name = fillItemNameTemplate(nameTemplate, func.name, func.id) + local paramString + + if ML_PARAM_LIST_COUNT_THRESHOLD and + #func.paramArray > ML_PARAM_LIST_COUNT_THRESHOLD then + s = s .. "\n" .. indent + paramString = getParamArrayString_ml(func.paramArray, indent) + else + paramString = getParamArrayString_sl(func.paramArray) + + if ML_PARAM_LIST_LENGTH_THRESHOLD then + local decl = functionKind .. g_preParamSpace .. func.name .. paramString + decl = replaceRolesWithPlainText(decl) + + if string.len(decl) > ML_PARAM_LIST_LENGTH_THRESHOLD then + s = s .. "\n" .. indent + paramString = getParamArrayString_ml(func.paramArray, indent) + end + end + end + + return s .. name .. paramString +end + +------------------------------------------------------------------------------- + +-- compound prep + +function itemLocationFilter(item) + return not (item.location and string.match(item.location.file, EXCLUDE_LOCATION_PATTERN)) +end + +function prepareCompound(compound) + if compound.stats then + return compound.stats + end + + local stats = {} + + if EXCLUDE_LOCATION_PATTERN then + filterArray(compound.variableArray, itemLocationFilter) + filterArray(compound.functionArray, itemLocationFilter) + filterArray(compound.defineArray, itemLocationFilter) + end + + stats.hasItems = + #compound.variableArray ~= 0 or + #compound.functionArray ~= 0 or + #compound.defineArray ~= 0 + + stats.hasBriefDocumentation = not isDocumentationEmpty(compound.briefDescription) + stats.hasDetailedDocumentation = not isDocumentationEmpty(compound.detailedDescription) + stats.hasDocumentedVariables = prepareItemArrayDocumentation(compound.variableArray, compound) + stats.hasDocumentedFunctions = prepareItemArrayDocumentation(compound.functionArray, compound) + stats.hasDocumentedDefines = prepareItemArrayDocumentation(compound.defineArray, compound) + stats.hasDocumentedItems = stats.hasDocumentedVariables or stats.hasDocumentedFunctions + + if EXCLUDE_UNDOCUMENTED_ITEMS then + filterArray(compound.variableArray, hasItemDocumentation) + filterArray(compound.functionArray, hasItemDocumentation) + filterArray(compound.defineArray, hasItemDocumentation) + end + + table.sort(compound.groupArray, cmpGroups) + + if SORT_GLOBAL_MEMBERS then + table.sort(compound.variableArray, cmpNames) + table.sort(compound.functionArray, cmpNames) + table.sort(compound.defineArray, cmpNames) + end + + compound.stats = stats + + return stats +end + +------------------------------------------------------------------------------- diff --git a/docs/doxyrest/frame/common/crefdb_external.py.in b/docs/doxyrest/frame/common/crefdb_external.py.in new file mode 100644 index 000000000..68cbd9dff --- /dev/null +++ b/docs/doxyrest/frame/common/crefdb_external.py.in @@ -0,0 +1,20 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) + +for id, url in pairs(EXTERNAL_CREF_DB) do +} + '$id' : '$url', +%{ +end -- for +} diff --git a/docs/doxyrest/frame/common/doc.lua b/docs/doxyrest/frame/common/doc.lua index e5b23a991..ac8568324 100644 --- a/docs/doxyrest/frame/common/doc.lua +++ b/docs/doxyrest/frame/common/doc.lua @@ -318,31 +318,6 @@ function formatDocBlock_sect(block, context, level) return s .. "\n\n" .. text .. "\n\n" end -function formatDocBlock_simplesect(block, context) - local s = "" - local text = getDocBlockText(block, context) - - if block.simpleSectionKind == "return" then - if not context.returnSection then - context.returnSection = {} - end - - local count = #context.returnSection - context.returnSection[count + 1] = text - elseif block.simpleSectionKind == "see" then - if not context.seeSection then - context.seeSection = {} - end - - local count = #context.seeSection - context.seeSection[count + 1] = text - else - s = text - end - - return s -end - function formatDocBlock_ulink(block, context) return "`" .. block.text .. " <" .. block.url .. ">`__" end @@ -402,6 +377,64 @@ function formatDocBlock_table(b, context) return s end +function formatDocBlock_graph(block, context, graphtype) + local code = getCodeDocBlockContents(block, context) + code = replaceCommonSpacePrefix(code, "\t") + code = trimTrailingWhitespace(code) + + return "\n\n.. " .. graphtype .. "::\n\n" .. code .. "\n\n" +end + +-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +function formatSimpleSectionBlock_return(block, context) + if not context.returnSection then + context.returnSection = {} + end + + local count = #context.returnSection + context.returnSection[count + 1] = getDocBlockText(block, context) + return "" +end + +function formatSimpleSectionBlock_see(block, context) + if not context.seeSection then + context.seeSection = {} + end + + local count = #context.seeSection + context.seeSection[count + 1] = getDocBlockText(block, context) + return "" +end + +function formatSimpleSectionBlock_admonition(block, context, kind) + local text = getDocBlockText(block, context) + text = replaceCommonSpacePrefix(text, "\t") + text = trimTrailingWhitespace(text) + return "\n\n.. " .. kind .. "::\n\n" .. text .. "\n\n" +end + +-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +g_simpleSectblockKindFormatMap = +{ + ["return"] = formatSimpleSectionBlock_return, + ["sa"] = formatSimpleSectionBlock_see, + ["see"] = formatSimpleSectionBlock_see, + ["note"] = formatSimpleSectionBlock_admonition, + ["attention"] = formatSimpleSectionBlock_admonition, + ["warning"] = formatSimpleSectionBlock_admonition, +} + +function formatDocBlock_simplesect(block, context) + format = g_simpleSectblockKindFormatMap[block.simpleSectionKind] + if format then + return format(block, context, block.simpleSectionKind) + else + return getDocBlockText(block, context) + end +end + -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - g_blockKindFormatMap = @@ -434,6 +467,9 @@ g_blockKindFormatMap = ["simplesect"] = formatDocBlock_simplesect, ["ulink"] = formatDocBlock_ulink, ["table"] = formatDocBlock_table, + ["dot"] = function(b, c) return formatDocBlock_graph(b, c, "graphviz") end, + ["plantuml"] = function(b, c) return formatDocBlock_graph(b, c, "uml") end, + ["msc"] = function(b, c) return formatDocBlock_graph(b, c, "msc") end, } function getDocBlockContents(block, context) diff --git a/docs/doxyrest/frame/common/string.lua b/docs/doxyrest/frame/common/string.lua index 368bccdd7..a7dbe6d74 100644 --- a/docs/doxyrest/frame/common/string.lua +++ b/docs/doxyrest/frame/common/string.lua @@ -98,4 +98,9 @@ function replaceCommonSpacePrefix(source, replacement) return s end +function replaceRolesWithPlainText(source) + local s = string.gsub(source, ":[^:]*:`([^<`]*)[^`]*`", "%1") + return s +end + ------------------------------------------------------------------------------- diff --git a/docs/doxyrest/frame/doxyrest-config.lua b/docs/doxyrest/frame/doxyrest-config.lua new file mode 100644 index 000000000..d975af07d --- /dev/null +++ b/docs/doxyrest/frame/doxyrest-config.lua @@ -0,0 +1,463 @@ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +--! +--! \defgroup frame-config +--! \grouporder 2 +--! \title Frame Settings +--! +--! This section describes frame settings controlling input and output paths, +--! titles, force-includes, declaration coding style, etc. +--! +--! A default ``doxyrest-config.lua`` file for standard frames can be found at +--! ``$DOXYREST_FRAME_DIR/doxyrest-config.lua``. Copy it to your project +--! directory and then adjust all the necessary parameters. +--! +--! @{ +--! + +--! +--! Table containing a list of frame directories. All frame files will be +--! searched in directories -- and in the sequence -- specified here. +--! + +FRAME_DIR_LIST = {} + +--! +--! The output master (index) reStructuredText file. Usually, the index frame +--! also generates auxillary files -- they will be placed next to the master +--! file. The command line option ``-f`` *overrides* this value. +--! If neither ``FRAME_FILE`` nor ``-f`` is specified, ``index.rst.in`` will be +--! used as the default frame file. +--! + +FRAME_FILE = nil + +--! +--! The input master (index) XML file. Specifying it here allows calling +--! ``doxyrest`` without parameters; otherwise, the master XML *must* be passed +--! via the command line. If both ``INPUT_FILE`` and command line parameter are +--! specified, the command line takes precedence. +--! + +INPUT_FILE = nil + +--! +--! The output master (index) reStructuredText file. Usually, the index frame +--! also generates auxillary files -- they will be placed next to the master +--! file. The command line option ``-o`` *overrides* this value. If neither +--! ``OUTPUT_FILE`` nor ``-o`` is specified, ``index.rst`` will be used as +--! the default output master file. +--! + +OUTPUT_FILE = nil + +--! +--! File with project-specific reStructuredText definitions. When non``nil``, +--! this file will be included at the top of every generated ``.rst`` file. +--! + +FORCE_INCLUDE_FILE = nil + +--! +--! If you want to add extra reStructuredText documentation pages, do so +--! by adding them to this list. +--! + +EXTRA_PAGE_LIST = {} + +--! +--! The title of the main (index) page. This only is used when ``INTRO_FILE`` +--! is not set (otherwise, the title of intro file will be used). +--! + +INDEX_TITLE = "My Project Documentation" + +--! +--! File with project introduction (reStructuredText). When non-nil, this file +--! will be included into ``index.rst`` file and NOT added to the list of other +--! documentation pages. +--! + +INTRO_FILE = nil + +--! +--! Specify whether to sort groups lexicographically (by ``title``) or +--! logically (by ``id``). To maintain the original order (in which a group has +--! been seen in the XML database), use ``originalIdx``. +--! +--! Omitting ``SORT_GROUPS_BY`` (or setting it to ``nil``) results in groups +--! being sorted by ``title``. +--! + +SORT_GROUPS_BY = "title" + +--[[! + By default, the page for the global namespace page will be called + "Global Namespace" and will contain no description except that for the + global compounds and members. + + It's possible to override this behaviour by defining an auxillary compound + (page or group) with a special ``id``; this page/group may contain a + user-defined title, a brief description and a detailed description. Use + ``GLOBAL_AUX_COMPOUND_ID`` to define this special id. + + .. note:: + + To make sure you use the correct **Doxygen** XML ID of the group/page, + find the definition of the group in one of ``.xml`` files and copy + the value of ``id`` attribute. + + For example, if the group was declared as ``\defgroup global`` then + the its ``id`` will probably be either ``group_`` or + ``group__``. +]] + +GLOBAL_AUX_COMPOUND_ID = "group_global" + +--[[! + Doxyrest offers a workaround for the lack of footnotes in Doxygen by + getting documentation blocks for specially named pseudo-members and + converting those into footnotes. + + ``FOOTNOTE_MEMBER_PREFIX`` specifies the name prefix for such + pseudo-members. If it is set to ``nil`` or an empty string, Doxyrest + will not attempt to convert any members to footnotes. + + \sa :ref:`footnotes` +]] + +FOOTNOTE_MEMBER_PREFIX = nil + +--! +--! Specify the main language of your project; this string will be used for +--! the reStructuredText ``.. code-block::`` sections and for conditional +--! formatting of module item declarations. +--! + +LANGUAGE = cpp + +--! +--! Convert ``\verbatim`` sections in doxy-comments to ``.. code-block::`` +--! sections in the output reStructuredText. The string value of +--! ``VERBATIM_TO_CODE_BLOCK`` will be used as the language of +--! ``.. code-block::`` section. By default, it's ``"none"`` which results in +--! no syntax highlighting. To disable conversion at all, use ``nil``. +--! + +VERBATIM_TO_CODE_BLOCK = "none" + +--! +--! If the original doxy comments contain asterisks, they have to be escaped in +--! reStructuredText (asterisks are used to mark **bold** or *italic* blocks). +--! + +ESCAPE_ASTERISKS = false + +--! +--! If the original doxy comments contain pipe characters ``|``, they have to be +--! escaped in reStructuredText (pipes are used for substitution references). +--! + +ESCAPE_PIPES = false + +--! +--! If the original doxy comments contain trailingasterisks, they have to be +--! escaped in reStructuredText (trailing underscores are used for internal +--! links). +--! + +ESCAPE_TRAILING_UNDERSCORES = false + +--! +--! Exclude items declared in specific locations. Use a regular expression to +--! define a mask of directories/source files to completely exclude from the +--! final documentation. For example, ``.*/impl/.*lua$`` will exclude all +--! ``.lua`` files located in ``impl/`` directory. +--! + +EXCLUDE_LOCATION_PATTERN = nil + +--! +--! Exclude variables and functions without any documentation (no doxy-comments). +--! + +EXCLUDE_UNDOCUMENTED_ITEMS = false + +--! +--! \subgroup +--! +--! By default, Doxyrest tries to translate Doxygen ``\section``, +--! ``\subsection``, and ``\subsubsection`` commands (as well as the +--! ```` blocks generated by Doxygen from Markdown titles +--! inside comments) into reStructuredText titles. +--! +--! This sometimes leads to problems because Doxygen headings may appear outside +--! of the global scope (e.g. inside lists) while reStructuredText titles are +--! only allowed at the global scope. Another issue is Doxygen headings may +--! yield inconsistent title structure (e.g. a title level 1 followed by level +--! 3). +--! +--! If you run into these issues, use ``SECTION_TO_RUBRIC`` or +--! ``HEADING_TO_RUBRIC`` to always convert Doxygen sections or ```` +--! blocks or into reStructuredText ``.. rubric::`` directives. This yields +--! uni-level headings, but solves both aforementioned problems. +--! + +SECTION_TO_RUBRIC = false +HEADING_TO_RUBRIC = false + +--[[! + By default, Doxyrest frames build a Python dictionary to be used later on by + the ``:cref:`` (code-reference) role. This database maps language-specific + qualified names of items to their IDs. + + This, together with setting the Sphinx ``default_role`` to ``cref``, allows + to conveniently reference items from Doxy-comments or regular ``.rst`` files + as such: + + .. code-block:: none + + The `ui::Dialog` class is a base to the `ui::FileDialog` class. + + However, if this facility is not used, building (and loading) of the + cref-database can be omitted to save both space and time. +]] + +CREF_DB = false + +--[[! + Exclude items with higher protection level than ``PROTECTION_FILTER``: + + 1. ``public`` + 2. ``protected`` + 3. ``private`` + 4. ``package`` + + By default, only public items are included into documentation. +]] + +PROTECTION_FILTER = "public" + +--! +--! In many projects empty defines are *only* used as include-guards (and as +--! such, should be excluded from the documentation). If this is not the case +--! and empty defines should be kept in the final documentation, change this +--! setting to ``false``. +--! + +EXCLUDE_EMPTY_DEFINES = true + +--! +--! If non-``nil``, each define will be checked using this regular expression +--! and if its name matches, this define will be excluded from the documentation. +--! + +EXCLUDE_DEFINE_PATTERN = nil + +--! +--! Usually providing documentation blocks for default constructors is +--! not necessary (as to avoid redundant meaningless "Constructs a new object" +--! paragraphs). Change this to ``false`` if default constructors *should* be +--! included. +--! + +EXCLUDE_DEFAULT_CONSTRUCTORS = true + +--! +--! Usually providing documentation blocks for a destructors is +--! not necessary (as to avoid redundant meaningless "Destructs an object" +--! paragraphs). Change this to ``false`` if destructors *should* be +--! included. +--! + +EXCLUDE_DESTRUCTORS = true + +--[[! + Usually providing documentation blocks for primitive C typedefs such as: + + .. code-block:: C + + typedef struct S S; + + is not necessary. Change this to ``false`` if such typedefs *should* be + included. +]] + +EXCLUDE_PRIMITIVE_TYPEDEFS = true + +--! +--! For a base class/struct, show all the types directly derived from it. +--! + +SHOW_DIRECT_DESCENDANTS = true + +--[[! + \subgroup + + Insert space between function name and parameter list like this: + + .. code-block:: C + + void foo (); + + By default, ``PRE_PARAM_LIST_SPACE`` is ``false`` which yields: + + .. code-block:: C + + void foo(); +]] + +PRE_PARAM_LIST_SPACE = false +PRE_OPERATOR_NAME_SPACE = true +PRE_OPERATOR_PARAM_LIST_SPACE = true + +--[[! + Insert a new line before the body of a enum, struct, class, etc. + + When ``PRE_BODY_NL`` is ``false``: + + .. code-block:: cpp + + class MyClass { + ... + } + + When ``PRE_BODY_NL`` is ``true``: + + .. code-block:: cpp + + class MyClass + { + ... + } +]] + +PRE_BODY_NL = false + +--[[! + Use multi-line parameter lists in function declarations if parameter count is + greater than this threshold. ``nil`` means don't use parameter count + threshold. + + For example, when ``ML_PARAM_LIST_COUNT_THRESHOLD`` is ``2``, the function + declarations will look as such: + + .. code-block:: C + + void fn0(); + void fn1(int a); + void fn2(int a, int b); + + void fn3( + int a, + int b + int c + ); +]] + +ML_PARAM_LIST_COUNT_THRESHOLD = nil + +--[[! + Use multi-line parameter lists in function declarations if single-line + declaration length parameter count is greater than this threshold. + ``nil`` means don't use length threshold. + + Similar to ``ML_PARAM_LIST_COUNT_THRESHOLD``, but the threshold parameter + here is *declaration length* and not *declaration parameter count*. + + Example: + + .. code-block:: C + + void foo(int a, int b, int c); + + void bar( + int veryLongParameterName, + int anotherVeryLongParameterName + ); + +]] + +ML_PARAM_LIST_LENGTH_THRESHOLD = 80 + +--[[! + Use multi-line specifier-modifier lists in function declarations, i.e + allocate a dedicated line for each type specifier/morifier. + + For example, when ``ML_SPECIFIER_MODIFIER_LIST`` is ``true``, the function + declarations will look as such: + + .. code-block:: C + + void + foo(); + + static + bool + __cdecl + bar(int a); +]] + +ML_SPECIFIER_MODIFIER_LIST = false + +--[[! + Use the new C++11 syntax for ``typedef``-s: + + When ``TYPEDEF_TO_USING`` is ``false``: + + .. code-block:: cpp + + typedef unsigned int uint_t; + typedef void Foo(int); + typedef void (*FooPtr)(int); + + When ``TYPEDEF_TO_USING`` is ``true``: + + .. code-block:: cpp + + using uint_t = unsigned int; + using Foo typedef void (int); + using FooPtr typedef void (*)(int); +]] + +TYPEDEF_TO_USING = false + +--[[! + Sometimes, it's required to redirect a Doxygen link to some external location. + In this case, add an entry to ``EXTERNAL_CREF_DB`` with the target URL, e.g.: + + .. code-block:: lua + + EXTERNAL_CREF_DB = + { + [ "jnc.Scheduler" ] = "https://vovkos.github.io/jancy/stdlib/class_jnc_Scheduler.html", + [ "strlen"] = "https://vovkos.github.io/jancy/stdlib/group_crt.html#doxid-function-strlen" + + -- ... + } + + The key of the map is an ``importid`` attribute. This is a non-standard Doxygen + attribute; Jancy compiler generates is when a referenced item is contained in an + imported extensions library (``.jncx``) +]] + +EXTERNAL_CREF_DB = {} + +--[[! + Usually providing documentation blocks for Lua ``local`` variables or + functions is not desired. Change this to ``false`` if local items + *should* be included in the final documentation. +]] + +EXCLUDE_LUA_LOCALS = true + +--! @} diff --git a/docs/doxyrest/frame/lua/class.rst.in b/docs/doxyrest/frame/lua/class.rst.in new file mode 100644 index 000000000..dc86429f0 --- /dev/null +++ b/docs/doxyrest/frame/lua/class.rst.in @@ -0,0 +1,30 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local compoundKind = argArray[2] + +if FORCE_INCLUDE_FILE then +} +.. include:: $FORCE_INCLUDE_FILE +%{ +end -- if +} +.. index:: pair: $compoundKind; $(compound.name) +.. _doxid-$(compound.id): + +$(getTitle(compoundKind .. " " .. compound.name, 1)) + +%{ +includeFile("compound.rst.in", compound) +} diff --git a/docs/doxyrest/frame/lua/compound.rst.in b/docs/doxyrest/frame/lua/compound.rst.in new file mode 100644 index 000000000..87ecbd67c --- /dev/null +++ b/docs/doxyrest/frame/lua/compound.rst.in @@ -0,0 +1,100 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] + +local variableSectionName +local functionSectionName +local isClass = compound.compoundKind == "class" or compound.compoundKind == "struct" + +if isClass then + variableSectionName = "Fields" + functionSectionName = "Methods" +else + variableSectionName = "Variables" + functionSectionName = "Functions" +end + +local compoundStats = prepareCompound(compound) +} + +$(getCompoundTocTree(compound)) + +%{ +local hasDetails = + compoundStats.hasDocumentedItems or + compoundStats.hasBriefDocumentation and compoundStats.hasDetailedDocumentation + +if hasDetails then +} +Overview +~~~~~~~~ + +$(getItemBriefDocumentation(compound)) + +%{ +else +} +$(getItemDetailedDocumentation(compound)) + +%{ +end -- if + +if #compound.groupArray > 0 or compound.hasGlobalNamespace then + local groupTree = "" + + for i = 1, #compound.groupArray do + local item = compound.groupArray[i] + local targetFileName = getItemFileName(item) + + generateFile(targetFileName, "group.rst.in", item) + groupTree = groupTree .. getGroupTree(item) + end -- for + + if compound.hasGlobalNamespace then + groupTree = groupTree .. getGroupTree(g_globalNamespace) + end +} +$groupTree + +%{ +end -- if + +if compoundStats.hasItems or isClass then + includeFile("overview_compound.rst.in", compound, variableSectionName, functionSectionName) +end + +if hasDetails then +} +.. _details-$(compound.id): + +Detailed Documentation +~~~~~~~~~~~~~~~~~~~~~~ + +$(getItemDetailedDocumentation(compound)) + +%{ +end -- if + +if compoundStats.hasDocumentedVariables then + includeFile("details_variables.rst.in", compound, variableSectionName) +end + +if compoundStats.hasDocumentedFunctions then + includeFile("details_functions.rst.in", compound, functionSectionName) +end + +if #compound.footnoteArray > 0 then + includeFile("footnotes.rst.in", compound) +end +} diff --git a/docs/doxyrest/frame/lua/crefdb.py.in b/docs/doxyrest/frame/lua/crefdb.py.in new file mode 100644 index 000000000..627745b3d --- /dev/null +++ b/docs/doxyrest/frame/lua/crefdb.py.in @@ -0,0 +1,21 @@ +#............................................................................... +# +# This file is part of the Doxyrest toolkit. +# +# Doxyrest is distributed under the MIT license. +# For details see accompanying license.txt file, +# the public copy of which is also available at: +# http://tibbo.com/downloads/archive/doxyrest/license.txt +# +#............................................................................... + +crefdb = { +%{ + includeFile("crefdb_groups.py.in", g_groupArray) + includeFile("crefdb_items.py.in", g_globalNamespace.enumArray) + includeFile("crefdb_structs.py.in", g_globalNamespace.structArray) + includeFile("crefdb_items.py.in", g_globalNamespace.variableArray) + includeFile("crefdb_items.py.in", g_globalNamespace.functionArray) + includeFile("crefdb_external.py.in") +} +} diff --git a/docs/doxyrest/frame/lua/crefdb_structs.py.in b/docs/doxyrest/frame/lua/crefdb_structs.py.in new file mode 100644 index 000000000..8464f6598 --- /dev/null +++ b/docs/doxyrest/frame/lua/crefdb_structs.py.in @@ -0,0 +1,25 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local itemArray = argArray[1] + +for i = 1, #itemArray do + local item = itemArray[i] +} + '$(item.name)' : 'doxid-$(item.id)', +%{ + local prefix = item.name .. "." + includeFile("crefdb_items.py.in", item.variableArray, prefix) + includeFile("crefdb_items.py.in", item.functionArray, prefix) +end -- for +} diff --git a/docs/doxyrest/frame/lua/details_functions.rst.in b/docs/doxyrest/frame/lua/details_functions.rst.in new file mode 100644 index 000000000..1a92a4e05 --- /dev/null +++ b/docs/doxyrest/frame/lua/details_functions.rst.in @@ -0,0 +1,24 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local sectionName = argArray[2] + +includeFile( + "details.rst.in", + compound, + compound.functionArray, + getFunctionDeclString, + sectionName + ) +} diff --git a/docs/doxyrest/frame/lua/details_variables.rst.in b/docs/doxyrest/frame/lua/details_variables.rst.in new file mode 100644 index 000000000..3e9ac3af3 --- /dev/null +++ b/docs/doxyrest/frame/lua/details_variables.rst.in @@ -0,0 +1,26 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local sectionName = argArray[2] + +includeFile( + "details.rst.in", + compound, + compound.variableArray, + function (item) + return item.name + end, + sectionName + ) +} diff --git a/docs/doxyrest/frame/lua/enum.rst.in b/docs/doxyrest/frame/lua/enum.rst.in new file mode 100644 index 000000000..8aca1763d --- /dev/null +++ b/docs/doxyrest/frame/lua/enum.rst.in @@ -0,0 +1,110 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local enum = argArray[1] + +local enumStats = prepareEnum(enum) + +if FORCE_INCLUDE_FILE then +} +.. include:: $FORCE_INCLUDE_FILE +%{ +end -- if +} +.. index:: pair: enum; $(enum.name) +.. _doxid-$(enum.id): + +$(getTitle("enumeration " .. enum.name, 1)) + +%{ +local hasDetails = + enumStats.hasDocumentedEnumValues or + enumStats.hasBriefDocumentation and enumStats.hasDetailedDocumentation + +if hasDetails then +} +Overview +~~~~~~~~ + +$(getItemBriefDocumentation(enum)) + +%{ +else +} +$(getItemDetailedDocumentation(enum)) + +%{ +end -- if +} +.. ref-code-block:: lua + :class: doxyrest-overview-code-block + + $(enum.name) =$g_preBodySpace{ + -- enumeration values + +%{ +for i = 1, #enum.enumValueArray do + local item = enum.enumValueArray[i] +} + $(getEnumValueString(item)), +%{ +end -- for +} + } + +%{ +if hasDetails then +} +.. _details-$(enum.id): + +Detailed Documentation +~~~~~~~~~~~~~~~~~~~~~~ + +$(getItemDetailedDocumentation(enum)) + +%{ +end -- if + +if enumStats.hasDocumentedEnumValues then +} +Enumeration Values +------------------ + +%{ + for i = 1, #enum.enumValueArray do + local item = enum.enumValueArray[i] + if item.hasDocumentation then +} +$(getItemRefTargetString(item)) +.. ref-code-block:: $LANGUAGE + :class: doxyrest-title-code-block + + $(getEnumValueString(item)) +%{ + if item.isSubGroupHead then + for j = 1, #item.subGroupSlaveArray do + slaveItem = item.subGroupSlaveArray[j] +} + $(getEnumValueString(slaveItem)) +%{ + end -- for + end -- if +} + +$(getItemDetailedDocumentation(item)) + +%{ + end -- if + end -- for +end -- if +} diff --git a/docs/doxyrest/frame/lua/global.rst.in b/docs/doxyrest/frame/lua/global.rst.in new file mode 100644 index 000000000..32ae9dfeb --- /dev/null +++ b/docs/doxyrest/frame/lua/global.rst.in @@ -0,0 +1,29 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +if not g_luaUtilsIncluded then + dofile(g_frameDir .. "/utils.lua") +end + +if FORCE_INCLUDE_FILE then +} +.. include:: $FORCE_INCLUDE_FILE +%{ +end -- if +} +.. _global: + +$(getTitle(g_globalNamespace.title, 1)) + +%{ +includeFile("compound.rst.in", g_globalNamespace) +} diff --git a/docs/doxyrest/frame/lua/index.rst.in b/docs/doxyrest/frame/lua/index.rst.in new file mode 100644 index 000000000..7a17fa074 --- /dev/null +++ b/docs/doxyrest/frame/lua/index.rst.in @@ -0,0 +1,19 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +dofile(g_frameDir .. "/utils.lua") +includeFile("index_main.rst.in") + +if CREF_DB then + generateFile("crefdb.py", "crefdb.py.in") +end +} diff --git a/docs/doxyrest/frame/lua/overview_classes.rst.in b/docs/doxyrest/frame/lua/overview_classes.rst.in new file mode 100644 index 000000000..e5a0c62c4 --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_classes.rst.in @@ -0,0 +1,27 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +} + -- classes + +%{ +for i = 1, #compound.classArray do + local item = compound.classArray[i] + local targetFileName = getItemFileName(item) + generateFile(targetFileName, "class.rst.in", item, "class") +} + :ref:`$(item.name)` +%{ +end -- for +} diff --git a/docs/doxyrest/frame/lua/overview_compound.rst.in b/docs/doxyrest/frame/lua/overview_compound.rst.in new file mode 100644 index 000000000..3edba7612 --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_compound.rst.in @@ -0,0 +1,89 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local variableSectionName = string.lower(argArray[2]) +local functionSectionName = string.lower(argArray[3]) +} +.. ref-code-block:: lua + :class: doxyrest-overview-code-block + +%{ +if #compound.namespaceArray > 0 then + includeFile("overview_modules.rst.in", compound) + emit("\n") +end + +if #compound.enumArray > 0 then + includeFile("overview_enums.rst.in", compound) + emit("\n") +end + +if #compound.classArray > 0 then + includeFile("overview_classes.rst.in", compound) + emit("\n") +end + +if #compound.structArray > 0 then + includeFile("overview_structs.rst.in", compound) + emit("\n") +end + +if compound.compoundKind == "class" or compound.compoundKind == "struct" then + if #compound.variableArray > 0 then +} + $(compound.name) =$g_preBodySpace{ +%{ + includeFileWithIndent("\t", "overview_variables.rst.in", compound, variableSectionName, ",") + + if compound.baseTypeArray and #compound.baseTypeArray then + + -- always link inherited members (even when no documentation) + + local prevHasItemDocumentation = hasItemDocumentation + hasItemDocumentation = function(item) + return true + end + + for i = 1, #compound.baseTypeArray do + local baseType = compound.baseTypeArray[i] +} + + -- inherited from :ref:`$(baseType.name)` + +%{ + includeFileWithIndent("\t", "overview_variables.rst.in", baseType, null, ",") + end -- for + + hasItemDocumentation = prevHasItemDocumentation + end --if +} + } + +%{ + else +} + $(compound.name) = {} + +%{ + end -- if +elseif #compound.variableArray > 0 then + includeFile("overview_variables.rst.in", compound, variableSectionName) + emit("\n") +end + +if #compound.functionArray > 0 then + includeFile("overview_functions.rst.in", compound, functionSectionName) + emit("\n") +end +} diff --git a/docs/doxyrest/frame/lua/overview_enums.rst.in b/docs/doxyrest/frame/lua/overview_enums.rst.in new file mode 100644 index 000000000..ccafaa82e --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_enums.rst.in @@ -0,0 +1,30 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +} + -- enumeration types + +%{ +for i = 1, #compound.enumArray do + local item = compound.enumArray[i] + local targetFileName = getItemFileName(item) + + if compound.compoundKind ~= "group" then + generateFile(targetFileName, "enum.rst.in", item) + end +} + :ref:`$(item.name)` +%{ +end -- for +} diff --git a/docs/doxyrest/frame/lua/overview_functions.rst.in b/docs/doxyrest/frame/lua/overview_functions.rst.in new file mode 100644 index 000000000..6972f34f9 --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_functions.rst.in @@ -0,0 +1,37 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local sectionName = argArray[2] +} + -- $sectionName + +%{ +local isPrevMl = false + +for i = 1, #compound.functionArray do + local item = compound.functionArray[i] + local decl = getFunctionDeclString(item, getItemNameTemplate(item), "\t") + local isMl = string.find(decl, "\n") + local extraNl = "" + + if i > 1 and (isMl or isPrevMl) then + extraNl = "\n" + end + + isPrevMl = isMl +} +$extraNl $decl +%{ +end -- for +} diff --git a/docs/doxyrest/frame/lua/overview_modules.rst.in b/docs/doxyrest/frame/lua/overview_modules.rst.in new file mode 100644 index 000000000..94651e76b --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_modules.rst.in @@ -0,0 +1,27 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +} + -- modules + +%{ +for i = 1, #compound.namespaceArray do + local item = compound.namespaceArray[i] + local targetFileName = getItemFileName(item) + generateFile(targetFileName, "class.rst.in", item, "module") +} + :ref:`$(item.name)` +%{ +end -- for +} diff --git a/docs/doxyrest/frame/lua/overview_structs.rst.in b/docs/doxyrest/frame/lua/overview_structs.rst.in new file mode 100644 index 000000000..e31c6b8ac --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_structs.rst.in @@ -0,0 +1,27 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +} + -- table types + +%{ +for i = 1, #compound.structArray do + local item = compound.structArray[i] + local targetFileName = getItemFileName(item) + generateFile(targetFileName, "class.rst.in", item, "table") +} + :ref:`$(item.name)` +%{ +end -- for +} diff --git a/docs/doxyrest/frame/lua/overview_variables.rst.in b/docs/doxyrest/frame/lua/overview_variables.rst.in new file mode 100644 index 000000000..75f2090f0 --- /dev/null +++ b/docs/doxyrest/frame/lua/overview_variables.rst.in @@ -0,0 +1,32 @@ +%{ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +local argArray = table.pack(...) +local compound = argArray[1] +local sectionName = argArray[2] +local comma = argArray[3] + +if sectionName then +} + -- $sectionName + +%{ +end -- if + +for i = 1, #compound.variableArray do + local item = compound.variableArray[i] + local nameTemplate = getItemNameTemplate(item) +} + $(getItemLocalPrefix(item))$(fillItemNameTemplate(nameTemplate, item.name, item.id))$comma +%{ +end -- for +} diff --git a/docs/doxyrest/frame/lua/utils.lua b/docs/doxyrest/frame/lua/utils.lua new file mode 100644 index 000000000..3484d3729 --- /dev/null +++ b/docs/doxyrest/frame/lua/utils.lua @@ -0,0 +1,228 @@ +-------------------------------------------------------------------------------- +-- +-- This file is part of the Doxyrest toolkit. +-- +-- Doxyrest is distributed under the MIT license. +-- For details see accompanying license.txt file, +-- the public copy of which is also available at: +-- http://tibbo.com/downloads/archive/doxyrest/license.txt +-- +-------------------------------------------------------------------------------- + +g_luaUtilsIncluded = true + +dofile(g_frameDir .. "/../common/string.lua") +dofile(g_frameDir .. "/../common/table.lua") +dofile(g_frameDir .. "/../common/item.lua") +dofile(g_frameDir .. "/../common/doc.lua") +dofile(g_frameDir .. "/../common/toc.lua") + +LANGUAGE = "lua" + +if not INDEX_TITLE then + INDEX_TITLE = "My Project Documentation" +end + +if not EXTRA_PAGE_LIST then + EXTRA_PAGE_LIST = {} +end + +if not EXTERNAL_CREF_DB then + EXTERNAL_CREF_DB = {} +end + +if PRE_PARAM_LIST_SPACE then + g_preParamSpace = " " +else + g_preParamSpace = "" +end + +if PRE_BODY_NL then + g_preBodySpace = "\n\t" +else + g_preBodySpace = " " +end + +if not g_globalNamespace.title then + g_globalNamespace.title = "Global Scope" +end + +------------------------------------------------------------------------------- + +-- formatting of function declarations + +function getParamName(param) + if param.declarationName ~= "" then + return param.declarationName + elseif param.definitionName ~= "" then + return param.definitionName + else + return param.type.plainText + end +end + +function getParamArrayString_sl(paramArray) + local s = "(" + + local count = #paramArray + if count > 0 then + s = s .. getParamName(paramArray[1]) + + for i = 2, count do + s = s .. ", " .. getParamName(paramArray[i]) + end + end + + return s .. ")" +end + +function getParamArrayString_ml(paramArray, indent) + local s = "(" + + if not indent then + indent = "" + end + + local nl = "\n" .. indent .. "\t" + + local count = #paramArray + if count > 0 then + s = s .. nl .. getParamName(paramArray[1]) + + for i = 2, count do + s = s .. "," .. nl .. getParamName(paramArray[i]) + end + end + + return s .. nl .. ")" +end + +function getFunctionDeclString(func, nameTemplate, indent) + local funcName + if func.virtualKind == "non-virtual" then + funcName = string.gsub(func.path, "/", ".") + else + local count + funcName, count = string.gsub(func.path, "/", ":") + if count > 1 then + funcName = string.gsub(funcName, ":", ".", count - 1) + end + end + + local s = getItemLocalPrefix(func) .. "function " .. fillItemNameTemplate(nameTemplate, funcName, func.id) + local paramString + + if ML_PARAM_LIST_COUNT_THRESHOLD and + #func.paramArray > ML_PARAM_LIST_COUNT_THRESHOLD then + paramString = getParamArrayString_ml(func.paramArray, indent) + else + paramString = getParamArrayString_sl(func.paramArray) + + if ML_PARAM_LIST_LENGTH_THRESHOLD then + local decl = "function " .. func.name .. g_preParamSpace .. paramString + decl = replaceRolesWithPlainText(decl) + + if string.len(decl) > ML_PARAM_LIST_LENGTH_THRESHOLD then + paramString = getParamArrayString_ml(func.paramArray, indent) + end + end + end + + return s .. g_preParamSpace .. paramString +end + +function getItemLocalPrefix(item) + -- lua 'local' translates to C/C++ 'static' + + if string.find(item.flags, "static") then + return "local " + else + return "" + end +end + +------------------------------------------------------------------------------- + +-- compound prep + +function itemLocationFilter(item) + return not (item.location and string.match(item.location.file, EXCLUDE_LOCATION_PATTERN)) +end + +function itemLocalFilter(item) + -- lua 'local' translates to C/C++ 'static' + + return not string.find(item.flags, "static") +end + +function prepareCompound(compound) + if compound.stats then + return compound.stats + end + + local stats = {} + + if EXCLUDE_LOCATION_PATTERN then + filterArray(compound.namespaceArray, itemLocationFilter) + filterArray(compound.enumArray, itemLocationFilter) + filterArray(compound.structArray, itemLocationFilter) + filterArray(compound.classArray, itemLocationFilter) + filterArray(compound.variableArray, itemLocationFilter) + filterArray(compound.functionArray, itemLocationFilter) + end + + if EXCLUDE_LUA_LOCALS then + filterArray(compound.variableArray, itemLocalFilter) + filterArray(compound.functionArray, itemLocalFilter) + end + + stats.hasItems = + #compound.namespaceArray ~= 0 or + #compound.enumArray ~= 0 or + #compound.structArray ~= 0 or + #compound.classArray ~= 0 or + #compound.variableArray ~= 0 or + #compound.functionArray ~= 0 + + stats.hasBriefDocumentation = not isDocumentationEmpty(compound.briefDescription) + stats.hasDetailedDocumentation = not isDocumentationEmpty(compound.detailedDescription) + stats.hasDocumentedVariables = prepareItemArrayDocumentation(compound.variableArray, compound) + stats.hasDocumentedFunctions = prepareItemArrayDocumentation(compound.functionArray, compound) + stats.hasDocumentedItems = stats.hasDocumentedVariables or stats.hasDocumentedFunctions + + if EXCLUDE_UNDOCUMENTED_ITEMS then + filterArray(compound.variableArray, hasItemDocumentation) + filterArray(compound.functionArray, hasItemDocumentation) + end + + table.sort(compound.groupArray, cmpGroups) + table.sort(compound.namespaceArray, cmpNames) + table.sort(compound.enumArray, cmpNames) + table.sort(compound.structArray, cmpNames) + table.sort(compound.classArray, cmpNames) + + if SORT_GLOBAL_MEMBERS and compound.compoundKind ~= "struct" and compound.compoundKind ~= "class" then + table.sort(compound.variableArray, cmpNames) + table.sort(compound.functionArray, cmpNames) + end + + compound.stats = stats + + return stats +end + +function prepareEnum(enum) + local stats = {} + + stats.hasDocumentedEnumValues = prepareItemArrayDocumentation(enum.enumValueArray) + stats.hasBriefDocumentation = not isDocumentationEmpty(enum.briefDescription) + stats.hasDetailedDocumentation = not isDocumentationEmpty(enum.detailedDescription) + + return stats +end + +function getEnumValueString(enumValue) + return (string.gsub(enumValue.initializer.plainText, "^%s*=%s*", "")) -- remove leading = +end + +------------------------------------------------------------------------------- diff --git a/docs/doxyrest/sphinx/conf/docutils.conf b/docs/doxyrest/sphinx/conf/doxyrest-docutils.conf.in similarity index 86% rename from docs/doxyrest/sphinx/conf/docutils.conf rename to docs/doxyrest/sphinx/conf/doxyrest-docutils.conf.in index e0febecf8..54d8314e4 100644 --- a/docs/doxyrest/sphinx/conf/docutils.conf +++ b/docs/doxyrest/sphinx/conf/doxyrest-docutils.conf.in @@ -3,7 +3,7 @@ footnote_backlinks = false [restructuredtext parser] trim_footnote_reference_space = false -tab_width = 4 +tab_width = %tab_width% [html4css1 writer] footnote_references = superscript diff --git a/docs/doxyrest/sphinx/cpplexer.py b/docs/doxyrest/sphinx/cpplexer.py index 8d45daaf5..4d3a8f85f 100644 --- a/docs/doxyrest/sphinx/cpplexer.py +++ b/docs/doxyrest/sphinx/cpplexer.py @@ -307,3 +307,9 @@ def setup(app): lexers['c++'] = cpp_lexer lexers['c++'] = cpp_lexer lexers['idl'] = idl_lexer + + return { + 'version': 'builtin', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/docs/doxyrest/sphinx/doxyrest.py b/docs/doxyrest/sphinx/doxyrest.py index 037127e89..622b127f5 100644 --- a/docs/doxyrest/sphinx/doxyrest.py +++ b/docs/doxyrest/sphinx/doxyrest.py @@ -12,29 +12,60 @@ import os import re import warnings +from packaging import version from docutils import nodes from docutils.parsers.rst import Directive, directives from docutils.transforms import Transform -from docutils.statemachine import StringList, string2lines -from sphinx import roles, addnodes, config -from sphinx.io import SphinxBaseFileInput, SphinxRSTFileInput +from sphinx import __version__ as sphinx_version_string, roles, addnodes, config from sphinx.directives.other import Include +from sphinx.domains import Domain #............................................................................... # # utils # +sphinx_version = version.parse(sphinx_version_string) this_dir = os.path.dirname(os.path.realpath(__file__)) +url_re_prog = re.compile('(ftp|https?)://') crefdb = {} +cref_w_target_re_prog = re.compile('(.+?)\s*<([^<>]*)>$') -def get_cref_target(text): - if text in crefdb: - return crefdb[text] +def get_cref_target(text, target=None): + if not target: + target = text - warnings.warn('target not found for cref: ' + text, Warning, 2) + if target in crefdb: + return crefdb[target] + + warnings.warn('target not found for cref: ' + target, Warning, 2) return None +def get_cref_target_ex(text): + match = cref_w_target_re_prog.match(text) + if match: + text = match.group(1) + target = match.group(2) + else: + target = text + + return get_cref_target(text, target), text + +# Sphinx.add_javascript was renamed to add_js_file in 1.8.0 +# Sphinx.add_stylesheet was renamed to add_css_file in 1.8.0 + +if sphinx_version >= version.parse('1.8.0'): + def add_js_file(app, filename): + app.add_js_file(filename) + + def add_css_file(app, filename): + app.add_css_file(filename) +else: + def add_js_file(app, filename): + app.add_javascript(filename) + + def add_css_file(app, filename): + app.add_stylesheet(filename) #............................................................................... # @@ -76,10 +107,13 @@ def visit_highlighted_text_node(self, node): raise nodes.SkipNode -def create_xref_node(raw_text, text, target): +def create_ref_node(raw_text, text, target): if not target: return nodes.Text(text, text) + if url_re_prog.match(target): + return nodes.reference(raw_text, text, refuri=target) + node = addnodes.pending_xref(raw_text) node['reftype'] = 'ref' node['refdomain'] = 'std' @@ -136,7 +170,6 @@ class RefCodeBlock(Directive): role_re_src += '`(.+?)(\s*<([^<>]*)>)?`' self.role_re_prog = re.compile(role_re_src) self.ws_re_prog = re.compile('\s+') - self.url_re_prog = re.compile('(ftp|https?)://') def run(self): config = self.state.document.settings.env.config @@ -167,7 +200,6 @@ class RefCodeBlock(Directive): role = match.group(1) text = match.group(2) target = match.group(4) - pos = match.end() if text: @@ -191,33 +223,19 @@ class RefCodeBlock(Directive): ['doxyrest-code-target'] ) - elif not role or role == ':cref:': - target = get_cref_target(target if target else text) - new_node = create_xref_node(raw_text, text, target) - - else: # :ref: - if not target: + else: + if not role or role == ':cref:': + target = get_cref_target(text, target) + elif not target: target = text - if self.url_re_prog.match(target): - new_node = nodes.reference(raw_text, text, refuri=target) - else: - new_node = create_xref_node(raw_text, text, target) + new_node = create_ref_node(raw_text, text, target) node += new_node self.add_name(node) return [node] - -class TabAwareInclude(Include): - def run(self): - # update tab_width setting - self.state.document.settings.tab_width = \ - self.state.document.settings.env.config.doxyrest_tab_width - return Include.run(self) - - #............................................................................... # # Sphinx transforms @@ -274,9 +292,9 @@ class RefTransform(Transform): target = match.group(4) if not role or role == ':cref:': - target = get_cref_target(text) + target = get_cref_target(text, target) - node += create_xref_node(raw_text, text, target) + node += create_ref_node(raw_text, text, target) pos = match.end() @@ -286,15 +304,10 @@ class RefTransform(Transform): # def cref_role(typ, raw_text, text, lineno, inliner, options={}, content=[]): - target = get_cref_target(text) - - if text.find(' ') == -1: - node = nodes.literal(raw_text, '') - else: - node = nodes.inline(raw_text, '') - + target, text = get_cref_target_ex(text) + node = nodes.literal(raw_text, '') node['classes'] += ['doxyrest-cref'] - node += create_xref_node(raw_text, text, target) + node += create_ref_node(raw_text, text, target) return [node], [] def target_role(typ, raw_text, text, lineno, inliner, options={}, content=[]): @@ -304,27 +317,70 @@ def target_role(typ, raw_text, text, lineno, inliner, options={}, content=[]): #............................................................................... # -# Sphinx source inputs +# Doxyrest domain -- so that the cref-database is checked for :any: refs # -class TabAwareSphinxRSTFileInput(SphinxRSTFileInput): - def read(self): - # type: () -> StringList - inputstring = SphinxBaseFileInput.read(self) - tab_width = self.env.config.doxyrest_tab_width - lines = string2lines(inputstring, convert_whitespace=True, tab_width=tab_width) +class DoxyrestDomain(Domain): + name = 'doxyrest' + label = 'Doxyrest' - content = StringList() - for lineno, line in enumerate(lines): - content.append(line, self.source_path, lineno) + def merge_domaindata(self, docnames, otherdata): + pass # as to avoid errors on parallel builds - if self.env.config.rst_prolog: - self.prepend_prolog(content, self.env.config.rst_prolog) - if self.env.config.rst_epilog: - self.append_epilog(content, self.env.config.rst_epilog) + def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): + cref_target = get_cref_target(target, target) + if not cref_target: + return [] - return content + std = env.get_domain('std') + node['refexplicit'] = True + resolved_node = std.resolve_xref(env, fromdocname, builder, 'ref', cref_target, node, contnode) + if not resolved_node: # shouldn't really happen + return [] + result_node = nodes.literal(target, '') + result_node += resolved_node + return [('std:ref', result_node)] + + +#............................................................................... +# +# Sphinx source inputs -- a workaround for sphinx-2.0.1 (and below) +# completely ignoring docutils.conf:tab_width +# + +is_sphinx_tab_aware = sphinx_version >= version.parse('2.1.0') + +if not is_sphinx_tab_aware: + from sphinx.io import SphinxBaseFileInput, SphinxRSTFileInput + from docutils.statemachine import StringList, string2lines + + + class TabAwareSphinxRSTFileInput(SphinxRSTFileInput): + def read(self): + # type: () -> StringList + inputstring = SphinxBaseFileInput.read(self) + tab_width = self.env.config.doxyrest_tab_width + lines = string2lines(inputstring, convert_whitespace=True, tab_width=tab_width) + + content = StringList() + for lineno, line in enumerate(lines): + content.append(line, self.source_path, lineno) + + if self.env.config.rst_prolog: + self.prepend_prolog(content, self.env.config.rst_prolog) + if self.env.config.rst_epilog: + self.append_epilog(content, self.env.config.rst_epilog) + + return content + + + class TabAwareInclude(Include): + def run(self): + # update tab_width setting + self.state.document.settings.tab_width = \ + self.state.document.settings.env.config.doxyrest_tab_width + return Include.run(self) #............................................................................... # @@ -337,8 +393,8 @@ def on_builder_inited(app): this_dir + '/js/target-highlight.js' ] - app.add_stylesheet('doxyrest-pygments.css') - app.add_javascript('target-highlight.js') + add_css_file(app, 'doxyrest-pygments.css') + add_js_file(app, 'target-highlight.js') supported_themes = { 'sphinx_rtd_theme', @@ -348,7 +404,7 @@ def on_builder_inited(app): if app.config.html_theme in supported_themes: css_file = 'doxyrest-' + app.config.html_theme + '.css' app.config.html_static_path += [this_dir + '/css/' + css_file]; - app.add_stylesheet(css_file); + add_css_file(app, css_file); for basedir, dirnames, filenames in os.walk(app.srcdir): if 'crefdb.py' in filenames: @@ -361,12 +417,42 @@ def on_builder_inited(app): global crefdb crefdb.update(new_crefdb) +def on_config_inited(app, config): + + # prepare and register doxyrest-specific docutils.conf + + # it's OK to put yet another docutils.conf into your config dir to + # override settings if necessary + + docutils_conf_in_path = this_dir + '/conf/doxyrest-docutils.conf.in' + docutils_conf_path = app.doctreedir + '/doxyrest-docutils.conf' + + src_file = open(docutils_conf_in_path, 'r') + contents = src_file.read() + contents = contents.replace('%tab_width%', str(config.doxyrest_tab_width)) + src_file.close() + + if not os.path.exists(app.doctreedir): + os.makedirs(app.doctreedir) + + dst_file = open(docutils_conf_path, 'w') + dst_file.write(contents) + dst_file.close() + + if 'DOCUTILSCONFIG' in os.environ: + prev_docutils_conf = os.environ['DOCUTILSCONFIG'] + os.environ['DOCUTILSCONFIG'] = docutils_conf_path + os.pathsep + prev_docutils_conf + else: + os.environ['DOCUTILSCONFIG'] = docutils_conf_path + #............................................................................... # # Doxyrest extenstion setup # def setup(app): + app.add_domain(DoxyrestDomain) + app.add_node( HighlightedText, html=(visit_highlighted_text_node, None), @@ -375,23 +461,19 @@ def setup(app): app.add_role('cref', cref_role) app.add_role('target', target_role) - app.add_config_value('doxyrest_tab_width', default=4, rebuild=True) app.add_config_value('doxyrest_cref_file', default=None, rebuild=True) - app.registry.source_inputs['restructuredtext'] = TabAwareSphinxRSTFileInput + app.add_config_value('doxyrest_tab_width', default=4, rebuild=True) directives.register_directive('ref-code-block', RefCodeBlock) - directives.register_directive('include', TabAwareInclude) app.add_transform(RefTransform) app.connect('builder-inited', on_builder_inited) + app.connect('config-inited', on_config_inited) - # register our docutils.conf + if not is_sphinx_tab_aware: + app.registry.source_inputs['restructuredtext'] = TabAwareSphinxRSTFileInput + directives.register_directive('include', TabAwareInclude) - prevConfig = None - - if 'DOCUTILSCONFIG' in os.environ: - prevConfig = os.environ['DOCUTILSCONFIG'] - - os.environ['DOCUTILSCONFIG'] = this_dir + '/conf/docutils.conf' - - if prevConfig: - os.environ['DOCUTILSCONFIG'] += os.pathsep - os.environ['DOCUTILSCONFIG'] += prevConfig + return { + 'version': 'builtin', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + }