From c8e305dbc34929399ff0434c558b7798ed483371 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Wed, 13 Jan 2016 04:31:09 +0000 Subject: [PATCH] CHM fixes --- chm-nav.dd | 35 +++++++++- chmgen.d | 173 +++++++++++++++++++++++++++---------------------- css/style.css | 3 +- dlang.org.ddoc | 16 ++--- spec/spec.ddoc | 9 +-- win32.mak | 13 ++-- 6 files changed, 147 insertions(+), 102 deletions(-) diff --git a/chm-nav.dd b/chm-nav.dd index ad595cf5e2..276806032a 100644 --- a/chm-nav.dd +++ b/chm-nav.dd @@ -2,7 +2,36 @@ Ddoc Macros: -DDOC=[$(NAVIGATION)] +DDOC= +[ + { + "hook" : "", + "root" : "", + "nav" : [{"t":"D Programming Language","a":"index.html"},$(NAVIGATION)] + }, + { + "hook" : "Language Reference", + "root" : "", + "nav" : [$(SUBNAV_SPEC)] + }, + { + "hook" : "Library Reference", + "root" : "phobos/", + "nav" : [{"t":"Library Reference","a":"index.html"},$(MODULE_MENU)] + }, + { + "hook" : "Articles", + "root" : "", + "nav" : [$(SUBNAV_ARTICLES)] + }, + { + "hook" : "D-Specific Tools", + "root" : "", + "nav" : [$(SUBNAV_TOOLS)] + }, +] +_= + DIVID=$2 B=$0 TT=$0 @@ -14,15 +43,19 @@ LATEST= MENU={"t":"$2","a":"$1"}, MENU_W_SUBMENU=[{"t":"$2"}, MENU_W_SUBMENU_END= +MENU_W_SUBMENU_LINK=[{"t":"$2","a":"$1"}, ITEMIZE=$(ITEMS_HELPER $1, $+)], ITEMS_HELPER = $1$(ITEMS_HELPER $+) SUBMENU=$(SUBMENU2 $1,$+)], SUBMENU2={"t":"$2","a":"$1"}, $(SUBMENU3 $+) SUBMENU3=$(SUBMENU2 $+) +SUBNAV_TEMPLATE=$0 +SUBNAV_HEAD={"t":"$3","a":"$2"}, MODULE= {"t":"$1","a":"$2$(JOIN_LINE_TAIL $+).html"}, PACKAGE=[$1$(ITEMIZE $+) PACKAGE_NAME={"t":"$1"}, ESCAPES=/"/\"/ +ROOT_DIR= _= diff --git a/chmgen.d b/chmgen.d index d54a070612..ec229309d7 100644 --- a/chmgen.d +++ b/chmgen.d @@ -17,79 +17,6 @@ string docRoot = `.`; // ******************************************************************** -class Nav -{ - string title, url; - Nav[] children; -} - -Nav loadNav(string fileName, string base, bool warn) -{ - import std.json; - auto text = fileName - .readText() - .replace("\r", "") - .replace("\n", "") - // .replaceAll(re!`/\*.*?\*/`, "") - .replaceAll(re!`,\s*\]`, `]`) - ; - scope(failure) std.file.write("error.json", text); - auto json = text.parseJSON(); - - Nav parseNav(JSONValue json) - { - if (json.type == JSON_TYPE.ARRAY) - { - auto nodes = json.array; - auto parsedNodes = nodes.map!parseNav.array().filter!`a`.array(); - if (!parsedNodes.length) - { - if (warn) - stderr.writeln("Warning: Empty navigation group"); - return null; - } - - auto root = parsedNodes[0]; - root.children = parsedNodes[1..$]; - return root; - } - else - { - auto obj = json.object; - auto nav = new Nav; - nav.title = obj["t"].str.strip(); - if ("a" in obj) - { - auto url = absoluteUrl(base, obj["a"].str.strip()); - if (url.canFind(`://`)) - { - stderr.writeln("Skipping external navigation item: " ~ url); - return null; - } - else - if (!exists(`chm/files/` ~ url)) - { - if (warn) - stderr.writeln("Warning: Item in navigation does not exist: " ~ url); - else - stderr.writeln("Skipping non-existent navigation item: " ~ url); - //url = "http://dlang.org/" ~ url; - return null; - } - else - nav.url = `files\` ~ url.backSlashes(); - } - return nav; - } - } - - return parseNav(json); -} - -Nav nav; - -// ******************************************************************** - struct KeyLink { string anchor; int confidence; bool sawAnchor; } KeyLink[string][string] keywords; // keywords[keyword][original url w/o anchor] = anchor/confidence string[] keywordList; // Sorted alphabetically, case-insensitive @@ -101,6 +28,11 @@ void addKeyword(string keyword, string link, int confidence, bool isAnchor = tru if (!keyword.length) return; link = link.strip(); + + while (link.skipOver("./")) {} + if (link.endsWith("/")) + link ~= "index.html"; + string file = link.stripAnchor(); string anchor = link.getAnchor(); @@ -204,7 +136,7 @@ void main(string[] args) foreach (m; src.matchAll(re!(`(.*?)`))) if (!m.captures[1].canFind("://")) - addKeyword(m.captures[2].replaceAll(re!`<.*?>`, ``), absoluteUrl(fileName, m.captures[1]), 4, false); + addKeyword(m.captures[2].replaceAll(re!`<.*?>`, ``), absoluteUrl(fileName, m.captures[1].strip()), 4, false); // Disable scripts @@ -246,15 +178,98 @@ void main(string[] args) // ************************************************************ +class Nav +{ + string title, url; + Nav[] children; +} + +Nav nav; + void loadNavigation() { stderr.writeln("Loading navigation"); - nav = loadNav("chm-nav-doc.json", ``, false); - auto phobosIndex = `files\phobos\index.html`; - auto navPhobos = nav.children.find!(child => child.url == phobosIndex).front; - auto phobos = loadNav("chm-nav-std.json", `phobos/`, true); - navPhobos.children = phobos.children.filter!(child => child.url != phobosIndex).array(); + import std.json; + auto text = "chm-nav.json" + .readText() + .replace("\r", "") + .replace("\n", "") + // .replaceAll(re!`/\*.*?\*/`, "") + .replaceAll(re!`,\s*\]`, `]`) + ; + scope(failure) std.file.write("error.json", text); + auto json = text.parseJSON(); + + Nav[string] subNavs; + + foreach_reverse (node; json.array) + { + auto hook = node["hook"].str; + auto root = node["root"].str; + + Nav parseNav(JSONValue json) + { + if (json.type == JSON_TYPE.ARRAY) + { + auto nodes = json.array; + auto parsedNodes = nodes.map!parseNav.array().filter!`a`.array(); + if (!parsedNodes.length) + { + if (/*warn*/true) + stderr.writeln("Warning: Empty navigation group"); + return null; + } + + auto root = parsedNodes[0]; + root.children = parsedNodes[1..$]; + return root; + } + else + { + auto obj = json.object; + auto nav = new Nav; + nav.title = obj["t"].str.strip(); + if ("a" in obj) + { + auto url = absoluteUrl(root, obj["a"].str.strip()); + if (url.canFind(`://`)) + { + stderr.writeln("Skipping external navigation item: " ~ url); + return null; + } + else + if (!exists(`chm/files/` ~ url)) + { + if (/*warn*/true) + stderr.writeln("Warning: Item in navigation does not exist: " ~ url); + else + stderr.writeln("Skipping non-existent navigation item: " ~ url); + //url = "http://dlang.org/" ~ url; + return null; + } + else + nav.url = `files\` ~ url.backSlashes(); + } + auto psubNav = nav.title in subNavs; + if (psubNav) + { + // if (nav.title != psubNav.title) + // stderr.writefln("Warning: Sub-navigation title mismatch: %s / %s", nav.title, psubNav.title); + // if (nav.url != psubNav.url) + // stderr.writefln("Warning: Sub-navigation url mismatch: %s / %s", nav.url, psubNav.url); + nav.url = psubNav.url; + nav.children = psubNav.children; + } + return nav; + } + } + + auto nav = parseNav(node["nav"]); + subNavs[hook] = nav; + } + + .nav = subNavs[""]; } // ************************************************************ diff --git a/css/style.css b/css/style.css index dfea5175dc..f6d773bfe4 100644 --- a/css/style.css +++ b/css/style.css @@ -1196,7 +1196,8 @@ img } body.chm div#news, -body.chm div#navigation, +body.chm div.subnav-helper, +body.chm div.subnav, body.chm div#top { display: none; diff --git a/dlang.org.ddoc b/dlang.org.ddoc index 8480b7c6f9..b32ed6e8cc 100644 --- a/dlang.org.ddoc +++ b/dlang.org.ddoc @@ -340,10 +340,7 @@ _= SUBNAV= SUBNAV_ARTICLES= $(SUBNAV_TEMPLATE - $(DIVC head, - $(H2 Articles) - $(P $(LINK2 $(ROOT_DIR)articles.html, overview)) - ) + $(SUBNAV_HEAD Articles, articles.html, overview) $(UL $(SUBMENU2 $(ROOT_DIR)faq.html, FAQ, $(ROOT_DIR)const-faq.html, const(FAQ), @@ -370,15 +367,18 @@ $(SUBNAV_TEMPLATE )) ) +SUBNAV_HEAD= + $(DIVC head, + $(H2 $1) + $(TC p, $4, + $(LINK2 $(ROOT_DIR)$2, $3)) + ) SUBNAV_TEMPLATE=$(DIVC subnav-helper) $(DIVC subnav, $0) _= SUBNAV_TOOLS= $(SUBNAV_TEMPLATE - $(DIVC head, - $(H2 D-Specific Tools) - $(P $(LINK2 $(ROOT_DIR)tools.html, overview)) - ) + $(SUBNAV_HEAD D-Specific Tools, tools.html, overview) $(UL $(SUBMENU2 https://github.com/Hackerpilot/dfix, dfix, https://github.com/Hackerpilot/dfmt, dfmt, diff --git a/spec/spec.ddoc b/spec/spec.ddoc index 1fece3e4f5..66c2336ede 100644 --- a/spec/spec.ddoc +++ b/spec/spec.ddoc @@ -2,13 +2,10 @@ ROOT_DIR = ../ ROOT = .. SEARCHDEFAULT_SPEC = selected -SUBNAV= +SUBNAV=$(SUBNAV_SPEC) +SUBNAV_SPEC= $(SUBNAV_TEMPLATE - $(DIVC head, - $(H2 Language Reference) - $(TC p, subnav-duplicate, - $(LINK2 $(ROOT_DIR)spec/spec.html, table of contents)) - ) + $(SUBNAV_HEAD Language Reference, spec/spec.html, table of contents, subnav-duplicate) $(UL $(SUBMENU2 $(ROOT_DIR)spec/intro.html, Introduction, diff --git a/win32.mak b/win32.mak index da2056fc25..c01614311f 100644 --- a/win32.mak +++ b/win32.mak @@ -591,18 +591,17 @@ chm : d.chm chmgen.exe : chmgen.d $(DMD) -g chmgen -chm\d.hhp chm\d.hhc chm\d.hhk : chmgen.exe chm-nav-doc.json chm-nav-std.json $(TARGETS) +chm\d.hhp chm\d.hhc chm\d.hhk : chmgen.exe chm-nav.json $(TARGETS) chmgen -d.chm : chm\d.hhp chm\d.hhc chm\d.hhk +chm\d.chm : chm\d.hhp chm\d.hhc chm\d.hhk -cmd /C "cd chm && "$(HHC)" d.hhp" - copy /Y chm\d.chm d.chm -chm-nav-doc.json : $(DDOC) chm-nav.dd - $(DMD) -o- -c -Df$@ $(DDOC) chm-nav.dd +d.chm : chm\d.chm + copy /Y chm\d.chm d.chm -chm-nav-std.json : $(DDOC) $(DDOC_STD) chm-nav.dd - $(DMD) -o- -c -Df$@ $(DDOC) $(DDOC_STD) chm-nav.dd +chm-nav.json : $(DDOC) std.ddoc spec\spec.ddoc modlist-release.ddoc chm-nav.dd + $(DMD) -o- -c -Df$@ $** d.tag : chmgen.exe $(TARGETS) chmgen --only-tags