#!/usr/bin/env ruby
require 'shellwords'
require 'fileutils'
require 'cgi'
require 'rexml/document'
require 'tempfile'

class String
  def markdownify
    tables = {}
    table_index = 0
    input = dup
    input.sub!(%r{(?:.|\n)*?<body>((?:.|\n)*)</body>(?:.|\n)*}, '\1')
    input.gsub!(%r{<span class="Apple-tab-span">.*?</span>}, ' ')
    input.gsub!(/\u00A0/, "@SPACE@")
    # input.gsub!(/<span class="Apple-converted-space">(.*?)<\/span>/) {|m|
    #   match = Regexp.last_match
    #   " " * match[1].length
    # }
    input.gsub!(%r{<span class="s2">.*?</span>}, '')
    input.gsub!(/•/, '')
    input.gsub!(/(?mi)&lt;\$Scr_H::1&gt;/, '<h2>')
    input.gsub!(/(?mi)&lt;!\$Scr_H::1&gt;/, '</h2>')
    input.gsub!(/&lt;!?\$Scr_Ps::0&gt;/, '')
    input.gsub!(/&lt;!?\$Scr_Cs::\d&gt;/, '')
    input.gsub!(/[“”]/, '"')
    input.gsub!(/[’‘]/, "'")
    input.gsub!(%r{</?span.*?>}, '')
    input.gsub!(/&amp;/, '&')
    input.gsub!(/&nbsp;/, ' ')
    input.gsub!(%r{<table .*?class=".*?">(.*?)</table>}m) { |m|
      # m.gsub!(/\s*<\/?t.*?>/,'')
      # puts '<blockquote class="mkscrivtable">' + m.markdownify + '</blockquote>'
      # "\n$@$@$@$@\n" + m + "\n!@!@!@!@\n"
      table = m.gsub(%r{<p class="p.*?">(.*?)</p>}, '\1')
      tables[table_index.to_s] = table
      out = "@@@TABLE:#{table_index}@@@"
      table_index += 1
      out
    }

    input.gsub!(/(?mi)\{\\Scrv_annot(?:[\s\S]*?)\\text=([\s\S]*?)\\end_Scrv_annot\}/,
%{((((ANNOTATION))))\\1((((/ANNOTATION))))})

    # Fix "mathjax" escaping
    input.gsub!(/\\/, "\\\\\\")

    html2text = File.join(File.dirname(__FILE__), 'html2text.py')
    result = `echo #{Shellwords.escape(input)} | #{Shellwords.escape(html2text)} -S`

    result.gsub!(/(?mi)(#+) \*\*(.*?)\*\*/, '\1 \2')
    result.gsub!(/(?mi)^(#+.*?\n)(?=\S)/, "\\1\n")
    result.gsub!(/(?mi)^(>+[\s\S]*(?=\n\n))/, "\n\\1\n")
    result.gsub!(/(?mi)^ +(?=[-*+])/) { |m|
      m.double_indent
    }
    result.gsub!(/@@@TABLE:(\d+)@@@/) { |_match|
      m = Regexp.last_match
      tables[m[1]]
    }
    result.gsub!(/\\([*_><])/, '\1')
    result.gsub!(/@SPACE@/, ' ')

    result.gsub!(%r{(?mi)\(\(\(\(COMMENT\)\)\)\)(.*?)\(\(\(\(/COMMENT\)\)\)\)},
'<span class="mkscriv_annotation">\1</span>')
    result.gsub!(%r{(?mi)\(\(\(\(ANNOTATION\)\)\)\)(.*?)\(\(\(\(/ANNOTATION\)\)\)\)},
'<span class="mkscriv_annotation inline">\1</span>')
    # Fix tables with double spacing
    result.gsub!(/(?mi)(\[.*?\]\n+)?(^.*?\|.*?\n+){2,}(\[.*?\]\n+)?/) { |m|
      "\n" + m.gsub(/\n+/, "\n") + "\n"
    }
    # Fix math with double spacing
    result.gsub!(/(?mi)^(\$\$.*?\$\$|\\\\\[.*?\\\\\])/) { |m|
      "\n" + m.gsub(/\n+/, "\n") + "\n"
    }
    result.to_s
  end
end

def gather_comments(cpath)
  comments = {}
  globpath = File.join(cpath, 'Files/Data/', '**', 'content.comments')
  Dir.glob(globpath).each { |path|
    doc = REXML::Document.new File.new(path)
    doc.elements.each('Comments/Comment') do |ele|
      id = ele.attributes['ID']
      contents = ele.text.sub(/<!\[CDATA\[(.*?)\]\]>/s, '\1')
      text = rtf_to_html(contents)
      comments[id] = text.markdownify
    end
  }
  comments
end

def rtf_to_html(contents)
  html = ""
  file = Tempfile.new(['marked-scrivener-rtf', '.rtf'])
  begin
    file.write(contents)
    file.read
    html = `textutil -convert html -stdout "#{file.path}"`
 ensure
    file.close
    file.unlink
  end
  html
end

def expand_scriv_path(scrivpath)
  scrivpath = File.expand_path(scrivpath)
  scrivx = File.basename(scrivpath.to_s, ".scriv") + ".scrivx"
  scrivxpath = File.join(scrivpath, scrivx)
  # handle cases where the package has been renamed after creation
  unless File.exist?(scrivxpath)
    scrivxpath = `ls -1 #{scrivpath}/*.scrivx|head -n 1`.strip
  end
  scrivxpath
end

path = File.expand_path('~/Downloads/issue with comment.scriv')
scrivxpath = expand_scriv_path(path)

puts gather_comments(path)
