Image References Alternative | Top | Image References |
Refactoring First
OK, our issue is that Scrivener puts references, including images, at the end of the whole document. When we split the document into multiple files, one per section, each section needs to have those references at its end, or its images won’t link up.
So our mission, and we do wish to accept it, is to strip out the references from the end, and copy them onto the end of every output file before we close it. My cunning plan is roughly this:
- Put a separator at the end of the document, so that the last chunk we split out is the references section.
- Remove that section from the array of chunks, so that we don’t put it out as a separate file,
- But do append it to each of the other files.
If you look at AmberV’s script, this is accomplished by saving the section’s titles and file handles in a Hash, and then looping over them, appending the reference section to each. My script doesn’t have the section titles, but I think I can accomplish much the same thing by saving the file handles in an array.
The big moral decision here is whether to clean up this script first. Here it is:
#!/usr/bin/env ruby -wU
require 'tempfile'
SPLIT_MARKER = "----\n\n"
filenumber = 0
input = ARGF.read
chunks = input.split(SPLIT_MARKER)
# puts "Chunks length %d" % chunks.length
chunks.each do |chunk|
next if chunk.length < 1
title = chunk.split("\n")[0]
if filenumber == 0
filename = "index.md"
else
filename = sprintf("%02d", filenumber) + ".md"
end
puts filename + ": " + title
tf = File.new(filename, "w")
tf.print chunk
link = ""
if ( filenumber == 1 )
link += "[Prev](index.html) "
elsif filenumber > 1
link += "[Prev](%02d.html) " % (filenumber - 1) unless filenumber == 0
end
link += "[Top](index.html) "
link += "[Next](%02d.html)" % (filenumber + 1) unless filenumber >= chunks.length - 1
tf.puts
tf.puts
tf.puts link
tf.close
filenumber += 1
end
That’s pretty awful. I think I need to do at least a little cleanup before making it worse. Without a pair, though, and without tests, I hesitate to go too far. I’ll try a bit of cleanup, however. I should probably really create a class and call it but I’m going to hold off on that, simply because I’m rusty and more confident pulling out some functions. First, let’s go after creating that link line, which should be pretty simple. (Hold my beer.)
Ha! How could you doubt me? How could I doubt me? This worked, the first time:
#!/usr/bin/env ruby -wU
require 'tempfile'
SPLIT_MARKER = "----\n\n"
def make_link_line(filenumber, max_length)
link = ""
if ( filenumber == 1 )
link += "[Prev](index.html) "
elsif filenumber > 1
link += "[Prev](%02d.html) " % (filenumber - 1) unless filenumber == 0
end
link += "[Top](index.html) "
link += "[Next](%02d.html)" % (filenumber + 1) unless filenumber >= max_length
return link
end
filenumber = 0
input = ARGF.read
chunks = input.split(SPLIT_MARKER)
# puts "Chunks length %d" % chunks.length
chunks.each do |chunk|
next if chunk.length < 1
title = chunk.split("\n")[0]
if filenumber == 0
filename = "index.md"
else
filename = sprintf("%02d", filenumber) + ".md"
end
puts filename + ": " + title
tf = File.new(filename, "w")
tf.print chunk
tf.puts
tf.puts
tf.puts make_link_line(filenumber, chunks.length - 1)
tf.close
filenumber += 1
end
I’ll factor out the filename creation the same way. Because I’m not as dumb as I look, I do that in two steps. First I create and use a make_file_name
function by extracting the code as-is:
def make_file_name(filenumber)
if filenumber == 0
filename = "index.md"
else
filename = sprintf("%02d", filenumber) + ".md"
end
end
Now let’s improve that function:
def make_file_name(filenumber)
return "index.md" if filenumber == 0
return sprintf("%02d.md", filenumber)
end
OK, that’s nice. Here’s the main code now:
filenumber = 0
input = ARGF.read
chunks = input.split(SPLIT_MARKER)
# puts "Chunks length %d" % chunks.length
chunks.each do |chunk|
next if chunk.length < 1
title = chunk.split("\n")[0]
filename = make_file_name(filenumber)
puts filename + ": " + title
tf = File.new(filename, "w")
tf.print chunk
tf.puts
tf.puts
tf.puts make_link_line(filenumber, chunks.length - 1)
tf.close
filenumber += 1
end
Looking at this, we see half a dozen lines writing out the file. That should be factored out as well. And I am wondering: if we break the reference chunk off at the very beginning and cache it away in a variable, couldn’t we just append it during the main write, rather than in a second pass? It sure seems like we could. So I’ll factor out the writing and see what we get. A bit of polishing and we have this:
def write_file(chunk, filenumber, max_length)
filename = make_file_name(filenumber)
title = chunk.split("\n")[0]
puts filename + ": " + title
tf = File.new(filename, "w")
tf.print chunk
tf.puts
tf.puts
tf.puts make_link_line(filenumber, max_length)
tf.close
end
input = ARGF.read
chunks = input.split(SPLIT_MARKER)
filenumber = 0
chunks.each do |chunk|
write_file(chunk, filenumber, chunks.length - 1) unless chunk.length < 1
filenumber += 1
end
Now that, I don’t mind saying, is a noticeable improvement. We’ll add the references in the next section.
Image References Alternative | Top | Image References |