| 
View
 

OPMLtoOL

This version was saved 18 years, 3 months ago View current version     Page history
Saved by PBworks
on August 14, 2007 at 7:19:43 pm
 

#!ruby

 

  1. =============================================================================

 

#

 

  1. Convert an OPML file to an ordered list, with the addition of

 

  1. heirarchical numbering, both in text and as named anchors,

 

  1. for embedding in HTML and/or WIKI

 

#

 

  1. *** Read the OPML file (as XML, in a very simple format)

 

  1. TODO: Look at OPML specification; currently only read

 

#

 

  1. *** Write the of the OPML as an HTML outline with named anchors

 

  1. and heirarchical legal outline numbers, suitable for embedding.

 

#

 

  1. TODO:

 

  1. Explicitly use "Purple Numbers" and/or Node IDs

 

  1. (http://www.eekim.com/software/purple/purple.html)

 

  1. Explicitly conform to XOXO

 

  1. (http://microformats.org/wiki/xoxo)

 

  1. Learn Ruby

 

#

 

  1. Written August, 2007, Edwin Wise, Simulated Reality Systems, LLC

 

  1. www.simreal.com

 

#

 

  1. DEPENDENCIES:

 

  1. REXML http://www.germane-software.com/software/rexml/

 

  1. GetoptLong http://www.ruby-doc.org/stdlib/libdoc/getoptlong/rdoc/index.html

 

  1. =============================================================================

 

 

 

  1. =============================================================================

 

  1. Help / Usage

 

  1. =============================================================================

 

def usage(*errorMesg)

 

print "\n\nERROR: '" + errorMesg.join("\n") + "'\n" if (errorMesg.length > 0)

print "\nUsage:\n"

print "OPMLtoOL.rb --opml file.opml --dest folder --format style\n"

print "where:\n"

print " --opml Source OPML file.\n"

print " --dest Destination folder name (optional).\n"

print " --format Output format, one of: pbwiki, mediawiki, html.\n"

 

end

 

 

 

  1. =============================================================================

 

  1. genOutlineString

 

#

 

  1. Given an outline numbering array, turn it into a relevant string

 

  1. =============================================================================

 

def genOutlineString(outline, delim)

 

string = ""

outline.each { index

string << index.to_s + delim

}

string.chop! if (delim === "_")

string

 

end

 

 

 

  1. =============================================================================

 

  1. GenericFormatter base class

 

#

 

  1. Given an element, pull out its text and generate the appropriate list

 

  1. entry. If that element has sub-elements, recurses appropriately.

 

#

 

  1. Abstract wrapper only; subclass to give specific formats.

 

  1. =============================================================================

 

class GenericFormatter

 

def initialize

end

def listStart

raise "Invalid use of GenericFormatter.listStart"

end

def listEnd

raise "Invalid use of GenericFormatter.listEnd"

end

def indent(depth)

raise "Invalid use of GenericFormatter.indent"

end

def itemStart

raise "Invalid use of GenericFormatter.itemStart"

end

def itemEnd

raise "Invalid use of GenericFormatter.itemEnd"

end

def anchor(hidAnchor)

raise "Invalid use of GenericFormatter.anchor"

end

def link(hidAnchor, hidName)

raise "Invalid use of GenericFormatter.link"

end

def title(element)

element.attributes["text"]

end

def writeElement(dstFile, element, outline)

depth = outline.size

count = outline.pop + 1

outline.push(count)

#

# Current Item

#

hidAnchor = "hid_" + genOutlineString(outline, "_")

hidName = genOutlineString(outline, ".")

 

dstFile.print indent(depth)+itemStart+anchor(hidAnchor)+link(hidAnchor, hidName)+title(element)+itemEnd

#

# Optional Element Recursion

#

if (element.has_elements?) then

dstFile.print indent(depth) + listStart; outline.push(0)

element.elements.each("outline") { subelement

writeElement(dstFile, subelement, outline)

}

dstFile.print indent(depth) + listEnd; outline.pop

end

end

 

end

 

 

 

 

 

  1. =============================================================================

 

  1. HTML Formatter

 

  1. =============================================================================

 

class HTMLFormatter < GenericFormatter

 

def initialize

end

 

def listStart

"

    \n"

    end

    def listEnd

    "

\n"

end

def indent(depth)

" "*depth

end

def itemStart

"

  • "

    end

    def itemEnd

    "

  • \n"

    end

    def anchor(hidAnchor)

    ''

    end

    def link(hidAnchor, hidName)

    '' + hidName + ""

    end

     

    end

     

     

     

     

     

    1. =============================================================================

     

    1. MediaWiki Formatter

     

    1. =============================================================================

     

    class MediaWikiFormatter < HTMLFormatter

     

    def initialize

    end

    def link(hidAnchor, hidName)

    "[[#" + hidAnchor + "|" + hidName + "]]"

    end

     

    end

     

     

     

     

     

    1. =============================================================================

     

    1. PBWiki Formatter

     

    1. =============================================================================

     

    class PBWikiFormatter < HTMLFormatter

     

    def initialize

    end

    def indent(depth)

    ""

    end

    def listStart

    "

      "

      end

      def listEnd

      "

    "

    end

    def itemEnd

    ""

    end

     

    end

     

     

     

    1. =============================================================================

     

    1. Main Loop

     

    1. =============================================================================

     

    begin

     

    require "rexml/document"

    require "getoptlong"

     

    include REXML

    opts = GetoptLong.new(

    ["--opml", GetoptLong::REQUIRED_ARGUMENT],

     

    ["--dest", GetoptLong::OPTIONAL_ARGUMENT],

     

    ["--format", GetoptLong::REQUIRED_ARGUMENT],

    ["--help", GetoptLong::NO_ARGUMENT]

    )

    #

    #

    srcOPMLFilename =

    destFolderName =

    destOLFilename = ''

    formatStr = "mediawiki"

    formatter = nil

     

    opts.each { opt, arg

    case opt

    when /^--opml$/ then srcOPMLFilename = arg

    when /^--dest$/ then destFolderName = arg

    when /^--format$/ then formatStr = arg

    when /^--help$/ then usage; exit 0;

    else usage("Unrecognized option #{opt}...\n")

    end

    }

    begin

    rescue GetoptLong::InvalidOption

    usage

    exit 1

    end

    case (formatStr)

    when "mediawiki"

    formatter = MediaWikiFormatter.new

    when "pbwiki"

    formatter = PBWikiFormatter.new

    when "html"

    formatter = HTMLFormatter.new

    end

    usage("You must specify a valid --format") if (formatter.nil?)

    usage("You must specify --opml") if (srcOPMLFilename.empty?)

    usage("OPML File '" + srcOPMLFilename + "' doesn't exist") unless File.exists?(srcOPMLFilename)

    usage("OPML File '" + srcOPMLFilename + "' isn't readable") unless File.readable?(srcOPMLFilename)

     

    destFolderName = File.dirname(srcOPMLFilename) if (destFolderName.empty?)

    #

    #

    destOLFilename = destFolderName +

    File::SEPARATOR +

    File.basename(srcOPMLFilename, ".opml") +

    ".html"

    #

    #

    opml = Document.new File.open(srcOPMLFilename, File::RDONLY)

    outline = Array.new

     

    File.open(destOLFilename, File::WRONLYFile::CREATFile::TRUNC) { dstFile

    dstFile.print formatter.listStart; outline.push(0)

    opml.elements.each("opml/body/outline") { element

    formatter.writeElement(dstFile, element, outline)

    }

    dstFile.print formatter.listEnd; outline.pop

    }

     

    end

    Comments (0)

    You don't have permission to comment on this page.