- # coding: utf-8
- require 'nokogiri'
- $default_style = 'Text_Style'
- class TopicFile
- attr_reader :filename
- attr_accessor :styles
- def initialize(filename)
- @filename = filename
- @doc = nil
- @styles = []
- @processed_nodes = []
- end
- def doc
- @doc || @doc = Nokogiri::XML(open(@filename))
- end
- # moves header and creates new header/para
- def process_header!(header_node_text='ueNTP HA4UC/|EHUU')
- # getting header text
- header_text = self.doc.xpath('//body/header/para').first.text
- # create para header
- body_childs = self.doc.xpath('//body').first.children
- # getting header
- h = body_childs.xpath('//header').first
- # getting header's para
- h_para = h.xpath('//para').first
- # store page header text
- h_para_content = h_para.content
- # replace header's para text
- h_para.content = header_node_text
- # creating new para for header
- para_header_node = Nokogiri::XML::Node.new('para', self.doc)
- para_header_node['styleclass'] = 'Header2'
- # creating para's text note with page header text
- para_header_text_node = Nokogiri::XML::Node.new('text', self.doc)
- para_header_text_node['styleclass'] = 'Header2'
- para_header_text_node['translate'] = 'true'
- para_header_text_node.content = h_para_content
- # add para's text into para node
- para_header_node.add_child(para_header_text_node)
- # insert para_header immedeatly after <header> node
- h.after(para_header_node)
- end
- def replace_styles!
- # get root nodes
- base_nodes = [self.doc.root]
- # for every root node...
- base_nodes.each do |base_node|
- # for every style replacement...
- @styles.each do |style|
- # replace style if exists
- process_node(base_node, style[:old], style[:new])
- end
- end
- # for every root node...
- base_nodes.each do |base_node|
- normalize_style(base_node)
- end
- end
- def clear_styles!
- # get root nodes
- base_nodes = [self.doc.root]
- # clear styles
- base_nodes.each {|base_node| clear_style(base_node) }
- end
- def process_node(node, old_style, new_style)
- if node
- # if style matches -> replace
- if node['styleclass'] == old_style
- node['styleclass'] = new_style
- @processed_nodes << node
- end
- # if have children -> proceed they
- if node.children && !node.children.empty?
- node.children.each {|n| process_node(n, old_style, new_style) }
- end
- end
- end
- def normalize_style(node)
- if node
- if node['styleclass'] && !@processed_nodes.include?(node)
- node['styleclass'] = 'Text_Style'
- node['style'] = ''
- end
- # if have children -> proceed they
- if node.children && !node.children.empty?
- node.children.each {|n| normalize_style(n) }
- end
- end
- end
- def clear_style(node)
- if node
- if node['style']
- node['style'] = ''
- end
- # if have children -> proceed they
- if node.children && !node.children.empty?
- node.children.each {|n| clear_style(n) }
- end
- end
- end
- def process_tables!
- @to_table_header = []
- base_nodes = [self.doc.root]
- base_nodes.each {|base_node| process_table(base_node) }
- @to_table_header.each do |para|
- para['styleclass'] = 'Table_Header'
- para['style'] = ''
- end
- end
- def process_table(node)
- if node
- # check one level children for image tag
- children_tr_first = node.xpath('child::table/tr').first
- if children_tr_first
- children_paras = children_tr_first.xpath('child::td/para')
- # end
- # children_paras = node.xpath('child::table/tr[1]/td/para')
- if children_paras && !children_paras.empty?
- children_paras.each do |p|
- @to_table_header << p
- p_text = p.xpath('child::text').first
- @to_table_header << p_text if p_text
- end
- end
- end
- # if have children -> proceed they
- if node.children && !node.children.empty?
- node.children.each {|n| process_table(n) }
- end
- end
- end
- def set_style_images!
- @to_style_image = []
- base_nodes = [self.doc.root]
- base_nodes.each {|base_node| set_style_image(base_node) }
- @to_style_image.each do |node_with_image|
- node_with_image['styleclass'] = 'Image_Style'
- node_with_image['style'] = ''
- end
- end
- def set_style_image(node)
- if node
- # check one level children for image tag
- children_images = node.xpath('child::image')
- if children_images && !children_images.empty?
- @to_style_image << node
- children_images.each {|x| @to_style_image << x }
- end
- # if have children -> proceed they
- if node.children && !node.children.empty?
- node.children.each {|n| set_style_image(n) }
- end
- end
- end
- end
- class FileProcessor
- def initialize(folder='.', is_batch=false)
- @folder = folder
- @is_batch = is_batch
- end
- def process!(h=false, s=false, c=false)
- if !h && !s
- puts "Обрабатывать нечего..."
- return
- end
- folders = []
- if @is_batch
- end
- puts @folder
- Dir.chdir(@folder)
- Dir.chdir('Topics')
- xmls = Dir.glob('*.xml')
- @renames = []
- i = 1
- wputs "\nОбработка файлов...\n\n"
- xmls.each do |xml_filename|
- wputs "#{i}: #{xml_filename}"
- tf = TopicFile.new(xml_filename)
- if h
- tf.process_header!('Центр Начислений')
- wputs " Заголовок перемещен"
- end
- if s
- # new actual styles
- tf.styles << { :old => 'Heading1', :new => 'header2' }
- tf.styles << { :old => 'List Number', :new => 'Number1' }
- tf.styles << { :old => 'List Number 2', :new => 'Number2' }
- tf.styles << { :old => 'List Number 3', :new => 'Number3' }
- tf.styles << { :old => 'List Bullet', :new => 'Mark1' }
- tf.styles << { :old => 'List Bullet+', :new => 'Mark2' }
- tf.styles << { :old => 'Термин +', :new => 'Term' }
- tf.styles << { :old => 'Примечание', :new => 'Note_Header' }
- tf.styles << { :old => 'annotation text', :new => 'Style_Note' }
- tf.styles << { :old => 'Таблица Заголовок+', :new => 'Table_Header' }
- tf.styles << { :old => 'Таблица текст', :new => 'Table_Text' }
- tf.styles << { :old => 'Код', :new => 'ProgramCod' }
- tf.styles << { :old => 'Код рамка', :new => 'ProgramCod_Border' }
- # tf.styles << { :old => 'Body Text Indent+', :new => 'Style_Image' }
- tf.styles << { :old => 'Body Text Indent+', :new => 'Image_Style' }
- tf.styles << { :old => 'Hyperlink', :new => 'Style_Link' }
- tf.styles << { :old => 'Доп. стиль заголовка 6',:new => 'Header3' }
- tf.styles << { :old => 'Доп. стиль заголовка 7',:new => 'Header3' }
- # removed 'cos Text_Style is $default_style
- # tf.styles << { :old => 'Основной текст без отступа',
- # :new => 'Text_Style' }
- # tf.styles << { :old => 'Body Text Indent', :new => 'Text_Style' }
- # New actual good styles
- tf.styles << { :old => 'header2', :new => 'header2' }
- tf.styles << { :old => 'Number1', :new => 'Number1' }
- tf.styles << { :old => 'Number2', :new => 'Number2' }
- tf.styles << { :old => 'Number3', :new => 'Number3' }
- tf.styles << { :old => 'Mark1', :new => 'Mark1' }
- tf.styles << { :old => 'Mark2', :new => 'Mark2' }
- tf.styles << { :old => 'Term', :new => 'Term' }
- tf.styles << { :old => 'Note_Header', :new => 'Note_Header' }
- tf.styles << { :old => 'Style_Note', :new => 'Style_Note' }
- tf.styles << { :old => 'Table_Header', :new => 'Table_Header' }
- tf.styles << { :old => 'Table_Text', :new => 'Table_Text' }
- tf.styles << { :old => 'ProgramCod', :new => 'ProgramCod' }
- tf.styles << { :old => 'ProgramCod_Border',:new => 'ProgramCod_Border' }
- # tf.styles << { :old => 'Style_Image', :new => 'Style_Image' }
- tf.styles << { :old => 'Image_Style', :new => 'Image_Style' }
- tf.styles << { :old => 'Style_Link', :new => 'Style_Link' }
- tf.styles << { :old => 'Header3', :new => 'Header3' }
- tf.styles << { :old => 'Header2', :new => 'Header2' }
- tf.styles << { :old => 'Header1', :new => 'Header1' }
- tf.styles << { :old => 'Style_Header1', :new => 'Style_Header1' }
- tf.styles << { :old => 'Style_Header2', :new => 'Style_Header2' }
- tf.styles << { :old => 'Style_Header2', :new => 'Header2' }
- tf.styles << { :old => 'Style_Header3', :new => 'Style_Header3' }
- tf.replace_styles!
- tf.set_style_images!
- tf.process_tables!
- wputs " Стили заменены"
- end
- if c
- tf.clear_styles!
- wputs " Дополнительные стили очищены"
- end
- Dir.mkdir('_new') if !Dir.exists?('_new')
- File.open("_new/#{i}.xml", 'w') do |file|
- file.write(tf.doc.to_xml)
- wputs " => #{i}.xml"
- @renames << { :old => xml_filename.split('.')[0], :new => i.to_s}
- end
- i += 1
- end
- Dir.chdir('..')
- # rename topic is in table of content
- toc = Nokogiri::XML(open('Maps/table_of_contents.xml'))
- # get root nodes
- base_nodes = [toc.root]
- wputs "\n\nОбработка содержания..."
- # for every root node...
- base_nodes.each do |base_node|
- # for every style replacement...
- @renames.each do |rename|
- # replace style if exists
- process_toc(base_node, rename[:old], rename[:new])
- end
- end
- wputs 'Содержание обработано, необходимо вручную переименовать новый'
- wputs 'файл Maps\table_of_contents_NEW.xml в файл table_of_contents.xml,'
- wputs 'старый файл необходимо удалить.'
- # puts toc.to_xml
- File.open('Maps/table_of_contents_NEW.xml', 'w') do |toc_file|
- toc_file.write(toc.to_xml)
- end
- end
- def process_toc(node, old_href, new_href)
- if node
- # if style matches -> replace
- if node['href'] == old_href
- node['href'] = new_href
- end
- # if have children -> proceed they
- if node.children && !node.children.empty?
- node.children.each {|n| process_toc(n, old_href, new_href) }
- end
- end
- end
- end
- def check(arg, s, f)
- arg == "-#{s}" || arg == "--#{f}"
- end
- def wputs(str='')
- begin
- puts str.encode('cp866')
- rescue
- puts str
- end
- end
- if ARGV.empty? || ARGV.count < 2
- wputs "Конвертер отчетов, заменяет стили и перемещает заголовки.\n\n"
- wputs "Способ использования: ruby ham_edit.rb [опции] [путь до распакованной папки]"
- wputs " Примечание: распакованная папка должна содержать папку Topics."
- wputs ""
- wputs "Возможные опции:"
- wputs " -s - замена стилей"
- wputs " -h - перемещение заголовков"
- # wputs " -c - очистка прямого указания форматирования"
- exit
- end
- fp = FileProcessor.new(ARGV[-1])
- s, h, c = false, false, false
- ARGV.each do |arg|
- s ||= check arg, :s, :styles
- h ||= check arg, :h, :headers
- # c ||= check arg, :c, :clear
- end
- fp.process!(h, s, c)