summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/hyph-utf8/collaboration/generate-js-Hyphenator.rb
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/generic/hyph-utf8/collaboration/generate-js-Hyphenator.rb')
-rwxr-xr-xMaster/texmf-dist/source/generic/hyph-utf8/collaboration/generate-js-Hyphenator.rb204
1 files changed, 204 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/generic/hyph-utf8/collaboration/generate-js-Hyphenator.rb b/Master/texmf-dist/source/generic/hyph-utf8/collaboration/generate-js-Hyphenator.rb
new file mode 100755
index 00000000000..55a44f67f1b
--- /dev/null
+++ b/Master/texmf-dist/source/generic/hyph-utf8/collaboration/generate-js-Hyphenator.rb
@@ -0,0 +1,204 @@
+#!/usr/bin/env ruby
+
+# This file generates patterns for Hyphenator.js
+# http://code.google.com/p/hyphenator
+#
+# Collaboration with:
+# Mathias Nater, <mathias at mnn.ch>
+
+load '../languages.rb'
+# TODO: should be singleton
+languages = Languages.new
+
+languages["de-CH-1901"] = languages["de-ch-1901"]
+languages["en-GB"] = languages["en-gb"]
+languages["en-US"] = languages["en-us"]
+languages["en-US-x-knuth"] = languages["en-us"]
+languages["mn"] = languages["mn-cyrl"]
+languages["sr-Cyrl"] = languages["sr-cyrl"]
+languages["sr-Latn"] = languages["sh-latn"]
+languages["zh-Latn"] = languages["zh-latn"]
+
+
+$path_root=File.expand_path(Dir.getwd + "/../../../..")
+$path_plain="#{$path_root}/tex/generic/hyph-utf8/patterns/txt"
+$path_js=File.expand_path("#{$path_root}/../collaboration/hyphenator/repo")
+
+# change to current folder and read all the files in it
+Dir.chdir("#{$path_plain}")
+files = Dir.glob("*.pat.txt")
+# files = Dir.glob("*sl.pat.txt")
+
+# we need to escape some characters; for a complete list see
+# http://www.jslint.com/lint.html
+# but at the moment there are only two such characters present anyway
+#
+# this function encapsulates the string into single quotes and uses
+def unescape_string_if_needed(str)
+ # unsafe characters - see above for complete list
+ unsafeCharacters = [0x200c, 0x200d]
+ # let's convert our string into array (to preserve proper unicode numbers)
+ str_array=str.unpack("U*")
+ # set this to false until the first replacement takes place
+ replacement_done = false
+
+ # loop over all unsafe character and try to replace all occurencies
+ unsafeCharacters.each do |c|
+ # find the first occurence of that character
+ i = str_array.index(c)
+ while i != nil
+ # replaces a single character with '%uXXXX', where XXXX is hex code of character
+ # this only works with non-math characters, but it should not happen that any bigger number would occur
+ str_array[i,1] = sprintf("%%u%4X", c).unpack("U*")
+ i = str_array.index(c)
+ replacement_done = true
+ end
+ end
+
+ # convert the array back to string
+ str = str_array.pack("U*")
+
+ if replacement_done
+ return "unescape('#{str}')"
+ else
+ return "'#{str}'"
+ end
+end
+
+class Pattern
+ # include Enumerable
+
+ def initialize(pattern)
+ @pattern = pattern.strip
+ @pattern_array = @pattern.unpack("U*")
+ @length = @pattern_array.length
+ end
+
+ def <=>(anOther)
+ # if @length == anOther.length
+ # 0.upto(@length-1) do |i|
+ # if @pattern_array[i] != anOther.pattern_array[i]
+ # return @pattern_array[i] <=> anOther.pattern_array[i]
+ # end
+ # end
+ # return 1 <=> 1
+ # else
+ # @length <=> anOther.length
+ # end
+ @length <=> anOther.length
+ end
+
+ def js_pattern
+ @pattern.gsub(/[.]/, "_")
+ end
+
+ def to_s
+ @pattern
+ end
+
+ def length_of_letters_only
+ return @pattern.gsub(/[0-9]/,'').unpack("U*").length
+ end
+
+ # def sort_by_length
+ attr_reader :pattern, :length, :pattern_array
+end
+
+# TODO: this should be an explicit array of patterns only
+class Patterns < Array
+ def length_of_shortest_and_longest_pattern
+ # store the minimum and maximum length of pattern
+ a = [self.first.length_of_letters_only, self.first.length_of_letters_only]
+ #
+ # a = [0, 1]
+ self.each do |pat|
+ a[0] = [a[0], pat.length_of_letters_only].min
+ a[1] = [a[1], pat.length_of_letters_only].max
+ # a.first = [a.first, pat.length_of_letters_only].min
+ # a.last = [a.last, pat.length_of_letters_only].max
+ end
+ return a
+ end
+ # TODO: you need to make sure that patterns are sorted according to their length first
+ def each_length
+ current_length = 0
+ first_pattern_with_some_size = Array.new
+
+ self.each_index do |i|
+ pattern = self[i]
+ if pattern.length > current_length
+ current_length = pattern.length
+ first_pattern_with_some_size.push(i)
+ end
+ end
+
+ first_pattern_with_some_size.each_index do |i|
+ i_first = first_pattern_with_some_size[i]
+ i_last = nil
+ if i < first_pattern_with_some_size.length-1
+ i_last = first_pattern_with_some_size[i+1]
+ else
+ i_last = self.length
+ end
+ i_len = i_last-i_first
+
+ yield self[i_first,i_len]
+ end
+ end
+end
+
+files.each do |filename|
+ code_in = filename.gsub(/hyph-(.*).pat.txt/,'\1')
+ code_out = code_in.gsub(/-/,"_")
+ language = languages[code_in] # FIXME
+ # TODO: handle exceptions
+ puts
+ puts "Generating Hyphenator.js support for " + code_in
+ puts " writing to '#{$path_js}/#{code_out}.js'"
+ puts
+ patterns = Patterns.new
+ File.open(filename,'r') do |f_in|
+ f_in.each_line do |line|
+ if line.strip.length > 0
+ patterns.push(Pattern.new(line))
+ end
+ end
+ end
+ patterns.sort!
+ # puts patterns
+ specialChars = patterns.join('').gsub(/[.0-9a-z]/,'').unpack('U*').sort.uniq.pack('U*')
+
+ File.open("#{$path_js}/#{code_out}.js", "w") do |f_out|
+ # BOM mark
+ # f_out.puts [239,187,191].pack("ccc")
+ # f_out.print ["EF","BB","BF"].pack("H2H2H2")
+ f_out.putc(239)
+ f_out.putc(187)
+ f_out.putc(191)
+ f_out.puts "Hyphenator.languages.#{code_out} = {"
+ f_out.puts "\tleftmin : #{language.hyphenmin[0]},"
+ f_out.puts "\trightmin : #{language.hyphenmin[1]},"
+ lengths = patterns.length_of_shortest_and_longest_pattern
+ f_out.puts "\tshortestPattern : #{lengths.first},"
+ f_out.puts "\tlongestPattern : #{lengths.last},"
+ # TODO: handle Ux201C, Ux201D
+ # if specialChars.gsub!(/.../, ...) ~= nil
+ # if specialChars =~ /[]/
+ # if has_unsafe_characters(specialChars)
+ # end
+ unescape_string_if_needed(specialChars)
+ f_out.puts "\tspecialChars : #{unescape_string_if_needed(specialChars)},"
+ f_out.puts "\tpatterns : {"
+
+ # current length of patterns (they are sorted according to their length)
+ current_length = 0
+ pattern_string = ""
+ i_first = i_last = -1
+ patterns.each_length do |pats|
+ f_out.puts "\t\t#{pats.first.length} : #{unescape_string_if_needed(pats.join(""))}"
+ end
+
+ f_out.puts "\t}"
+ f_out.puts "};"
+ end
+end