Skip to content

Commit

Permalink
Started to implement the html manual similar to Red Shoes --manual-ht…
Browse files Browse the repository at this point in the history
…ml option. Added the *to_html* link on built-in manual sidebar. Finished to make the page formatting and sidebar only so far. Contents will come later. Added some licence notes to README.md and LICENSE files.
  • Loading branch information
ashbb committed Mar 21, 2011
1 parent 8bc4d16 commit c467837
Show file tree
Hide file tree
Showing 7 changed files with 466 additions and 1 deletion.
4 changes: 4 additions & 0 deletions LICENSE
Expand Up @@ -3,6 +3,7 @@ Copyright (c) 2010-2011 ashbb
Except:

* hh/static/(all).png (c) 2008 why the lucky stiff
* lib/ext/hpricot/(all) (c) 2008 why the lucky stiff
* lib/ext/projector/(all).rb (c) 2010 MIZUTANI Tociyuki
* samples/akatsukiface.png (c) 2010 MIZUTANI Tociyuki
* samples/class-book.yaml (c) 2008 why the lucky stiff
Expand All @@ -13,6 +14,9 @@ Except:
* static/Lacuna.ttf (c) 2003 Glashaus, designed by Peter Hoffman
* static/gshoes-icon.png (c) 2010 Zachary Scott
* static/gshoes-heading-icon.png (c) 2010 Zachary Scott
* static/code_highlighter.js (c) 2005 Dan Webb
* static/code_highlighter_ruby.js (c) 2008 why the lucky stiff
* static/manual.css (c) 2008 why the lucky stiff

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -97,6 +97,7 @@ Copyright (c) 2010-2011 ashbb
Except:

- hh/static/(all).png (c) 2008 why the lucky stiff
- lib/ext/hpricot/(all) (c) 2008 why the lucky stiff
- lib/ext/projector/(all).rb (c) 2010 MIZUTANI Tociyuki
- samples/akatsukiface.png (c) 2010 MIZUTANI Tociyuki
- samples/class-book.yaml (c) 2008 why the lucky stiff
Expand All @@ -107,6 +108,9 @@ Except:
- static/Lacuna.ttf (c) 2003 Glashaus, designed by Peter Hoffman
- static/gshoes-icon.png (c) 2010 Zachary Scott
- static/gshoes-heading-icon.png (c) 2010 Zachary Scott
- static/code_highlighter.js (c) 2005 Dan Webb
- static/code_highlighter_ruby.js (c) 2008 why the lucky stiff
- static/manual.css (c) 2008 why the lucky stiff

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.192.0
0.193.0
76 changes: 76 additions & 0 deletions lib/shoes/help.rb
Expand Up @@ -2,6 +2,8 @@ class Manual < Shoes
url '/', :index
url '/manual/(\d+)', :index

include Hpricot

def index pnum = 0
font LANG == 'ja' ? 'MS UI Gothic' : 'Arial'
style Link, underline: false, weight: 'bold'
Expand All @@ -13,6 +15,7 @@ def index pnum = 0

