#--
#
# Webgen Plugin for highlighting source code in arbirtrary languages using the vim-editor
# author: Hannes Schulz < mail at hannes-schulz dot de >
#
#++
#

require 'cgi'
require 'digest/md5'
require 'tempfile'

class HiLightTag < Tags::DefaultTag

	infos( :name => 'Tag/Hilight',
		  :author => "Hannes Schulz < mail at hannes-schulz dot de >",
		  :summary => 'Highlights code using vim (www.vim.org)'
		 )

	param 'filename',    nil,            'The file to highlight'
	param 'lang',        nil,            'The language to highlight the file in'
	param 'retab',       nil,            'Whether to reindent the file'
	param 'number',      true,           'Whether to number the lines'
	param 'vimpath',     '/usr/bin/vim', 'Where to find the vim executable'
	set_mandatory 'file', true

	register_tag 'hilight'

	def process_tag( tag, chain )
		retab        = param( 'retab' )
		lang         = param( 'lang' )
		filename     = param( 'filename' )
		number       = param( 'number' )
		vimpath      = param( 'vimpath' )
		content = ''
		begin
			filename = File.join( chain.first.parent.node_info[:src], param( 'filename' ) ) unless filename =~ /^(\/|\w:)/
			content = File.read( filename ) + lang.to_s + retab.to_s + number.to_s
		rescue
			log(:error) { "Given file <#{filename}> specified in <#{chain.first.node_info[:src]}> does not exist or can't be read" }
		end

		# test whether we did this already using the md5-sum of the file and the parameters
		m        = Digest::MD5.new 
		id       = m.hexdigest(content)
		md5fn    = filename.gsub(/\/([^\/]+)$/,"/.\\1") + ".hexdigest"
		codefn   = filename.gsub(/\/([^\/]+)$/,"/.\\1") + ".htmlcode"
		recreate = false
		recreate = true unless File.exist?(codefn)
		begin
			oldid    = File.read(md5fn)
			recreate = true if id != oldid
		rescue
			idequal = true
		end

		# recreate file if necessary
		if recreate
			retabcmd        = retab   ? "-c 'normal gg=G'"  : ""
			langcmd         = lang    ? "-c 'se ft=#{lang}'"  : ""
			numbercmd       = number  ? "-c 'se number'"  : "-c 'se nonumber'"

			cmd = "#{vimpath} -c 'syn on' #{langcmd} #{numbercmd} #{retabcmd} -R -c Yankcode -c tabnew -c 'normal P' -c 'w! #{codefn}' -c 'qa!' #{filename}"
			system(cmd)

			# save new md5 sum
			begin
				f = File.open(md5fn,"wb")
				f.print(id)
				f.close
			rescue
				log(:warn) { "Could not save MD5-Sum to #{md5fn} " }
			end
		end

		begin
			content = File.read( codefn )
		rescue
			log(:error) { "HTML-Code for #{filename} expected in #{codefn} cannot be read" }
		end
		content
	end

end

