Skip to content

Commit

Permalink
for #5 - can auto create the TOC in ebook-builder
Browse files Browse the repository at this point in the history
* can also re-order TOC from the gui (in case you don't have the
  github navigation documents.)
* still need ability to  manually modify an auto created TOC.
  and detect md files not in the menus.
* Should be good enough to start working on rendering.
  • Loading branch information
Cecil committed Dec 21, 2016
1 parent bdef3ea commit 6b2ac91
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 24 deletions.
104 changes: 81 additions & 23 deletions ebook-builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,24 @@

button "2 - preprocess" do
require 'kd-pre'
require 'kd-toc'
@panel.clear do
para "This phase does a deeper dive into your .md documents and downloads any ",
"images from website that you have not downloaded before. It is safe to 'download' ",
"images from website that you have not downloaded before. It is safe to 'Proceed' ",
"as many times as you like. Downloads will be shown below. 'Save' when ready to move on."
flow do
button "download" do
button "Proceed" do
@image_dirs = []
@header_hash = {}
@link_hash = {}
@menu_list = []
Dir.chdir(cfg["doc_home"]) do
cfg['sections'].keys.each do |section|
puts "using #{section}"
#puts "using #{section}"
#puts " #{cfg['sections'][section]}"
#puts " #{cfg['sections'][section][:files]}"
@image_hash = {}
@header_hash = {}
cfg['sections'][section][:files].each do |fname|
relpath = "#{cfg['sections'][section][:dir]}/#{fname}"
#puts "In dir #{relpath}"
Expand All @@ -143,37 +145,93 @@
end
Dir.chdir(".ebook/images") do
here = Dir.getwd
@image_hash.each do |k, v|
next if File.exists?("#{here}/#{d}/#{v}")
if confirm "Download to #{here}/#{d}/#{v}"
Dir.mkdir(d) if !Dir.exists?(d)
download k, save: "#{d}/#{v}"
@err_box.append("downloaded #{d}/#{v} <- #{k}\n")
# Grr
if cfg['nested']
@image_hash.each do |k, v|
next if File.exists?("#{here}/#{d}/#{v}")
if confirm "Download to #{here}/#{d}/#{v}"
Dir.mkdir(d) if !Dir.exists?(d)
download k, save: "#{d}/#{v}"
@err_box.append("downloaded #{d}/#{v} <- #{k}\n")
end
end
else
@image_hash.each do |k, v|
next if File.exists?("#{here}/#{v}")
if confirm "Download to #{here}/#{v}"
download k, save: "#{here}/#{v}"
@err_box.append("downloaded #{here}/#{v} <- #{k}\n")
end
end
end
end
end
foo = cfg['sections'][section]['images'] = @image_hash
#puts "images: #{foo.inspect}"
foo = cfg['sections'][section]['headers'] = @header_hash
end

# Process the toc/menu documents if available and github nested
if cfg['toc']['root'] && cfg['nested'] == true
@menu_list = []
Dir.chdir(cfg['doc_home']) do |p|
f = "#{p}/#{cfg['toc']['root']}"
puts "process toc #{f}"
pre_toc = Kramdown::Document.new(File.read(f, encoding: "UTF-8"),
{ menu_list: @menu_list, input: cfg['input_format']
}).to_menuparse
#puts "first level #{@menu_list}"
# Getting tricksy and clumsy. Stumble or Dance?
cfg['toc']['section_order'] = []
cfg['toc']['files'] = []
@menu_list.each do |md|
cfg['sections'].each do |sect_k, sect_v|
sect_files = cfg['sections'][sect_k][:files]
pos = sect_files.find_index(md)
if pos
puts "Found #{md} in #{sect_k}"
cfg['toc']['section_order'] << sect_k
cfg['toc']['files'] << md
sect_files.delete_at(pos)
end
end
end
cfg['toc']['section_order'].each_index do |i|
d = cfg['toc']['section_order'][i]
sect = cfg['sections'][d]
f = cfg['toc']['files'][i]
@menu_list = []
@err_box.append "toc process #{d}/#{f}\n"
pre_toc = Kramdown::Document.new(File.read("#{d}/#{f}", encoding: "UTF-8"),
{ menu_list: @menu_list, input: cfg['input_format']
}).to_menuparse
cfg['sections'][d]['display_order'] = []
@menu_list.each do |md|
cfg['sections'][d]['display_order'] << md
pos = cfg['sections'][d][:files].find_index(md)
if pos
cfg['sections'][d][:files].delete_at(pos)
else
@err_box.append("failed delete of #{md}\n")
end
end
end
@err_box.append("Done - You can save if you want\n")
end
else
puts "no toc to deal with"
end
end

