diff --git a/ebook.rb b/ebook.rb index ba07ae5..afe3930 100644 --- a/ebook.rb +++ b/ebook.rb @@ -1,27 +1,89 @@ -Shoes.app { + +require 'yaml' +Shoes.app :width => 800 do + yaml_fl = ARGV[1] + cfg = {} + if yaml_fl + cfg = YAML.load_file(yaml_fl) + else # debugging + cfg['doc_home'] = "/home/ccoupe/Projects/shoes3.wiki/chapter-8" + cfg['files'] = ["Plot-Widget.md"] + #@doc = "/home/ccoupe/Projects/shoes3.wiki/chapter-8/Plot-Widget.md" + end stack do flow do button "init ebook" do # create a yaml and .ebook dir dir = ask_open_folder @ebook_dir_el.text = dir; + cfg = {} + cfg['doc_home'] = dir + cfg['files'] = [] + cfg['chapters'] = [] if confirm "make .ebook directory at #{dir}" - Dir.mkdir('.ebook') unless Dir.exist?("#{curdir}/.ebook") - Dir.mkdir(".ebook/images") unless Dir.exist? "#{curdir}/.ebook/images" - # create a bare yaml. + Dir.mkdir("#{dir}/.ebook") unless Dir.exist?("#{dir}/.ebook") + Dir.mkdir("#{dir}/.ebook/images") unless Dir.exist? "#{dir}/.ebook/images" + Dir.entries(dir).each do |e| + next if e[0] == '.' + puts e + if File.directory?("#{dir}/#{e}") + cfg['chapters'] << e + end + end + Dir.chdir(cfg['doc_home']) do |d| + Dir.glob("**/*.md") do |f| + cfg['files'] << f unless File.basename(f) == "_Sidebar.md" + end + end + File.open("#{dir}/.ebook/ebook.yaml", 'w') do |f| + YAML.dump(cfg, f) + end end end - button "load" do - # load the yaml file - yf = ask_open_file + button "preprocess" do + require 'kd-pre' + @image_hash = {} + @header_hash = {} + @link_hash = {} + Dir.chdir(cfg["doc_home"]) do + cfg['files'].each do |relpath| + d = File.dirname(relpath) + f = File.basename(relpath) + Dir.chdir(d) do + # returns an array, not an object - + pre_doc = Kramdown::Document.new(File.read(f), {img_hash: @image_hash, + hdr_hash: @header_hash, lnk_hash: @link_hash}).to_preprocess + end + Dir.chdir(".ebook/images") do + @image_hash.each do |k, v| + if !File.exists?("#{d}/#{v}") + download k, save: "#{d}/#{v}" + @err_box.append("downloaded #{d}/#{v} <- #{k}\n") + break unless confirm "Continue:" + end + end + end + end + end + puts "images: #{@image_hash}" + puts "headers: #{@header_hash}" + puts "links: #{@link_hash}" end + button "render" do - # parse the yaml - require 'ebook-kd' - doc = Kramdown::Document.new(File.read("/home/ccoupe/Projects/shoes3.wiki/chapter-8/Plot-Widget.md")).to_shoes - rendering(doc) + require 'kd-render' + cfg['files'].each do |relpath| + + render_doc = Kramdown::Document.new(File.read(@doc), + { :syntax_highlighter => "rouge", + :syntax_highlighter_opts => { css_class: false, line_numbers: false, inline_theme: "github" } + } + ).to_shoes + rendering(render_doc) + end end end @ebook_dir_el = edit_line width: 400 + @err_box = edit_box heigth: 300, width: 780 end -} +end diff --git a/kd-pre.rb b/kd-pre.rb new file mode 100644 index 0000000..999f18a --- /dev/null +++ b/kd-pre.rb @@ -0,0 +1,143 @@ +# -*- encoding: utf-8 -*- +# Preprocess for img and links + +require("kramdown") + +module Kramdown + module Converter + class Preprocess < Base + + + def initialize(root, options) + #puts "pre_proc init opts: #{options.inspect}" + if options + @image_hash = options[:img_hash] + @header_hash = options[:hdr_hash] + @link_hash = options[:lnk_hash] + #puts "setting up @image_hash #{@image_hash.inspect}" + end + super + end + + DISPATCHER = Hash.new {|h,k| h[k] = "convert_#{k}"} + + def convert(el) + send(DISPATCHER[el.type], el) + end + + def convert_root(el) + results = [] + el.children.each do |inner_el| + results << send(DISPATCHER[inner_el.type], inner_el) + end + results + end + + def convert_blank(el) + #%{para("\n")} + end + + def convert_text(el) + #%{para("#{el.value}", :margin_left => 0, :margin_right => 0)} + end + + def convert_header(el) + #puts "hdr: #{el.options[:raw_text]} #{el.options[:level]}" + @header_hash[el.options[:raw_text]] = el.options[:level] + end + + def convert_p(el) + results = [] + el.children.each do |inner_el| + results << send(DISPATCHER[inner_el.type], inner_el) + end + #%[flow(:margin_left => 6, :margin_right => gutter) { #{results.join(";")} }] + end + + def convert_ul(el) + results = [] + el.children.each do |inner_el| + results << send(DISPATCHER[inner_el.type], inner_el) + end + #results + end + + def convert_li(el) + results = [] + el.children.each do |inner_el| + results << %[flow(:margin_left => 30) { fill black; oval -10, 10, 6; #{send(DISPATCHER[inner_el.type], inner_el)} }] + end + #results + end + ##alias :convert_ol :convert_ul + ##alias :convert_dl :convert_ul + + def convert_smart_quote(el) + #%{para("'", :margin_left => 0, :margin_right => 0)} + end + + def convert_a(el) + puts "anchor: #{el.inspect}" + results = [] + el.children.each do |inner_el| + results << inner_el.value if inner_el.type.eql?(:text) + end + #%[para(link("#{results.join}") { open_url("#{el.attr['href']}") }, :margin_left => 0, :margin_right => 0)] + end + + # TODO: syntax highlight not working (no errors - just doesn't return anything) + def convert_codespan(el) + #puts el.type + ##puts highlight_code(el.value, el.attr['class'], :span) + ##h = ::Kramdown::Converter.syntax_highlighter(@options[:syntax_highlighter]) + ##puts h.call(self, el.value, el.attr['class'], :span) + #puts syntax_highlighter(self, el.value, el.attr['class'], :span) + end + + def convert_codeblock(el) + #puts el.type + end + + def convert_strong(el) + #%[para "STRONG"] + end + + def convert_img(el) + url = el.attr['src'] + ext = File.extname(url); + hsh = @image_hash + #puts "#{el.attr['src']} -> #{el.attr['alt']}#{ext} for #{hsh}" + hsh[url] = "#{el.attr['alt']}#{ext}" + end + + def convert_typographic_sym(el) + #%[para"??"] + end + + def convert_em(el) + #%[para '-'] + end + + def syntax_highlighter(converter, text, lang, type) + opts = converter.options[:syntax_highlighter_opts].dup + lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text) + return nil unless lexer + + opts[:wrap] = false if type == :span + + formatter = ::Rouge::Formatters::ShoesFormatter.new(opts) + formatter.format(lexer.lex(text)) + end + # TODO: end + end + end +end + +def pre_process(e) + e.kind_of?(Array) ? (e.each { |n| pre_process(n) }) : (eval e unless e.nil?) + return +end + + + + diff --git a/kd-render.rb b/kd-render.rb new file mode 100644 index 0000000..9bfb472 --- /dev/null +++ b/kd-render.rb @@ -0,0 +1,167 @@ +# https://github.com/Shoes3/shoes3/wiki +# http://www.w3schools.com/tags/tag_li.asp +# http://stackoverflow.com/questions/4900167/override-module-method-from-another-module + +require("rouge") +require("kramdown") +require("pp") + +def open_url(url) + if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ + system("start #{url}") + elsif RbConfig::CONFIG['host_os'] =~ /darwin/ + system("open #{url}") + elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/ + system("xdg-open #{url}") + end +end + +module Rouge + module Formatters + class ShoesFormatter < Formatter + tag 'shoes' + + def initialize(options) + @inline_theme = options.fetch(:inline_theme, nil) + @inline_theme = Theme.find(@inline_theme).new if @inline_theme.is_a? String + puts @inline_theme.render + end + + def stream(tokens, &b) + tokens.each do |tok, val| + yield "\t#{@inline_theme.style_for(tok).rendered_rules.to_a.join(';')}\n" + yield "#{tok} #{val.inspect}\n" + end + end + end + end +end + +module Kramdown + module Converter + class Shoes < Base + ##include ShoesRouge + def initialize(root, options) + super + ## options[:syntax_highlighter] = "rouge" + #puts options + end + + DISPATCHER = Hash.new {|h,k| h[k] = "convert_#{k}"} + + def convert(el) + send(DISPATCHER[el.type], el) + end + + def convert_root(el) + results = [] + el.children.each do |inner_el| + results << send(DISPATCHER[inner_el.type], inner_el) + end + results + end + + def convert_blank(el) + %{para("\n")} + end + + def convert_text(el) + %{para("#{el.value}", :margin_left => 0, :margin_right => 0)} + end + + def convert_header(el) + %{para(strong("#{el.options[:raw_text]}\n"), :margin_left => 6, :margin_right => gutter)} + end + + def convert_p(el) + results = [] + el.children.each do |inner_el| + results << send(DISPATCHER[inner_el.type], inner_el) + end + %[flow(:margin_left => 6, :margin_right => gutter) { #{results.join(";")} }] + end + + def convert_ul(el) + results = [] + el.children.each do |inner_el| + results << send(DISPATCHER[inner_el.type], inner_el) + end + results + end + + def convert_li(el) + results = [] + el.children.each do |inner_el| + results << %[flow(:margin_left => 30) { fill black; oval -10, 10, 6; #{send(DISPATCHER[inner_el.type], inner_el)} }] + end + results + end + ##alias :convert_ol :convert_ul + ##alias :convert_dl :convert_ul + + def convert_smart_quote(el) + %{para("'", :margin_left => 0, :margin_right => 0)} + end + + def convert_a(el) + results = [] + el.children.each do |inner_el| + results << inner_el.value if inner_el.type.eql?(:text) + ##send(DISPATCHER[inner_el.type], inner_el) + end + %[para(link("#{results.join}") { open_url("#{el.attr['href']}") }, :margin_left => 0, :margin_right => 0)] + end + + # TODO: syntax highlight not working (no errors - just doesn't return anything) + def convert_codespan(el) + puts el + ##puts highlight_code(el.value, el.attr['class'], :span) + ##h = ::Kramdown::Converter.syntax_highlighter(@options[:syntax_highlighter]) + ##puts h.call(self, el.value, el.attr['class'], :span) + puts syntax_highlighter(self, el.value, el.attr['class'], :span) + end + + def convert_codeblock(el) + puts el.type + end + + # TODO: + def convert_strong(el) + %[para "STRONG"] + end + + def convert_img(el) + puts el.attr['src'] + #%[image "#{el.attr['src']}"] # crashes shoes + url = el.attr['src'] + ext = File.extname(url); + %[para "IMAGE_HERE: #{el.attr['alt']}#{ext}"] + end + + def convert_typographic_sym(el) + %[para"??"] + end + + def convert_em(el) + %[para '-'] + end + + def syntax_highlighter(converter, text, lang, type) + opts = converter.options[:syntax_highlighter_opts].dup + lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text) + return nil unless lexer + + opts[:wrap] = false if type == :span + + formatter = ::Rouge::Formatters::ShoesFormatter.new(opts) + formatter.format(lexer.lex(text)) + end + # TODO: end + end + end +end + +def rendering(e) + e.kind_of?(Array) ? (e.each { |n| rendering(n) }) : (eval e unless e.nil?) +end + diff --git a/kramdown001.rb b/kramdown001.rb index 0a06692..0cedb3d 100644 --- a/kramdown001.rb +++ b/kramdown001.rb @@ -145,6 +145,6 @@ def rendering(e) Shoes.app { doc = Kramdown::Document.new(File.read("manual-en.txt"), { :syntax_highlighter => "rouge", :syntax_highlighter_opts => { css_class: false, line_numbers: false, inline_theme: "github" } }).to_shoes - #info doc.inspect + info doc.inspect rendering(doc) -} \ No newline at end of file +} diff --git a/manual-en.txt b/manual-en.txt new file mode 100644 index 0000000..9a3967d --- /dev/null +++ b/manual-en.txt @@ -0,0 +1,53 @@ +Shoes +===== + +## Welcome to the Shoes 3.2 wiki + +This wiki contains information that's important to anyone who wants learn more about Shoes. There are things that are not in the built-in manual you might like to know about. + +## Beginners + +Just go to the [Shoes website](http://shoesrb.com/) and download Shoes. You can also find the [Shoes manual](http://shoesrb.com/manual/Hello.html) and a book, [Nobody Knows Shoes](http://cloud.github.com/downloads/shoes/shoes/nks.pdf). That'll get you started building applications with Shoes. + +Have a question? - You should join the Shoes mailing list by sending an email to shoes@librelist.com and ask. That's also a good place to discuss bugs if you don't want to get a github account. + +Need a Beginners Guide to Ruby? - I recommend [Programming Ruby, The Pragmatic Programmers Guide](https://7chan.org/pr/src/ruby.pdf) aka the PickAxe book. It doesn't cover Shoes - it's for Ruby. I suggest buying the hardcover book - my copy is always open to some reference page or another. + +## Intermediate Level +Perhaps you already know everything about Ruby (congrats!) or you're a command line maven and Shoes doesn't do what you want. Or maybe you're curious to read more. Shoes is all about learning and exploring. If you see something below that you don't understand, just file it away for further cogitating. Reading is not harmful. Acting without knowledge can be harmful but it's trait I live with. + +Actually, Shoes might do what you want if someone would write it down so you can find it so you can experiment and learn more. You should join the mailing list and get a github account and file bug reports (or answer them) at the [Shoes issue tracker](http://github.com/shoes3/shoes/issues) + +* Dude, where's the secret files? [[Where are files kept]] +* Shoes command line [[Command-line]] +* Shoes and Ruby Gems [[Gems]] +* Cobbler [[Cobbler]] +* Packaging [[Packaging]] +* Development tools [[Developers Tools]] +* Shoes is not Ruby [[Shoes is not Ruby]] + +## I want to dig deep into how Shoes works and fix some bugs. 'C' doesn't scare me! Makefiles and Rakefile? I can handle that! + +Awesome! We'd love to have you help out with Shoes. Here's some resources you're gonna need: (they may be out of date, but you can handle that). + +* Development tools [[Developers Tools]] +* [[Building Shoes]] Put on your fire hose gear. +* [[Creating Icons]] Icons for packaging. +* The [Shoes issue tracker](http://github.com/shoes3/shoes/issues), where bug reports go. +* You should join the Shoes mailing list by sending an email to shoes@librelist.com +* [[The Future of Shoes]] +* [[A Developer's Tour Through Shoes]] A bit outdated. +* [[A Developer's Tour Through The Magic Packager]] Even more outdated. + +## I hate 'C' and Makefiles. I like jRuby! + +OK. Fine. You want to follow/join the [Shoes 4 project](https://github.com/shoes/shoes4) + +## Coding with Style + +` + ary = ['potion', 'swords', 'shields'] + ary.each do |item| + puts item + end +`{:.ruby} diff --git a/manual-markdown.txt b/manual-markdown.txt new file mode 100644 index 0000000..2ed6fa4 --- /dev/null +++ b/manual-markdown.txt @@ -0,0 +1 @@ + #, :location => 1, :abbrev_defs => { } } [ 1, :raw_text => "Shoes", :location => 1 } [ 1 }>]>, , 2, :raw_text => "Welcome to the Shoes 3.2 wiki", :location => 4 } [ 4 }>]>, , 6 } [ 6 }>, 6 }>, 6 }>]>, , 2, :raw_text => "Beginners", :location => 8 } [ 8 }>]>, , 10 } [ 10 }>, "http://shoesrb.com/" } { :location => 10 } [ 10 }>]>, 10 }>, "http://shoesrb.com/manual/Hello.html" } { :location => 10 } [ 10 }>]>, 10 }>, "http://cloud.github.com/downloads/shoes/shoes/nks.pdf" } { :location => 10 } [ 10 }>]>, 10 }>, 10 }>, 10 }>]>, , 12 } [ 12 }>, 12 }>, 12 }>, 12 }>, 12 }>]>, , 14 } [ 14 }>, "https://7chan.org/pr/src/ruby.pdf" } { :location => 14 } [ 14 }>]>, 14 }>, 14 }>, 14 }>, 14 }>, 14 }>]>, , 2, :raw_text => "Intermediate Level", :location => 16 } [ 16 }>]>, 17 } [ 17 }>, 17 }>, 17 }>, 17 }>, 17 }>, 17 }>, 17 }>, 17 }>, 17 }>, 17 }>, 17 }>]>, , 19 } [ 19 }>, "http://github.com/shoes3/shoes/issues" } { :location => 19 } [ 19 }>]>]>, , 21 } [ 21 } [ 21, :transparent => true } [ 21 }>, 21 }>, 21 }>]>]>, 22 } [ 22, :transparent => true } [ 22 }>]>]>, 23 } [ 23, :transparent => true } [ 23 }>]>]>, 24 } [ 24, :transparent => true } [ 24 }>]>]>, 25 } [ 25, :transparent => true } [ 25 }>]>]>, 26 } [ 26, :transparent => true } [ 26 }>]>]>, 27 } [ 27, :transparent => true } [ 27 }>]>]>]>, , 2, :raw_text => "I want to dig deep into how Shoes works and fix some bugs. 'C' doesn't scare me! Makefiles and Rakefile? I can handle that!", :location => 29 } [ 29 }>, 29 }>, 29 }>, 29 }>, 29 }>, 29 }>, 29 }>]>, , 31 } [ 31 }>, 31 }>, 31 }>, 31 }>, 31 }>, 31 }>, 31 }>]>, , 33 } [ 33 } [ 33, :transparent => true } [ 33 }>]>]>, 34 } [ 34, :transparent => true } [ 34 }>]>]>, 35 } [ 35, :transparent => true } [ 35 }>]>]>, 36 } [ 36, :transparent => true } [ 36 }>, "http://github.com/shoes3/shoes/issues" } { :location => 36 } [ 36 }>]>, 36 }>]>]>, 37 } [ 37, :transparent => true } [ 37 }>]>]>, 38 } [ 38, :transparent => true } [ 38 }>]>]>, 39 } [ 39, :transparent => true } [ 39 }>, 39 }>, 39 }>]>]>, 40 } [ 40, :transparent => true } [ 40 }>, 40 }>, 40 }>]>]>]>, , 2, :raw_text => "I hate 'C' and Makefiles. I like jRuby!", :location => 42 } [ 42 }>, 42 }>, 42 }>, 42 }>, 42 }>]>, , 44 } [ 44 }>, "https://github.com/shoes/shoes4" } { :location => 44 } [ 44 }>]>]>, ]>