From 879ac405ee80f91b574517355f029a406d123302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Laleve=CC=81e?= Date: Sat, 27 Dec 2014 23:42:13 +0100 Subject: [PATCH 01/10] Experimental xooki to asciidoc convertor --- asciidoc-template/document.html.slim | 87 ++ asciidoc-template/helpers.rb | 168 +++ build-doc.xml | 58 + doc/xooki2asciidoc/antlib.xml | 82 ++ doc/xooki2asciidoc/xooki2asciidoc.js | 1569 ++++++++++++++++++++++++++ 5 files changed, 1964 insertions(+) create mode 100644 asciidoc-template/document.html.slim create mode 100644 asciidoc-template/helpers.rb create mode 100644 build-doc.xml create mode 100644 doc/xooki2asciidoc/antlib.xml create mode 100644 doc/xooki2asciidoc/xooki2asciidoc.js diff --git a/asciidoc-template/document.html.slim b/asciidoc-template/document.html.slim new file mode 100644 index 00000000..81e99a88 --- /dev/null +++ b/asciidoc-template/document.html.slim @@ -0,0 +1,87 @@ +doctype transitional +/! +/! Licensed to the Apache Software Foundation (ASF) under one +/! or more contributor license agreements. See the NOTICE file +/! distributed with this work for additional information +/! regarding copyright ownership. The ASF licenses this file +/! to you under the Apache License, Version 2.0 (the +/! "License"); you may not use this file except in compliance +/! with the License. You may obtain a copy of the License at +/! +/! http://www.apache.org/licenses/LICENSE-2.0 +/! +/! Unless required by applicable law or agreed to in writing, +/! software distributed under the License is distributed on an +/! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +/! KIND, either express or implied. See the License for the +/! specific language governing permissions and limitations +/! under the License. +- page = IvyDocHelpers.page(attr("basedir"), attr("docfile")) +html lang=(attr :lang, 'en' unless attr? :nolang) + head + meta http-equiv="Content-Type" content="text/html; charset=utf-8" + meta name='generator' content="Asciidoctor #{attr 'asciidoctor-version'}" + title=((doctitle :sanitize => true) || (attr 'untitled-label')) + link rel="stylesheet" type="text/css" href="#{page.relativeRoot}style/style.css" + script src="#{page.relativeRoot}js/jquery.pack.js" type="text/javascript" + script src="#{page.relativeRoot}js/jquery.treeview.js" type="text/javascript" + javascript: + $(document).ready(function(){$("#treemenu").Treeview({speed: "fast",store: true});}); + body + div id="body" + table id="header" summary="Navigation elements." border="0" cellpadding="0" cellspacing="0" width="100%" + tr + td id="home" width="30%" + a href="http://ant.apache.org/" title="Apache Ant" + img src="#{page.relativeRoot}images/ant-group-logo.gif" alt="Apache Ant" border="0"/ + td class="product" width="70%" align="right" valign="middle" + img src="#{page.relativeRoot}images/logo.png" alt="ivy" border="0"/ + table id="top-menu" summary="Navigation elements." border="0" cellpadding="0" cellspacing="0" width="100%" + tr + td + div id="navcontainer" + a<> href="http://www.apache.org/" Apache™ + | > + a<> href="http://ant.apache.org/" Apache Ant™ + | > + a<> href="http://ant.apache.org/ivy/" Apache Ivy™ + | > + = page.breadCrumb + table id="content" border="0" cellpadding="0" cellspacing="0" width="100%" + tr + td id="sidebar-left" + div class="block block-book" id="block-book-0" + h2 Apache Ivy™ + div class="content" + = page.menu() + center + iframe src="http://www.apache.org/ads/buttonbar.html" style="border-width:0;" frameborder="0" scrolling="no" width="135" height="265" + td valign="top" + div id="main" + h1 class="title" = page.title + #content=content + table id="footer-menu" summary="Navigation elements." border="0" cellpadding="0" cellspacing="0" width="100%" + tr + td align="center" valign="middle" + div class="primary-links" + | :: + a href="index.html" Home + | :: + a href="reference.html" Reference + | :: + a href="tutorial.html" Tutorials + | :: + a href="dev.html" Developer's doc + | :: + div id="footer-message" class="footer" + hr/ + i + | Copyright © 2014 The Apache Software Foundation, Licensed under the + a href="http://www.apache.org/licenses/LICENSE-2.0.txt" Apache License, Version 2.0 + | . + br/ + i + | Apache Ivy, Apache Ant, Ivy, Ant, Apache, the Apache Ivy logo, the Apache Ant logo and the Apache feather logo are trademarks of The Apache Software Foundation. + br/ + i + | All other marks mentioned may be trademarks or registered trademarks of their respective owners. diff --git a/asciidoc-template/helpers.rb b/asciidoc-template/helpers.rb new file mode 100644 index 00000000..b11768b9 --- /dev/null +++ b/asciidoc-template/helpers.rb @@ -0,0 +1,168 @@ +# Add custom functions to this module that you want to use in your Slim +# templates. Within the template you must namespace the function +# (unless someone can show me how to include them in the evaluation context). +# You can change the namespace to whatever you want. + +require 'json' + +module IvyDocHelpers + + class Page + attr_accessor :id, :title, :url, :allChildIds, :children, :parent + + def initialize() + @id = "" + @title = "" + @url = "" + @allChildIds = [] + @children = [] + @parent = nil + end + + def link(printpage) + l = '' + if self.url + l += '' + else + l += self.title + end + return l + end + + def relativeRoot() + p = '' + (self.id.split("/").length-1).times do |e| + p += '../' + end + return p + end + + def breadCrumb() + b = '' + b += breadCrumbStep(self) + b += '' + return b + end + + def breadCrumbStep(page) + b = ' ' + if page.parent && page.parent.parent + b += breadCrumbStep(page.parent) + b += ' > ' + end + b += page.link(page) + return b + end + + def rootpage() + if self.parent + return self.parent.rootpage() + else + return self + end + end + + def menu() + return innermenu(rootpage()) + end + + def innermenu(page) + m = '\n" + return m + end + + end + + def self.page(basedir, docfile) + rootpage = loadPages(basedir) + pageId = docfile[basedir.length+1..docfile.rindex(/\./)-1] + p = findPage(rootpage, pageId) + if !p + p = Page.new + end + return p + end + + def self.loadPages(basedir) + rootpage = Page.new + toc = JSON.parse(IO.read(basedir + "/toc.json")) + toc['children'].each do |child| + rootpage.children << loadPage(basedir, rootpage, child, "") + end + return rootpage + end + + def self.loadPage(basedir, parent, node, path) + p = Page.new + p.title = node['title'] + p.parent = parent + if node.has_key?("importRoot") + p.id = path + child['importRoot'] + '/' + node['importNode'] + p.url = p.id + ".html" + toc = JSON.parse(IO.read(basedir + '/' + child['importRoot'] + "/toc.json")) + toc['children'].each do |child| + p.children << loadPage(basedir, p, child, path + child['importRoot'] + '/') + end + else + p.id = node['id'] + if !(node.has_key?("isAbstract")) + if node.has_key?("url") + p.url = node['url'] + else + p.url = path + node['id'] + ".html" + end + end + if node.has_key?("children") + node['children'].each do |child| + p.children << loadPage(basedir, p, child, path) + end + end + end + p.children.each { |cp| p.allChildIds += cp.allChildIds } + if p.id + p.allChildIds << p.id + end + return p + end + + def self.findPage(parent, pageId) + parent.children.each do |p| + if p.id == pageId + return p + end + if p.children.length > 0 + found = findPage(p, pageId) + if found + return found + end + end + end + return nil + end + +end diff --git a/build-doc.xml b/build-doc.xml new file mode 100644 index 00000000..e9316f98 --- /dev/null +++ b/build-doc.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/xooki2asciidoc/antlib.xml b/doc/xooki2asciidoc/antlib.xml new file mode 100644 index 00000000..8f4d2e2c --- /dev/null +++ b/doc/xooki2asciidoc/antlib.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/doc/xooki2asciidoc/xooki2asciidoc.js b/doc/xooki2asciidoc/xooki2asciidoc.js new file mode 100644 index 00000000..554924e5 --- /dev/null +++ b/doc/xooki2asciidoc/xooki2asciidoc.js @@ -0,0 +1,1569 @@ +/* + Copyright (c) 2006-2007, The Xooki project + http://xooki.sourceforge.net/ + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Some code is largely inspired by code found in the dojo toolkit, + see http://dojotoolkit.org/ for more information. +*/ + +/* +This script can be either embedded in a xooki page for in browser processing, or used in batch using rhino or java 6 javascript tool: +jrunscript path/to/xooki.js inputFileFromXookiSite.html [path/to/dir/to/put/generated/file] + +Be sure to be in the directory where the html input to process is when running this command. + */ +var batchMode = (typeof arguments != 'undefined'); + +var xooki = {}; +xooki.console = ""; // used for debugging purpose only, and only when the debug div is not yet created +xooki.config = {}; +xooki.c = xooki.config; + +function t(msg) { + // returns the internationalized version of the message, or the message if no translation is available + // t stands for translate +// FIXME +// if (typeof xooki.c == "object" +// && typeof xooki.c.messages == "object" +// && typeof xooki.c.messages[msg] == "string") { +// msg = xooki.c.messages[msg]; +// } + var arr = []; + for (var i=1; i'); + document.write(''); + }, + + evalURL: function( url, warnOnErrorUrl ) { + script = this.loadURL(url, warnOnErrorUrl); + if (script != null) { + try { + eval(script); + } catch (e) { + xooki.error(e, t("error while executing script from URL ${0}", url)); + } + } + }, + + action: function(action) { + // returns the url for an action on the same page + loc = batchMode?'':xooki.pageURL; + if (loc.indexOf("#") != -1) { + loc = loc.substring(0, loc.indexOf("#")); + } + return loc+"?action="+action; + } + + }; + +xooki.string = { + + substituteParams: function(/*string*/template, /* object - optional or ... */hash) { + // borrowed from dojo + // summary: + // Performs parameterized substitutions on a string. Throws an exception if any parameter is unmatched. + // + // description: + // For example, + // dojo.string.substituteParams("File '${0}' is not found in directory '${1}'.","foo.html","/temp"); + // returns + // "File 'foo.html' is not found in directory '/temp'." + // + // template: the original string template with ${values} to be replaced + // hash: name/value pairs (type object) to provide substitutions. Alternatively, substitutions may be + // included as an array + + var map; + if (typeof hash == "object" && hash.length) { // array + map = {}; + for (var i in hash) { + map[i+""] = hash[i]; + } + } else { + map = hash; + } + + return template.replace(/\$\{(\w+)\}/g, function(match, key){ + if(typeof(map[key]) != "undefined" && map[key] != null){ + return map[key]; + } + xooki.warn("Substitution not found: " + key); + return key; + }); // string + }, + + processTemplate: function(/*string*/template, /* object */hash) { + if (typeof template.process == "function") { + return template.process(hash); + } else { + return this.substituteParams(template, hash); + } + }, + + exceptionText: function(e, message) { + var s = e.description ? e.description : e.toString(); + return message ? message+":\n"+s : s; + }, + + findXmlSection: function(str, element, from) { + return this.findSection(str, new RegExp('<'+element+'(\\s*\\w+="[^\\"]*")*>'), new RegExp(''), from); + }, + + find: function(/*string*/str, /*string or regexp*/exp, /*number, optional*/from) { + // find an expression (string or regexp) in a string, from an optional index + // the object returned has two properties: + // begin: the index in str of the matching find + // end: the index in str of the end of the matching find + // returns null if no match is found + if (typeof from != "number") { + from = 0; + } + if (typeof exp == "string") { + var result = {}; + result.begin = str.indexOf(exp,from); + if (result.begin >= 0) { + result.end = result.begin + exp.length; + return result; + } + } else { + var m; + if (from > 0) { + // I haven't found any other way to start from the given index + m = exp.exec(str.substring(from)); + } else { + m = exp.exec(str); + } + if (m != null) { + var result = {}; + result.begin = m.index + from; + result.end = result.begin + m[0].length; + result.matcher = m; + return result; + } + } + return null; + }, + + findSection: function(/*string*/str, /*string or regexp*/open, /*string or regexp*/close, /*number, optional*/from) { + // finds a section delimited by open and close tokens in the given string + // the algorithm looks for matching open and close tokens + // the returned object has the following properties: + // outerStart: the index in str where the first open token was found + // innerStart: the index in str just after the found open token + // innerEnd: the index in str where the matching close token was found + // outerEnd: the index in str just after the matching close token + // children: an array of similar objects if nested sections where found + // if no section is found (no open token, an open token with no matching + // close token, or a close token before an open token), null is returned + // + // for instance if open=='(' and close==')' then the section will find + // a section delimited by the first found open parenthesis and the matching + // close parentethis, taking into account other opening parentethis + // examples: + // findSection("a(test)b", "(", ")") == {outerStart: 1, innerStart:2, innerEnd:6, outerEnd:7, children:[]} + // findSection("a(te(s)(t))b", "(", ")") == {outerStart: 1, innerStart:2, innerEnd:10, outerEnd:11, + // children:[ + // {outerStart: 4, innerStart:5, innerEnd:6, outerEnd:7, children:[]}, + // {outerStart: 7, innerStart:8, innerEnd:9, outerEnd:10, children:[]} + // ]} + + var openResult = this.find(str, open, from); + if (openResult == null) { + print('no open\n'); + return null; + } + if (openResult.end <= openResult.begin) { + print('empty open\n'); + // empty match are not allowed + return null; + } + var closeResult = this.find(str, close, openResult.end); + if (closeResult == null) { + print('no close\n'); + return null; + } + if (closeResult.end <= closeResult.begin) { + print('empty close\n'); + // empty match are not allowed + return null; + } + + //print('matched !' + str.substring(openResult.begin, closeResult.end) + '\n'); + + var children = []; + var child = this.findSection(str, open, close, openResult.end); + while (child != null) { + if (child.outerStart > closeResult.begin) { + break; + } + if (child.outerEnd > closeResult.begin) { + closeResult = this.find(str, close, child.outerEnd); + if (closeResult == null) { + // unmatched open token + return null; + } + } + children.push(child); + child = this.findSection(str, open, close, child.outerEnd); + } + + //print('found !' + str.substring(openResult.begin, closeResult.end) + '\n'); + + return { + outerStart: openResult.begin, + innerStart: openResult.end, + matcherStart: openResult.matcher, + innerEnd: closeResult.begin, + outerEnd: closeResult.end, + matcherEnd: closeResult.matcher, + children: children + }; + }, + + mul: function (/*string*/ s, /*int*/ n) { + r = ''; + for (var i=0; i < n; i++) { + r += s; + } + return r; + } +}; + +xooki.json = { + evalJson: function (str) { + try { + return eval("("+str+")"); + } catch (e) { + return null; + } + }, + + loadURL: function (url) { + return this.evalJson(xooki.url.loadURL(url)); + } + }; + +// Displays an alert of an exception description with optional message +xooki.warn = function(e, message) { + xooki.display(xooki.string.exceptionText(e, message), "#eecccc"); +} + +// Displays an alert of an exception description with optional message +xooki.error = function(e, message) { + xooki.display(xooki.string.exceptionText(e, message), "#ffdddd"); +} + +xooki.info = function(message) { + xooki.display(message, "#ddddff"); +} + +xooki.display = function(message, background) { + var messages = document.getElementById('xooki-messages'); + if (messages) { + messages.innerHTML = '
'+message+'
'; + messages.style.background = background; + messages.style.display = "inline"; + } else { + alert(message); + } +} + +xooki.debug = function(message) { + var console = typeof document == 'undefined' ? false : document.getElementById('xooki-console'); + if (console) { + console.value += message + "\n"; + } else { + xooki.console += message + "\n"; + } +} + +xooki.debugShowDetail = function (message) { + var detail = typeof document == 'undefined' ? false : document.getElementById('xooki-debug-detail'); + if (detail) { + detail.value=message; + } else { + alert(message); + } +} + + +xooki.html = { + hide: function(divid) { + document.getElementById(divid).style.display = 'none'; + }, + + show: function (divid) { + document.getElementById(divid).style.display = ''; + }, + + pageLink: function(page) { + if (page.isAbstract) { + return page.title; + } else { + return '
'+page.title+''; + } + }, + + // insert the given header in the html head + // can be used only when the browser is still in the head ! + addHeader: function(/* string */ head) { + document.write(head); + }, + + setBody: function( /* string */ body) { + document.body.innerHTML = body; + } +}; + +xooki.component = { + childrenList: function () { + if (xooki.page.children.length > 0) { + childrenList = '\n"; + return childrenList; + } else { + return ""; + } + }, + + menu: function () { + var menu = '