button "Save" do
# follow the TOC document and all the parts it points to
#puts "menu_list: #{@menu_list.uniq.sort}"
#cfg['toc']['files'] = @menu_list.uniq
#cfg['images'] = @image_hash
cfg['headers'] = @header_hash
cfg['links'] = @link_hash
# rewrite the ebook.yaml
File.open("#{cfg['doc_home']}/.ebook/ebook.yaml", 'w') do |f|
YAML.dump(cfg, f)
end
end
button "Save" do
cfg['links'] = @link_hash
# rewrite the ebook.yaml
File.open("#{cfg['doc_home']}/.ebook/ebook.yaml", 'w') do |f|
YAML.dump(cfg, f)
end
end
end
@err_box = edit_box height: 300, width: 680
end
end

button "3- order sections" do
Expand Down Expand Up @@ -276,7 +334,7 @@
end
button "6 - Create an app" do
@panel.clear do
para "Create your \"#{cfg['book_title']}\" ebook for #{RUBY_PLATFORM}. May gods have mercy on you!"
para "Create your \"#{cfg['book_title']}\" ebook for #{RUBY_PLATFORM}. May the gods be merciful!"
button "Package" do
end
end
Expand Down
3 changes: 3 additions & 0 deletions help_ebook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ def render_section
def Shoes.make_ebook(book_title = "The Shoes Manual")
font "fonts/Coolvetica.ttf" unless Shoes::FONTS.include? "Coolvetica"
# load the yaml and see what we have for a TOC and settings
# we need to do a lot in our load_doc including the kramdown generation
# and toc building
cfg = YAML.load_file('shoes_ebook.yaml')

puts "Toc root #{cfg['toc']['root']}"
proc do
#extend Shoes::Manual
Expand Down
2 changes: 1 addition & 1 deletion kd-pre.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def convert_text(el)
if dblbracket
menu = dblbracket[2..-3].gsub(' ', '-')
@menu_list << "#{menu}.md"
puts "LINK: #{menu}"
#puts "LINK: #{menu}"
end
end

Expand Down
172 changes: 172 additions & 0 deletions kd-toc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# -*- encoding: utf-8 -*-
# Preprocess for menus those [[ ]] links

require("kramdown")

module Kramdown
module Converter
class Menuparse < Base
attr_accessor :image_hash

def initialize(root, options)
#puts "MenuParse init opts: #{options.inspect}"
if options
@image_hash = options[:img_hash]
@header_hash = options[:hdr_hash]
@link_hash = options[:lnk_hash]
@menu_list = options[:menu_list]
#@section = options[:chapter]
#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

# TODO: fix these in kd-render
def convert_br(el)
end

def convert_blockquote(el)
end

def convert_table(el)
end

def convert_ol(el)
end

def convert_html_element(el)
end

#end of *this* TODO

def convert_text(el)
#%{para("#{el.value}", :margin_left => 0, :margin_right => 0)}
dblbracket = el.value[/\[\[(.*)\]\]/]
if dblbracket
menu = dblbracket[2..-3].gsub(' ', '-')
@menu_list << "#{menu}.md"
#puts "LINK: #{menu}"
end
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)
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)]
return nil
end

# TODO: syntax highlight not working (no errors - just doesn't return anything)
def convert_codespan(el)
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
fname = "#{el.attr['alt']}#{ext}"
fname.gsub!(' ', '-');
#puts "alt tag: #{fname}"
if !fname || fname[0] == '.' # start of extension
# someone didn't put an alt tag like they were supposed to do.
fname = File.basename(url)
#puts "missing alt - using #{fname}"
end
hsh[url] = fname
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 to_menuparse(e)
puts "to_menuparse called"
e.kind_of?(Array) ? (e.each { |n| to_menuparse(n) }) : (eval e unless e.nil?)
return
end




0 comments on commit 6b2ac91

Please sign in to comment.