#!/usr/bin/ruby
# coding: utf-8

require 'nokogiri'

LogLevel=1
raise ArgumentError, 'Source/destination files not specified' if ARGV.size != 2
srcfile = ARGV[0]
dstfile = ARGV[1]

f=File.open(srcfile)
xml = Nokogiri::XML(f)

def log(level,what)
  indicators = %w(! • # -)
  if level >= LogLevel
    print indicators[level]
  else
    print "\n%s %s\n" % ['*' * (level+1), what]
  end
end

def partreplace(xml, partid, tag)
  xml.css('part[id=' + partid + ']').each do |part|
    part.name = tag
  end
end


log 0, 'replace article* with book*'
xml.css('articleinfo').each do |node|
  node.name = 'bookinfo'
  node.last_element_child.after(<<'XML')
<copyright>
    <year>2017</year>
    <holder>Creative Commons</holder>
</copyright>
XML
  node.last_element_child.after(<<'XML')
<publisher>
    <publishername>Instituto de Investigaciones Económicas</publishername>
    <address><city>Universidad Nacional Autónoma de México</city></address>
</publisher>
XML
end
xml.css('article').each do |node|
  node.name = 'book'
  node['lang'] = 'en'
end

log 0, 'change parts to colophon, dedication and chapter'
partreplace(xml, 'colophon', 'colophon')
partreplace(xml, 'dedication', 'dedication')
partreplace(xml, 'foreword', 'preface')
partreplace(xml, 'introduction', 'preface')
partreplace(xml, 'bibliography', 'appendix')
partreplace(xml, 'acknowledgments', 'appendix')

log 0, 'place part introduction into <partintro>'
s = xml.xpath("//part/title[text()='The Case Studies']")[0]
if s
  s.after('<partintro>')
  p = xml.css('part partintro')[0]
  s.parent.xpath("//part/para").each do |node|
    node.parent = p
  end
end


log 0, 'remove empty notes/web links sections'
[
  'Notes',
  'Web links',
  'Web link',
].each do |title|
  xml.xpath("//title[text()='%s']" % title).each do |node|
    p = node.parent
    node.remove
    if p.content =~ /^\s*$/
      p.remove
    else
      raise RuntimeError, 'Non-empty «%s» found' % title
    end
  end
end

log 0, 'remove title from dedication'
if ! xml.css('dedication title').empty?
  xml.css('dedication title')[0].content = ""
end

log 0, 're-styling dedication, preface and introduction authors'
xml.css('dedication').each do |ded|
# Take content out of the quote marks, and into the blockquote
  quote = ded.css('quote').first
  auth = ded.css('itemizedlist').first
  quote_c = quote.content
  auth_c = auth.content
  # Styling the attribution (including the introducing hyphen) should
  # be left to the following layers
  auth_c.gsub!(/\s+/, ' ')
  c = ded.css('quote').first.content
  quote.parent.remove # remove the '<para>' containing the quote
  auth.remove
  ded.last_element_child.after('<blockquote><attribution>%s</attribution><para>%s</para></blockquote>' %
                               [auth_c, quote_c])
end

%w(preface#foreword preface#introduction).each do |spec|
  sect = xml.css(spec)[0]
  paras = sect.css('para emphasis')
  auth = '<blockquote><attribution>'
  auth += paras.map{|p| p.content}.join(', <?latex \newline ?>')
  auth += '</attribution><para/></blockquote>'
  sect.last_element_child.after(auth)
  paras.each {|i| i.parent.remove} # Remove both the 'emphasis' and its parent 'para'
end

auth = xml.css('chapter')[0].css('para')[0]
auth.content =~ /^\s*Paul Stacey\s*$/ or
  raise RuntimeError, 'Error finding author name in chapter 1 -- ' + auth.content
auth.before('<blockquote><attribution>Paul Stacey</attribution><para/></blockquote>')
auth.remove

auth = xml.css('chapter')[1].css('para')[0]
auth.content =~ /^\s*Sarah Hinchliff Pearson.*$/ or
  raise RuntimeError, 'Error finding author name in chapter 2 -- ' + auth.content
auth.before('<blockquote><attribution>Sarah Hinchliff Pearson</attribution><para/></blockquote>')
auth.remove

log 0, 'move legal notice to bookinfo'
xml.css('book bookinfo')[0].last_element_child.after('<legalnotice>')
ln = xml.css('book bookinfo legalnotice')[0]
xml.css('para').each do |para|
  if para.content =~ /This book is published under a/
    log 0, 'found legal'
    para.parent = ln
    break
  end
end

log 0, 'replace colophon page with one for this edition'
 xml.xpath('//colophon/para').remove
s = xml.xpath('//colophon')[0]
s.first_element_child.after(<<'XML')
<para>Made with Creative Commons by Paul Stacey and Sarah Hinchliff Pearson</para>

<para>© 2017 by the Creative Commons Foundation.</para>

<para>Published under a Creative Commons Attribution-ShareAlike
license (CC BY-SA), version 4.0.</para>

<para>The license means that you can copy, redistribute, remix,
transform, and build upon the content for any purpose, even
commercially, as long as you give appropriate credit, provide a link
to the license, and indicate if changes were made. If you remix,
transform, or build upon the material, you must distribute your
contributions under the same license as the original. License details:
<ulink url="http://creativecommons.org/licenses/by-sa/4.0/"/></para>

<para>Illustrations by Bryan Mathers,
<ulink url="https://bryanmmathers.com/"/>.</para>

<para>Publisher: Gunnar Wolf.</para>

<para>
<!--space for information about translators-->
&nbsp;
</para>

<para>Made With Creative Commons was originally published with the
kind support of Creative Commons and backers of our
crowdfunding-campaign on the Kickstarter.com platform.</para>

<para>This edition of the book is maintained on
<ulink url="https://gitlab.com/gunnarwolf/madewithcc-es/"/>, and the
translations are maintained on
<ulink url="https://hosted.weblate.org/projects/madewithcc/"/>.  If
you find any error in the book, please let us know.</para>

<para>ISBN: YET-TO-BE-DECIDED (PDF), YET-TO-BE-DECIDED (ePub),
YET-TO-BE-DECIDED (Paperback) </para>

<para><ulink url="https://madewith.cc/"/></para>

<para>
(Dewey) 346.048, 347.78
</para>

<para>
(US Library of Congress) Z286 O63 S73 2017
</para>

<para>
(Melvil) 025.523
</para>

XML

log 0, 'remove title from colophon'
xml.css('colophon title')[0].content = ""

log 0, 'change CC logo images to informalfigure'
xml.css('figure mediaobject imageobject imagedata[width="40.0%"]').each do |id|
  f = id.parent.parent.parent
  f.name = 'informalfigure'
end

log 0, 'assigning IDs to formal figures'
seq = 1
xml.css('figure').each do |fig|
  fig['id'] = 'fig-%d' % seq
  seq = seq + 1
end

log 0, 'Set epigraph line in each case study'
xml.css('blockquote para').select {|p| p.inner_text =~ /Profile written by/}.each do |epi|
  p = epi.parent
  by = epi.inner_text
  epi.remove
  p.first_element_child.before('<attribution>%s</attribution></para>' % by)
end


# Disabled as dblatex do not understand chapter/chapterinfo/author,
# see <URL: https://bugs.debian.org/891183 >.
if false
log 0, 'migrate chapter author into <chapterinfo> where relevant'
xml.css('chapter para').each do |para|
  if para.content =~ /^\s*((Paul|Sarah Hinchliff) (Stacey|Pearson))\s*$/
    log 1, 'migrated %s %s' % [$2, $3]
    para.parent.css('title')[0].before(<<'XML' % [$2, $3])
      <chapterinfo>
	<author>
	  <firstname>%s</firstname><surname>%s</surname>
	</author>
      </chapterinfo>
XML
    para.remove
  end
end
end

log 0, 'replace "Fig. \#." with docbook figure xref'
xml.css("para").each do |para|
  xml_text = para.to_xml(:skip_instruct => true).to_s
  xml_text.gsub!(/Fig\.\s+(\d)\.?/,
                 'Fig. <xref xrefstyle="template:%n" linkend="fig-\\1"/>')
  para.after(xml_text)
  para.remove
end

log 0, 'Writing processed file'
# Unable to figure out API way to replace DOCTYPE
data = xml.to_xml().gsub!(/DOCTYPE article/, 'DOCTYPE book')
File.open(dstfile, 'w') {|f| f.write(data)}