def get_title_and_desc pnum
chapter, section = PNUMS[pnum]
return nil unless chapter
if section
[pnum, DOCS[chapter][1][:sections][section][1][:title],
DOCS[chapter][1][:sections][section][1][:description],
Expand Down Expand Up @@ -45,6 +48,7 @@ def manual pnum, docs_title, docs_description, docs_methods
stack{para NL * 4}
flow width: 0.2, margin_left: 10 do
para *TOC
para link(fg 'to_html', darkmagenta){html_manual}
end

flow width: 0.8, margin: [10, 0, 20, 0] do
Expand Down Expand Up @@ -203,6 +207,78 @@ def self.mk_page_numbers docs
pnum
end

def html_manual
dir = ask_save_folder
return unless dir
FileUtils.mkdir_p File.join(dir, 'static')
%w[gshoes-icon.png shoes-manual-apps.png manual.css code_highlighter.js code_highlighter_ruby.js].
each{|x| FileUtils.cp "#{DIR}/../static/#{x}", "#{dir}/static"}
Dir[File.join DIR, '../static/man-*.png'].each{|x| FileUtils.cp x, "#{dir}/static"}

TOC_LIST.length.times do |n|
num, title, desc = get_title_and_desc n
open File.join(dir, "#{TOC_LIST[n][0]}.html"), 'w' do |f|
f.puts mk_html(title, desc, TOC_LIST[n+1], get_title_and_desc(n+1), mk_sidebar_list(num))
end
end
end

def mk_html title, desc, next_file, next_title, menu
Hpricot do
xhtml_transitional do
head do
meta :"http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8"
title "The Green Shoes Manual // #{title}"
script type: "text/javascript", src: "static/code_highlighter.js"
script type: "text/javascript", src: "static/code_highlighter_ruby.js"
style type: "text/css" do
text "@import 'static/manual.css';"
end
end
body do
div.main! do
div.manual! do
h2 "The Green Shoes Manual #{VERSION}"
h1 title

p "<h4>test test test</h4>"

p.next{text "Next: "; a next_title[1], href: "#{next_file[0]}.html"} if next_title
end
div.sidebar do
img src: "static/gshoes-icon.png"
ul do
li{a.prime "HELP", href: "./"}
menu.each do |m|
li do
unless m.is_a?(Array)
a m, href: "#{m}.html"
else
ul.sub do
m.each do |sm|
li{a sm, href: "#{sm}.html"}
end
end
end
end
end
end
end
end
end
end
end.to_html
end

def mk_sidebar_list num
toc = []
[0..3, 4..9, 10..16, 17..32, 33..35].each do |r|
toc.push TOC_LIST[r.first][0]
toc.push(TOC_LIST[r.first+1..r.last].to_a.map &:first) if r.include?(num)
end
toc
end

IMAGE_RE = /\!(\{([^}\n]+)\})?([^!\n]+\.\w+)\!/
CODE_RE = /\{{3}(?:\s*\#![^\n]+)?(.+?)\}{3}/m
NL = "\n"
Expand Down
188 changes: 188 additions & 0 deletions static/code_highlighter.js
@@ -0,0 +1,188 @@
/* Unobtrustive Code Highlighter By Dan Webb 11/2005
Version: 0.4
Usage:
Add a script tag for this script and any stylesets you need to use
to the page in question, add correct class names to CODE elements,
define CSS styles for elements. That's it!
Known to work on:
IE 5.5+ PC
Firefox/Mozilla PC/Mac
Opera 7.23 + PC
Safari 2
Known to degrade gracefully on:
IE5.0 PC
Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors
in older browsers use expressions that use lookahead in string format when defining stylesets.
This script is inspired by star-light by entirely cunning Dean Edwards
http://dean.edwards.name/star-light/.
*/

// replace callback support for safari.
if ("a".replace(/a/, function() {return "b"}) != "b") (function(){
var default_replace = String.prototype.replace;
String.prototype.replace = function(search,replace){
// replace is not function
if(typeof replace != "function"){
return default_replace.apply(this,arguments)
}
var str = "" + this;
var callback = replace;
// search string is not RegExp
if(!(search instanceof RegExp)){
var idx = str.indexOf(search);
return (
idx == -1 ? str :
default_replace.apply(str,[search,callback(search, idx, str)])
)
}
var reg = search;
var result = [];
var lastidx = reg.lastIndex;
var re;
while((re = reg.exec(str)) != null){
var idx = re.index;
var args = re.concat(idx, str);
result.push(
str.slice(lastidx,idx),
callback.apply(null,args).toString()
);
if(!reg.global){
lastidx += RegExp.lastMatch.length;
break
}else{
lastidx = reg.lastIndex;
}
}
result.push(str.slice(lastidx));
return result.join("")
}
})();

var CodeHighlighter = { styleSets : new Array };

CodeHighlighter.addStyle = function(name, rules) {
// using push test to disallow older browsers from adding styleSets
if ([].push) this.styleSets.push({
name : name,
rules : rules,
ignoreCase : arguments[2] || false
})

function setEvent() {
// set highlighter to run on load (use LowPro if present)
if (typeof Event != 'undefined' && typeof Event.onReady == 'function')
return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter));

var old = window.onload;

if (typeof window.onload != 'function') {
window.onload = function() { CodeHighlighter.init() };
} else {
window.onload = function() {
old();
CodeHighlighter.init();
}
}
}

// only set the event when the first style is added
if (this.styleSets.length==1) setEvent();
}

CodeHighlighter.init = function() {
if (!document.getElementsByTagName) return;
if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function
// throw out older browsers

var codeEls = document.getElementsByTagName("CODE");
// collect array of all pre elements
codeEls.filter = function(f) {
var a = new Array;
for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i];
return a;
}

var rules = new Array;
rules.toString = function() {
// joins regexes into one big parallel regex
var exps = new Array;
for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
return exps.join("|");
}

function addRule(className, rule) {
// add a replace rule
var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
// converts regex rules to strings and chops of the slashes
rules.push({
className : className,
exp : "(" + exp + ")",
length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule
replacement : rule.replacement || null
});
}

function parse(text, ignoreCase) {
// main text parsing and replacement
return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
var i = 0, j = 1, rule;
while (rule = rules[i++]) {
if (arguments[j]) {
// if no custom replacement defined do the simple replacement
if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
else {
// replace $0 with the className then do normal replaces
var str = rule.replacement.replace("$0", rule.className);
for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
return str;
}
} else j+= rule.length;
}
});
}

function highlightCode(styleSet) {
// clear rules array
var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)");
rules.length = 0;

// get stylable elements by filtering out all code elements without the correct className
var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.className) });

// add style rules to parser
for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);


// replace for all elements
for (var i = 0; i < stylableEls.length; i++) {
// EVIL hack to fix IE whitespace badness if it's inside a <pre>
if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
stylableEls[i] = stylableEls[i].parentNode;

parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
});
parsed = parsed.replace(/\n( *)/g, function() {
var spaces = "";
for (var i = 0; i < arguments[1].length; i++) spaces+= "&nbsp;";
return "\n" + spaces;
});
parsed = parsed.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");

} else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);

stylableEls[i].innerHTML = parsed;
}
}

// run highlighter on all stylesets
for (var i=0; i < this.styleSets.length; i++) {
highlightCode(this.styleSets[i]);
}
}
26 changes: 26 additions & 0 deletions static/code_highlighter_ruby.js
@@ -0,0 +1,26 @@
CodeHighlighter.addStyle("rb",{
comment : {
exp : /#[^\n]+/
},
brackets : {
exp : /\(|\)|\{|\}/
},
string : {
exp : /'[^']*'|"[^"]*"/
},
keywords : {
exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|raise)\b/
},
constant : {
exp : /\b([A-Z]\w+)\b/
},
ivar : {
exp : /([^@])(@{1,2}\w+)\b/
},
ns : {
exp : /(:{2,})/
},
symbol : {
exp : /(:[A-Za-z0-9_!?]+)/
}
});

0 comments on commit c467837

Please sign in to comment.