View on GitHub

scriv-git-pages

Writing in Scrivener for GitHub Pages

The End Top Appendices and Ephemera

This just in

I’m using this setup for a book I’m trying to write about software development (surprise!). I’m having to change some things in the setup and script, and as I notice important ones, I’ll add a note here in the “This just in” section.

In the book, I’m using two levels of outline (so far), so I have some Markdown headers with just one pound sign, and some with two. And I wanted the table of contents to reflect that, using an outline structure that looks like this:

The indented bits are done, in Markdown, by putting four spaces for each level, before the asterisk that means list item. My table of contents maker wasn’t that clever, so I added some logic to strip pound signs differently, save the leading ones, and convert them to spaces at the last minute. I also needed to change the way the top of page / bottom of page links were parsed.

The resulting code is here:

#!/usr/bin/ruby
#!/Users/ron/.rvm/rubies/ruby-2.3.0/bin/ruby
require 'tempfile'
require 'fileutils'

SPLIT_MARKER = "----\n\n"
TOC_MARKER = "<!--TOC-->\n"
SCRIPT_FILE = "/Users/ron/Dropbox/bin/splitter"
TAB = '    '
Titles = {}

def add_toc(chunk)
  halves = chunk.split(TOC_MARKER)
  puts "halves length %d" % halves.length
  return chunk if halves.length != 2
  return halves[0] + table_of_contents + halves[1]
end

def make_file_name(filenumber)
  return "index.md" if filenumber == 0
  return sprintf("%02d.md", filenumber)
end

def make_link_line(filenumber, max_length)
  link = ""
  link += "[%s](%02d.html) | " % [trim_left(Titles[filenumber - 1]), filenumber - 1] unless filenumber == 0
  link += "[Top](index.html) | "
  link += "[%s](%02d.html)" % [trim_left(Titles[filenumber + 1]), filenumber + 1] unless filenumber >= max_length
  return link
end

def record_titles(chunks)
  filenumber = 0
  chunks.each do | chunk |
    title = chunk.split("\n")[0].strip # remove any spaces
    Titles[filenumber] = trim_right(title) # remove trailing stuff
    filenumber += 1
  end
end

def trim_full(string)
  trim_left(trim_right(string))
end

def trim_right(string)
  string.gsub(/ *#*$/, '')
end

def trim_left(string)
  string.gsub(/^#* */, '')
end

def table_of_contents
  toc = ""
  Titles.each_pair do | number, title |
    # looks like: ### title
    pounds, *rest = title.split(' ')
    the_title = rest.join(' ')
    tabs = pounds.gsub(/#/, '    ')
    tabs = tabs[4..-1] # remove one set
    toc += "%s* [%s](%s)\n" % [tabs, the_title, make_file_name(number)] 
  end
  return toc
end

def update_table_of_contents(chunks)
  toc_chunk = chunks.delete_at(0)
  updated_toc = add_toc(toc_chunk)
  chunks.insert(0, updated_toc)
end

def write_file(chunk, reference_chunk, filenumber, max_length)
  filename = make_file_name(filenumber)
  title = Titles[filenumber]
  puts filename + ": " + title
  tf = File.new(filename, "w")
  tf.puts make_link_line(filenumber, max_length)
  tf.puts
  tf.print chunk
  tf.puts
  tf.puts
  tf.puts make_link_line(filenumber, max_length)
  tf.puts
  tf.puts
  tf.print reference_chunk
  tf.puts
  tf.puts
  tf.close
end

def write_files(chunks, reference_chunk)
  filenumber = 0
  chunks.each do |chunk|
    write_file(chunk, reference_chunk, filenumber, chunks.length - 1) unless chunk.length < 1
    filenumber += 1
  end
end

ARGF.set_encoding(Encoding::UTF_8) 
input = ARGF.read
chunks = input.split(SPLIT_MARKER)
reference_chunk = chunks.delete_at(-1)
record_titles(chunks)
update_table_of_contents(chunks)
write_files(chunks, reference_chunk)
FileUtils.cp(SCRIPT_FILE, ".")

I expect that I may go to more than two levels, and I think the above code will handle that.

At present, the splitter only looks for table of contents headings right after a page separator. I can imagine that it might need to be changed to search for all headings in the whole document. We’ll see.

Stay tuned for any other important changes!

The End Top Appendices and Ephemera