mizuho-0.9.19/0000755000175000017500000000000012231154765012133 5ustar felixfelixmizuho-0.9.19/data.tar.gz.asc0000644000175000017500000000102712226725615014742 0ustar felixfelix-----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org iQEcBAABAgAGBQJRgSgWAAoJECrHRaUKISqMkckH/1t5KU4rDgkQ1QmsRcdIMLTQ M3SAW5nABxs4lPT4iJL0YZmh19oJOcmFQRx/v2dYImv0/R8Q3LLs5gqFWG+Nwow9 caW87HKLB51KIImXxYMc9rB3Gp6jB+VKgW8uVAdv5ENTaDf72ldJJFNZbzzHrD6F 6hpuDKhvbHeBIFawjdmYlKMZUACKqglCtXkxGxqhXp78IMrR+X31imAZTDj0TdXO qak10qS4OLHBLZtNYIpVj0m5lAD2uiX64/CgaolnbqIYXJLIgT0snUrueaRuPRaH ryM7sASE6WYeEdavInfjE98Q7h5qfVThT/bgmB8wMHhWBMfauB6M631ZWrxGuHE= =KT1Y -----END PGP SIGNATURE----- mizuho-0.9.19/metadata.gz.asc0000644000175000017500000000102712226725615015024 0ustar felixfelix-----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org iQEcBAABAgAGBQJRgSgWAAoJECrHRaUKISqM0KoIALYyey+TmESUUVaI4bANXCmv 8IEOPmzmzLgddEbEE+4Sgm9neu9lBPCTLTIJQCNxcET2CkmfvhcqCYpWj6ewQIPS W49y/TF5iMCeLrbtyehCivE7/IatPKZ5Q+hmcQzb/9k3Vq+Pvxr8KIFrDgaKM8eB prQw+g5TBEok4H0Sp0YwkKT3utx4Oj9XpvdlpXzFUlL7sYGylbKeJWGfr8uK/jxC XIJzkTiWHRf7fbKEHVn5Wvka4DgLXGqNZiVgPb4/5MZykGQMqrPgdvVmVRb7DCW4 Xsqk0j0qfaxRVWgEs1rdOwwMtzFpmJ+OkDA9XrIoDHCDyCnFZlao7UjCJC6bwCc= =i2ql -----END PGP SIGNATURE----- mizuho-0.9.19/README.markdown0000644000175000017500000000735612226725615014651 0ustar felixfelix# Mizuho documentation formatting tool Mizuho is a documentation formatting tool, best suited for small to medium-sized documentation. One writes documentation in plain text files, which Mizuho then converts to nicely formatted HTML. Mizuho wraps [Asciidoc](http://www.methods.co.nz/asciidoc/), the text formatting tool used by e.g. Git and Phusion Passenger for its manuals. Mizuho adds the following functionality on top of Asciidoc: * A top bar that gives quick access to the table of contents. * Commenting via [Juvia](https://github.com/FooBarWidget/juvia). Mizuho bundles Asciidoc so you don't have to install it yourself. Mizuho should Just Work(tm) out-of-the-box. Asciidoc uses GNU source-highlight for highlighting source code. GNU source-highlight depends on Boost and so is notorious for being difficult to install on systems without a decent package manager (e.g. OS X). Mizuho comes prebundled with an OS X binary for GNU source-highlight so that you don't have to worry about that. ## Requirements * Nokogiri (`gem install nokogiri`) * Python (because Asciidoc is written in Python) * [GNU Source-highlight](http://www.gnu.org/software/src-highlite/), if you want syntax highlighting support. If you're on OS X then it's not necessary to install this yourself; we've bundled a precompiled source-highlight binary for OS X for your convenience. ## Installation with RubyGems Run: gem install mizuho This gem is signed using PGP with the [Phusion Software Signing key](http://www.phusion.nl/about/gpg). That key in turn is signed by [the rubygems-openpgp Certificate Authority](http://www.rubygems-openpgp-ca.org/). You can verify the authenticity of the gem by following [The Complete Guide to Verifying Gems with rubygems-openpgp](http://www.rubygems-openpgp-ca.org/blog/the-complete-guide-to-verifying-gems-with-rubygems-openpgp.html). ## Installation on Ubuntu Use our [PPA](https://launchpad.net/~phusion.nl/+archive/misc): sudo add-apt-repository ppa:user/ppa-name sudo apt-get update sudo apt-get install mizuho ## Installation on Debian Our Ubuntu Lucid packages are compatible with Debian 6. sudo sh -c 'echo deb http://ppa.launchpad.net/phusion.nl/misc/ubuntu lucid main > /etc/apt/sources.list.d/mizuho.list' sudo sh -c 'echo deb-src http://ppa.launchpad.net/phusion.nl/misc/ubuntu lucid main >> /etc/apt/sources.list.d/mizuho.list' sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C324F5BB38EEB5A0 sudo apt-get update sudo apt-get install mizuho ## Usage First, read [the Asciidoc manual](http://www.methods.co.nz/asciidoc/userguide.html) to learn the input file format: Next, write an input file and save it in a .txt file. Finally, convert the .txt file to a single HTML file with Mizuho, with the default template: mizuho input.txt This will generate 'input.html'. ### Commenting via Juvia To enable commenting via Juvia, pass `-c juvia` and the `--juvia-url` and `--juvia-site-key` arguments with appropriate values. Mizuho will generate a so-called *ID map file* if there isn't already one. This file maps section titles to Juvia topic IDs. This way you can preserve a section's comments even when you rename that section's title. Note that the section's number is considered part of the title, so renaming can happen implicitly. When a section title has been renamed, Mizuho will look for a Juvia topic ID for which the previous title is similar to the new title, and assign that ID to the section. The entry in the ID map file is then marked 'fuzzy' in order to warn you about this. You have to remove the `# fuzzy` comment in the ID map file, or Mizuho will keep complaining about this in subsequent runs. ## Credits This tool is named after Kazami Mizuho from the 2003 anime 'Onegai Teacher'. mizuho-0.9.19/LICENSE.txt0000644000175000017500000000204312226725615013757 0ustar felixfelixCopyright (c) 2008-2013 Hongli Lai Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. mizuho-0.9.19/Rakefile0000644000175000017500000002635412226725615013614 0ustar felixfelix$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/lib")) require 'mizuho' PACKAGE_NAME = "mizuho" PACKAGE_VERSION = Mizuho::VERSION_STRING PACKAGE_SIGNING_KEY = "0x0A212A8C" MAINTAINER_NAME = "Hongli Lai" MAINTAINER_EMAIL = "hongli@phusion.nl" desc "Run unit tests" task :test do ruby "-S spec -f s -c test/*_spec.rb" end desc "Build, sign & upload gem" task 'package:release' do sh "git tag -s release-#{PACKAGE_VERSION}" sh "gem build #{PACKAGE_NAME}.gemspec --sign --key #{PACKAGE_SIGNING_KEY}" puts "Proceed with pushing tag to Github and uploading the gem? [y/n]" if STDIN.readline == "y\n" sh "git push origin release-#{PACKAGE_VERSION}" sh "gem push #{PACKAGE_NAME}-#{PACKAGE_VERSION}.gem" else puts "Did not upload the gem." end end ##### Utilities ##### def string_option(name, default_value = nil) value = ENV[name] if value.nil? || value.empty? return default_value else return value end end def boolean_option(name, default_value = false) value = ENV[name] if value.nil? || value.empty? return default_value else return value == "yes" || value == "on" || value == "true" || value == "1" end end ##### Debian packaging support ##### PKG_DIR = string_option('PKG_DIR', "pkg") DEBIAN_NAME = PACKAGE_NAME ALL_DISTRIBUTIONS = ["raring", "precise", "lucid"] ORIG_TARBALL_FILES = lambda do require 'mizuho/packaging' Dir[*MIZUHO_FILES] - Dir[*MIZUHO_DEBIAN_EXCLUDE_FILES] end # Implements a simple preprocessor language: # # Today # #if @today == :fine # is a fine day. # #elif @today == :good # is a good day. # #else # is a sad day. # #endif # Let's go walking. # # When run with... # # Preprocessor.new.start('input.txt', 'output.txt', :today => :fine) # # ...will produce: # # Today # is a fine day. # Let's go walking. # # Highlights: # # * #if blocks can be nested. # * Expressions are Ruby expressions, evaluated within the binding of a # Preprocessor::Evaluator object. # * Text inside #if/#elif/#else are automatically unindented. class Preprocessor def initialize @indentation_size = 4 @debug = boolean_option('DEBUG') end def start(filename, output_filename, variables = {}) if output_filename temp_output_filename = "#{output_filename}._new" output = File.open(temp_output_filename, 'w') else output = STDOUT end the_binding = create_binding(variables) context = [] @lineno = 1 @indentation = 0 each_line(filename) do |line| debug("context=#{context.inspect}, line=#{line.inspect}") name, args_string, cmd_indentation = recognize_command(line) case name when "if" case context.last when nil, :if_true, :else_true check_indentation(cmd_indentation) result = the_binding.eval(args_string, filename, @lineno) context.push(result ? :if_true : :if_false) inc_indentation when :if_false, :else_false, :if_ignore check_indentation(cmd_indentation) inc_indentation context.push(:if_ignore) else terminate "#if is not allowed in this context" end when "elif" case context.last when :if_true dec_indentation check_indentation(cmd_indentation) inc_indentation context[-1] = :if_false when :if_false dec_indentation check_indentation(cmd_indentation) inc_indentation result = the_binding.eval(args_string, filename, @lineno) context[-1] = result ? :if_true : :if_false when :else_true, :else_false terminate "#elif is not allowed after #else" when :if_ignore dec_indentation check_indentation(cmd_indentation) inc_indentation else terminate "#elif is not allowed outside #if block" end when "else" case context.last when :if_true dec_indentation check_indentation(cmd_indentation) inc_indentation context[-1] = :else_false when :if_false dec_indentation check_indentation(cmd_indentation) inc_indentation context[-1] = :else_true when :else_true, :else_false terminate "it is not allowed to have multiple #else clauses in one #if block" when :if_ignore dec_indentation check_indentation(cmd_indentation) inc_indentation else terminate "#else is not allowed outside #if block" end when "endif" case context.last when :if_true, :if_false, :else_true, :else_false, :if_ignore dec_indentation check_indentation(cmd_indentation) context.pop else terminate "#endif is not allowed outside #if block" end when "", nil # Either a comment or not a preprocessor command. case context.last when nil, :if_true, :else_true output.puts(unindent(line)) else # Check indentation but do not output. unindent(line) end else terminate "Unrecognized preprocessor command ##{name.inspect}" end @lineno += 1 end ensure if output_filename && output output.close stat = File.stat(filename) File.chmod(stat.mode, temp_output_filename) File.chown(stat.uid, stat.gid, temp_output_filename) rescue nil File.rename(temp_output_filename, output_filename) end end private UBUNTU_DISTRIBUTIONS = { "lucid" => "10.04", "maverick" => "10.10", "natty" => "11.04", "oneiric" => "11.10", "precise" => "12.04", "quantal" => "12.10", "raring" => "13.04", "saucy" => "13.10" } # Provides the DSL that's accessible within. class Evaluator def _infer_distro_table(name) if UBUNTU_DISTRIBUTIONS.has_key?(name) return UBUNTU_DISTRIBUTIONS end end def is_distribution?(expr) if @distribution.nil? raise "The :distribution variable must be set" else if expr =~ /^(>=|>|<=|<|==|\!=)[\s]*(.+)/ comparator = $1 name = $2 else raise "Invalid expression #{expr.inspect}" end table1 = _infer_distro_table(@distribution) table2 = _infer_distro_table(name) raise "Distribution name #{@distribution.inspect} not recognized" if !table1 raise "Distribution name #{name.inspect} not recognized" if !table2 v1 = table1[@distribution] v2 = table2[name] case comparator when ">" return v1 > v2 when ">=" return v1 >= v2 when "<" return v1 < v2 when "<=" return v1 <= v2 when "==" return v1 == v2 when "!=" return v1 != v2 else raise "BUG" end end end end def each_line(filename) File.open(filename, 'r') do |f| while true begin line = f.readline.chomp rescue EOFError break end yield line end end end def recognize_command(line) if line =~ /^([\s\t]*)#(.+)/ indentation_str = $1 command = $2 name = command.scan(/^\w+/).first args_string = command.sub(/^#{Regexp.escape(name)}[\s\t]*/, '') return [name, args_string, indentation_str.to_s.size] else return nil end end def create_binding(variables) object = Evaluator.new variables.each_pair do |key, val| object.send(:instance_variable_set, "@#{key}", val) end return object.instance_eval do binding end end def inc_indentation @indentation += @indentation_size end def dec_indentation @indentation -= @indentation_size end def check_indentation(expected) if expected != @indentation terminate "wrong indentation: found #{expected} characters, should be #{@indentation}" end end def unindent(line) line =~ /^([\s\t]*)/ found = $1.to_s.size if found >= @indentation return line[@indentation .. -1] else terminate "wrong indentation: found #{found} characters, should be at least #{@indentation}" end end def debug(message) puts "DEBUG:#{@lineno}: #{message}" if @debug end def terminate(message) abort "*** ERROR: line #{@lineno}: #{message}" end end def recursive_copy_files(files, destination_dir, preprocess = false, variables = {}) require 'fileutils' if !defined?(FileUtils) files.each_with_index do |filename, i| dir = File.dirname(filename) if !File.exist?("#{destination_dir}/#{dir}") FileUtils.mkdir_p("#{destination_dir}/#{dir}") end if !File.directory?(filename) if preprocess && filename =~ /\.template$/ real_filename = filename.sub(/\.template$/, '') FileUtils.install(filename, "#{destination_dir}/#{real_filename}") Preprocessor.new.start(filename, "#{destination_dir}/#{real_filename}", variables) else FileUtils.install(filename, "#{destination_dir}/#{filename}") end end printf "\r[%5d/%5d] [%3.0f%%] Copying files...", i + 1, files.size, i * 100.0 / files.size STDOUT.flush end printf "\r[%5d/%5d] [%3.0f%%] Copying files...\n", files.size, files.size, 100 end def create_debian_package_dir(distribution) require 'time' variables = { :distribution => distribution } root = "#{PKG_DIR}/#{distribution}" sh "rm -rf #{root}" sh "mkdir -p #{root}" recursive_copy_files(ORIG_TARBALL_FILES.call, root) recursive_copy_files(Dir["debian.template/**/*"], root, true, variables) sh "mv #{root}/debian.template #{root}/debian" changelog = File.read("#{root}/debian/changelog") changelog = "#{DEBIAN_NAME} (#{PACKAGE_VERSION}-1~#{distribution}1) #{distribution}; urgency=low\n" + "\n" + " * Package built.\n" + "\n" + " -- #{MAINTAINER_NAME} <#{MAINTAINER_EMAIL}> #{Time.now.rfc2822}\n\n" + changelog File.open("#{root}/debian/changelog", "w") do |f| f.write(changelog) end end task 'debian:orig_tarball' do if File.exist?("#{PKG_DIR}/#{DEBIAN_NAME}.orig.tar.gz") puts "Debian orig tarball #{PKG_DIR}/#{DEBIAN_NAME}_#{PACKAGE_VERSION}.orig.tar.gz already exists." else sh "rm -rf #{PKG_DIR}/#{DEBIAN_NAME}_#{PACKAGE_VERSION}" sh "mkdir -p #{PKG_DIR}/#{DEBIAN_NAME}_#{PACKAGE_VERSION}" recursive_copy_files(ORIG_TARBALL_FILES.call, "#{PKG_DIR}/#{DEBIAN_NAME}_#{PACKAGE_VERSION}") sh "cd #{PKG_DIR} && tar -c #{DEBIAN_NAME}_#{PACKAGE_VERSION} | gzip --best > #{DEBIAN_NAME}_#{PACKAGE_VERSION}.orig.tar.gz" end end desc "Build Debian source and binary package(s) for local testing" task 'debian:dev' do sh "rm -f #{PKG_DIR}/#{DEBIAN_NAME}_#{PACKAGE_VERSION}.orig.tar.gz" Rake::Task["debian:clean"].invoke Rake::Task["debian:orig_tarball"].invoke case distro = string_option('DISTRO', 'current') when 'current' distributions = [File.read("/etc/lsb-release").scan(/^DISTRIB_CODENAME=(.+)/).first.first] when 'all' distributions = ALL_DISTRIBUTIONS else distributions = distro.split(',') end distributions.each do |distribution| create_debian_package_dir(distribution) sh "cd #{PKG_DIR}/#{distribution} && dpkg-checkbuilddeps" end distributions.each do |distribution| sh "cd #{PKG_DIR}/#{distribution} && debuild -F -us -uc" end end desc "Build Debian source packages to be uploaded to repositories" task 'debian:production' => 'debian:orig_tarball' do ALL_DISTRIBUTIONS.each do |distribution| create_debian_package_dir(distribution) sh "cd #{PKG_DIR}/#{distribution} && dpkg-checkbuilddeps" end ALL_DISTRIBUTIONS.each do |distribution| sh "cd #{PKG_DIR}/#{distribution} && debuild -S -k#{PACKAGE_SIGNING_KEY}" end end desc "Clean Debian packaging products, except for orig tarball" task 'debian:clean' do files = Dir["#{PKG_DIR}/*.{changes,build,deb,dsc,upload}"] sh "rm -f #{files.join(' ')}" sh "rm -rf #{PKG_DIR}/dev" ALL_DISTRIBUTIONS.each do |distribution| sh "rm -rf #{PKG_DIR}/#{distribution}" end sh "rm -rf #{PKG_DIR}/*.debian.tar.gz" end mizuho-0.9.19/bin/0000755000175000017500000000000012226725615012705 5ustar felixfelixmizuho-0.9.19/bin/mizuho0000755000175000017500000000643012226725615014151 0ustar felixfelix#!/usr/bin/env ruby # Copyright (c) 2008-2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib")) require 'optparse' begin require 'rubygems' rescue LoadError end require 'mizuho' require 'mizuho/generator' $KCODE = 'UTF-8' if RUBY_VERSION < '1.9' options = { :topbar => true, :attributes => [] } parser = OptionParser.new do |opts| nl = "\n" + ' ' * 37 opts.banner = "Usage: mizuho [options] INPUT" opts.separator "" opts.separator "Options:" opts.on("-c", "--comments SYSTEM", "Use a commenting system. The only#{nl}" + "supported commenting system right now is#{nl}" + "'juvia'.") do |value| if value != 'juvia' abort "The only supported commenting system right now is 'juvia'." end options[:commenting_system] = value end opts.on("--juvia-url URL", "When using Juvia as the commenting system,#{nl}" + "specify the Juvia base URL here.") do |value| options[:juvia_url] = value end opts.on("--juvia-site-key KEY", "When using Juvia as the commenting system,#{nl}" + "specify the Juvia site key here.") do |value| options[:juvia_site_key] = value end #opts.on("-m", "--multi-page", "Generate one file per chapter.") do |value| # options[:multi_page] = value #end opts.on("--icons-dir DIR", "Specify the directory in which icons#{nl}" << "should be searched. Defaults to#{nl}" << "'images/icons'.") do |value| options[:icons_dir] = value end opts.on("-a", "--attribute=ATTRIBUTE", "Define or delete document attribute. Uses#{nl}" << "same syntax as asciidoc's '-a' option.") do |value| options[:attributes] << value end opts.on("-o", "--output FILE", String, "Specify the output filename.") do |value| options[:output] = value end opts.on("--index", "Generate a full-text index.") do options[:index] = true end opts.on("--no-run", "Do not run Asciidoc. Developer option#{nl}" << "only, don't use.") do options[:no_run] = true end end begin parser.parse! rescue OptionParser::ParseError => e STDERR.puts e STDERR.puts STDERR.puts "Please see '--help' for valid options." exit 1 end begin if ARGV.empty? puts parser exit 1 else Mizuho::Generator.new(ARGV[0], options).start end rescue Mizuho::GenerationError STDERR.puts "*** ERROR" exit 2 end mizuho-0.9.19/bin/mizuho-asciidoc0000755000175000017500000000237112226725615015725 0ustar felixfelix#!/usr/bin/env ruby # Copyright (c) 2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib")) require 'mizuho' require 'mizuho/source_highlight' exec(*[Mizuho::ASCIIDOC, ARGV].flatten)mizuho-0.9.19/lib/0000755000175000017500000000000012226725615012703 5ustar felixfelixmizuho-0.9.19/lib/mizuho/0000755000175000017500000000000012226725615014216 5ustar felixfelixmizuho-0.9.19/lib/mizuho/fuzzystringmatch.rb0000644000175000017500000000454412226725615020205 0ustar felixfelix# Extracted from https://github.com/kiyoka/fuzzy-string-match # # Fuzzy String Match # # Copyright 2010 Kiyoka Nishiyama # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Mizuho class JaroWinklerPure THRESHOLD = 0.7 def getDistance( s1, s2 ) a1 = s1.split( // ) a2 = s2.split( // ) if s1.size > s2.size (max,min) = a1,a2 else (max,min) = a2,a1 end range = [ (max.size / 2 - 1), 0 ].max indexes = Array.new( min.size, -1 ) flags = Array.new( max.size, false ) matches = 0; (0 ... min.size).each { |mi| c1 = min[mi] xi = [mi - range, 0].max xn = [mi + range + 1, max.size].min (xi ... xn).each { |i| if (not flags[i]) && ( c1 == max[i] ) indexes[mi] = i flags[i] = true matches += 1 break end } } ms1 = Array.new( matches, nil ) ms2 = Array.new( matches, nil ) si = 0 (0 ... min.size).each { |i| if (indexes[i] != -1) ms1[si] = min[i] si += 1 end } si = 0 (0 ... max.size).each { |i| if flags[i] ms2[si] = max[i] si += 1 end } transpositions = 0 (0 ... ms1.size).each { |mi| if ms1[mi] != ms2[mi] transpositions += 1 end } prefix = 0 (0 ... min.size).each { |mi| if s1[mi] == s2[mi] prefix += 1 else break end } if 0 == matches 0.0 else m = matches.to_f t = (transpositions/ 2) j = ((m / s1.size) + (m / s2.size) + ((m - t) / m)) / 3.0; return j < THRESHOLD ? j : j + [0.1, 1.0 / max.size].min * prefix * (1 - j) end end end endmizuho-0.9.19/lib/mizuho/generator.rb0000644000175000017500000002452412226725615016540 0ustar felixfelix# Copyright (c) 2008-2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'nokogiri' require 'mizuho' require 'mizuho/source_highlight' require 'mizuho/id_map' require 'mizuho/utils' module Mizuho class GenerationError < StandardError end class Generator def initialize(input, options = {}) @options = options @input_file = input @output_file = options[:output] || default_output_filename(input) @id_map_file = options[:id_map] || default_id_map_filename(input) @icons_dir = options[:icons_dir] @conf_file = options[:conf_file] @attributes = options[:attributes] || [] @enable_topbar = options[:topbar] @no_run = options[:no_run] @commenting_system = options[:commenting_system] @index = options[:index] @index_filename = options[:index_filename] || default_index_filename(input) if @commenting_system == 'juvia' require_options(options, :juvia_url, :juvia_site_key) end end def start if @commenting_system @id_map = IdMap.new if File.exist?(@id_map_file) @id_map.load(@id_map_file) else warn "No ID map file, generating one (#{@id_map_file})..." end end if !@no_run self.class.run_asciidoc(@input_file, @output_file, @icons_dir, @conf_file, @attributes) end transform(@output_file) if @commenting_system @id_map.save(@id_map_file) stats = @id_map.stats if stats[:fuzzy] > 0 warn "Warning: #{stats[:fuzzy]} fuzzy ID(s)" end if stats[:orphaned] > 0 warn "Warning: #{stats[:orphaned]} unused ID(s)" end end end def self.run_asciidoc(input, output, icons_dir = nil, conf_file = nil, attributes = []) args = [ ASCIIDOC, "-b", "html5", "-a", "theme=flask", "-a", "icons", "-n" ].flatten if icons_dir args << "-a" args << "iconsdir=#{icons_dir}" end attributes.each do |attribute| args << "-a" args << attribute end if conf_file # With the splat operator we support a string and an array of strings. [*conf_file].each do |cf| args << "-f" args << cf end end args += ["-o", output, input] if !system(*args) raise GenerationError, "Asciidoc failed." end end private def default_output_filename(input) return File.dirname(input) + "/" + File.basename(input, File.extname(input)) + ".html" end def default_id_map_filename(input) return File.dirname(input) + "/" + File.basename(input, File.extname(input)) + ".idmap.txt" end def default_index_filename(input) return File.dirname(input) + "/" + File.basename(input, File.extname(input)) + ".index.sqlite3" end def warn(message) STDERR.puts(message) end def transform(filename) File.open(filename, 'r+') do |f| doc = Nokogiri.HTML(f) head = (doc / "head")[0] body = (doc / "body")[0] title = (doc / "title")[0].text header_div = (doc / "#header")[0] headers = (doc / "#content" / "h1, h2, h3, h4") head.add_child(make_node(stylesheet_tag, doc)) # Remove footer with generation timestamp. (doc / "#footer-text").remove # Add commenting balloons. if @commenting_system titles = [] headers.each do |header| if header['class'] !~ /float/ titles << header.text end end @id_map.generate_associations(titles) headers.each do |header| if header['class'] !~ /float/ titles << header.text header['data-comment-topic'] = @id_map.associations[header.text] header.add_previous_sibling(make_node(create_comment_balloon, doc)) end end end # Add top bar. if @enable_topbar body.children.first.add_previous_sibling(make_node(topbar(title), doc)) end # Add Mizuho Javascript. body.add_child(javascript_tag(doc)) # Move preamble from content area to header area. if preamble = (doc / "#preamble")[0] preamble.remove header_div.add_child(make_node(preamble, doc)) end # Create a TOC after the preamble. toc_div = add_child_and_get(header_div, %Q{
}) if @commenting_system # Add a commenting balloon to the TOC title. toc_div.add_child(make_node(create_comment_balloon, doc)) end toc_div.add_child(make_node(%Q{
Table of Contents
}, doc)) headers.each do |header| if header['class'] !~ /float/ level = header.name.scan(/\d+/).first div = add_child_and_get(toc_div, "
") link = add_child_and_get(div, "") link['href'] = '#' + header['id'] link.content = header.text end end if @enable_topbar # Add invisible spans before each header so that anchor jumps # don't hide the header behind the top bar. # http://nicolasgallagher.com/jump-links-and-viewport-positioning/ headers.each do |header| span = add_previous_sibling_and_get(header, '') span['id'] = header['data-anchor'] = header['id'] header.remove_attribute('id') end end if @index # Add docid attributes to headers. headers.each do |header| next if header['class'] =~ /float/ docid = Utils.title_to_docid(header.text) header['data-docid'] = docid.to_s header['class'] = "#{header['class']} docid-#{docid}".strip end create_search_index(headers, @index_filename) end f.rewind f.truncate(0) f.puts(doc.to_html) end end def stylesheet_tag content = %Q{\n} return content end def topbar(title) content = render_template("topbar.html") content.gsub!(/\{TITLE\}/, title) return content end def javascript_tag(doc) node = Nokogiri::XML::Node.new('script', doc) content = "" content << File.read("#{TEMPLATES_DIR}/jquery-1.7.1.min.js") << "\n" content << File.read("#{TEMPLATES_DIR}/jquery.hashchange-1.0.0.js") << "\n" content << File.read("#{TEMPLATES_DIR}/mizuho.js") << "\n" if @enable_topbar content << File.read("#{TEMPLATES_DIR}/topbar.js") << "\n" end if @commenting_system == 'juvia' content << %Q{ var JUVIA_URL = '#{@options[:juvia_url]}'; var JUVIA_SITE_KEY = '#{@options[:juvia_site_key]}'; } content << File.read("#{TEMPLATES_DIR}/juvia.js") << "\n" end node.content = content return node end def create_comment_balloon return %Q{} end def render_template(name) content = File.read("#{TEMPLATES_DIR}/#{name}") content.gsub!(/\{INLINE_IMAGE:(.*?)\.png\}/) do data = File.open("#{TEMPLATES_DIR}/#{$1}.png", "rb") do |f| f.read end data = [data].pack('m') data.gsub!("\n", "") "data:image/png;base64,#{data}" end return content end def require_options(options, *required_keys) fail = false required_keys.each do |key| if !options.has_key?(key) fail = true argument_name = '--' + key.to_s.gsub('_', '-') STDERR.puts "You must also specify #{argument_name}!" end end exit 1 if fail end # For Nokogiri 1.4.0 compatibility def make_node(html, doc) result = Nokogiri::XML::Node.new('div', doc) result.inner_html = html return result.children[0] end # For Nokogiri 1.4.0 compatibility def add_child_and_get(node, html) result = node.add_child(make_node(html, node.document)) result = result[0] if result.is_a?(Array) return result end # For Nokogiri 1.4.0 compatibility def add_previous_sibling_and_get(node, html) result = node.add_previous_sibling(make_node(html, node.document)) result = result[0] if result.is_a?(Array) return result end def gather_content(header) result = [] elem = header while true elem = elem.next_sibling if !elem || elem.name =~ /^h/i break else text = elem.text.strip if !text.empty? text.gsub!(/\r?\n/, " ") result << text end end end return result.join(" ") end def create_search_index(headers, filename) require 'sqlite3' db = SQLite3::Database.new("#{filename}.tmp") db.transaction do db.execute(%q{ CREATE VIRTUAL TABLE book USING fts4( title TEXT NOT NULL, content TEXT NOT NULL, content="", tokenize=porter ) }) db.execute(%q{ CREATE TABLE version( version INTEGER NOT NULL ) }) db.execute("INSERT INTO version VALUES(1)") db.prepare("INSERT INTO book(docid, title, content) VALUES(?, ?, ?)") do |stmt| headers.each do |header| next if header['class'] =~ /float/ title = header.text.strip docid = Utils.title_to_docid(title) content = gather_content(header) stmt.execute(docid, title, content) end end end db.execute("INSERT INTO book(book) VALUES('optimize')") db.execute("VACUUM") db.close File.rename("#{filename}.tmp", filename) rescue Exception => e File.unlink("#{filename}.tmp") rescue nil raise e end end end mizuho-0.9.19/lib/mizuho/id_map.rb0000644000175000017500000002151512226725615016000 0ustar felixfelix# Copyright (c) 2011-2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'mizuho/fuzzystringmatch' require 'mizuho/utils' module Mizuho class IdMap class AlreadyAssociatedError < StandardError end include Utils URANDOM = File.open("/dev/urandom", "rb") MATCHER = JaroWinklerPure.new BANNER = "###### Autogenerated by Mizuho, DO NOT EDIT ######\n" << "# This file maps section names to IDs so that the commenting system knows which\n" << "# comments belong to which section. Section names may be changed at will but\n" << "# IDs always stay the same, allowing one to retain old comments even if you\n" << "# rename a section.\n" << "#\n" << "# This file is autogenerated but is not a cache; you MUST NOT DELETE this\n" << "# file and you must check it into your version control system. If you lose\n" << "# this file you may lose the ability to identity old comments.\n" << "#\n" << "# Entries marked with \"fuzzy\" indicate that the section title has changed\n" << "# and that Mizuho has found an ID which appears to be associated with that\n" << "# section. You should check whether it is correct, and if not, fix it.\n\n" attr_reader :entries, :associations def initialize @entries = {} @associations = {} #@namespace = slug(File.basename(filename, File.extname(filename))) end def load(filename_or_io) @entries.clear open_io(filename_or_io, :read) do |io| fuzzy = false while true begin line = io.readline.strip if line.empty? fuzzy = false elsif line == "# fuzzy" fuzzy = true elsif line !~ /\A#/ title, id = line.split("\t=>\t", 2) add(title, id, fuzzy, false) fuzzy = false end rescue EOFError break end end end return self end def save(filename_or_io) normal, orphaned = group_and_sort_entries output = "" output << BANNER normal.each do |entry| output << "# fuzzy\n" if entry.fuzzy? output << "#{entry.title} => #{entry.id}\n" output << "\n" end if !orphaned.empty? output << "\n" output << "### These sections appear to have been removed. Please check.\n" output << "\n" orphaned.each do |entry| output << "# fuzzy\n" if entry.fuzzy? output << "#{entry.title} => #{entry.id}\n" output << "\n" end end open_io(filename_or_io, :write) do |f| f.write(output) end end def generate_associations(titles) @associations = {} # Associate exact matches. titles = titles.reject do |title| if (entry = @entries[title]) && !entry.associated? entry.associated = true @associations[title] = entry.id true else false end end # For the remaining titles, associate with moved or similar-looking entry. titles.reject! do |title| if entry = find_moved(title) @entries.delete(entry.title) @entries[title] = entry entry.title = title entry.associated = true entry.fuzzy = false @associations[title] = entry.id true else false end end # For the remaining titles, associate with similar-looking entry. titles.reject! do |title| if entry = find_similar(title) @entries.delete(entry.title) @entries[title] = entry entry.title = title entry.associated = true entry.fuzzy = true @associations[title] = entry.id true else false end end # For the remaining titles, create new entries. titles.each do |title| id = create_unique_id(title) add(title, id, false, true) @associations[title] = id end end def xassociate(title) if entry = @entries[title] if entry.associated? raise AlreadyAssociatedError, "Cannot associate an already associated title (#{title.inspect})" else entry.associated = true id = entry.id end elsif (moved_entry = find_moved(title)) || (similar_entry = find_similar(title)) if moved_entry puts "moved entry: #{title.inspect} -> #{moved_entry.title.inspect}" elsif similar_entry puts "similar entry: #{title.inspect} -> #{similar_entry.title.inspect}" end entry = (moved_entry || similar_entry) @entries.delete(entry.title) @entries[title] = entry entry.title = title entry.associated = true entry.fuzzy = true if similar_entry id = entry.id else id = create_unique_id(title) add(title, id, false, true) end return id end def add(title, id, *options) return @entries[title] = Entry.new(title, id || create_unique_id(title), *options) end def stats fuzzy = 0 orphaned = 0 @entries.each_value do |entry| fuzzy += 1 if entry.fuzzy? orphaned += 1 if !entry.associated? end return { :fuzzy => fuzzy, :orphaned => orphaned } end private # fuzzy # Whether #associate has fuzzily associated a title with this entry. # # associated # Whether #associate has associated a title with this entry. # Immediately after loading a map file, all entries are marked # as 'not associated'. class Entry < Struct.new(:title, :id, :fuzzy, :associated) alias fuzzy? fuzzy alias associated? associated def <=>(other) if (a = Utils.extract_chapter(title)) && (b = Utils.extract_chapter(other.title)) # Sort by chapter whenever possible. a[0] = Utils.chapter_to_int_array(a[0]) b[0] = Utils.chapter_to_int_array(b[0]) return a <=> b else return title <=> other.title end end end def find_moved(title) orig_chapter, orig_pure_title = extract_chapter(title) return nil if !orig_chapter # Find all possible matches. orig_chapter_digits = chapter_to_int_array(orig_chapter) matches = [] @entries.each_value do |entry| next if entry.associated? chapter, pure_title = extract_chapter(entry.title) if chapter && orig_pure_title == pure_title matches << { :chapter_digits => chapter_to_int_array(chapter), :pure_title => pure_title, :entry => entry } end end # Iterate until we find the best match. We match the chapter # digits from left to right. digit_match_index = 0 while matches.size > 1 orig_digit = orig_chapter_digits[digit_match_index] # Find closest digit in all matches. tmp = matches.min do |a, b| x = a[:chapter_digits][digit_match_index] - orig_digit y = b[:chapter_digits][digit_match_index] - orig_digit x.abs <=> y.abs end closest_digit = tmp[:chapter_digits][digit_match_index] # Filter out all matches with this digit. matches = matches.find_all do |m| m[:chapter_digits][digit_match_index] == closest_digit end # If a next iteration is necessary, we check the next digit. digit_match_index += 1 end if matches.empty? return nil else return matches[0][:entry] end end def find_similar(title) lower_title = title.downcase best_score = nil best_match = nil @entries.each_value do |entry| next if entry.associated? score = MATCHER.getDistance(entry.title.downcase, lower_title) if best_score.nil? || score > best_score best_score = score best_match = entry end end if best_score && best_score > 0.8 return best_match else return nil end end def slug(text) text = text.downcase text.gsub!(/^(\d+\.)+ /, '') text.gsub!(/[^a-z0-9\-\_]/i, '-') text.gsub!('_', '-') text.gsub!(/--+/, '-') return text end def create_unique_id(title) suffix = URANDOM.read(4).unpack('H*')[0].to_i(16).to_s(36) return "#{slug(title)}-#{suffix}" end def open_io(filename_or_io, mode, &block) if mode == :read if filename_or_io.respond_to?(:readline) yield(filename_or_io) else File.open(filename_or_io, 'r', &block) end else if filename_or_io.respond_to?(:write) yield(filename_or_io) else File.open(filename_or_io, 'w', &block) end end end def group_and_sort_entries normal = [] orphaned = [] @entries.each_value do |entry| if entry.associated? normal << entry else orphaned << entry end end normal.sort! orphaned.sort! return [normal, orphaned] end end endmizuho-0.9.19/lib/mizuho/packaging.rb0000644000175000017500000000253512226725615016474 0ustar felixfelix# Copyright (c) 2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. MIZUHO_FILES = [ "README.markdown", "LICENSE.txt", "Rakefile", "bin/*", "lib/**/*", "debian.template/**/*", "test/*", "templates/*", "asciidoc/**/*", "source-highlight/**/*" ] MIZUHO_DEBIAN_EXCLUDE_FILES = [ "Rakefile", "debian.template/**/*", "source-highlight/**/*", ] mizuho-0.9.19/lib/mizuho/source_highlight.rb0000644000175000017500000000230412226725615020071 0ustar felixfelix# Copyright (c) 2008-2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'mizuho' if !Mizuho::NATIVELY_PACKAGED ENV['PATH'] += ":" + File.join(Mizuho::SOURCE_ROOT, "source-highlight") end mizuho-0.9.19/lib/mizuho/utils.rb0000644000175000017500000000377712226725615015721 0ustar felixfelix# Copyright (c) 2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. module Mizuho module Utils extend self def self.included(klass) # When included into another class, make sure that Utils # methods are made private. public_instance_methods(false).each do |method_name| klass.send(:private, method_name) end end # Given a title with a chapter number, e.g. "6.1 Installation using tarball", # splits the two up. def extract_chapter(title) title =~ /^((\d+\.)*) (.+)$/ chapter = $1 pure_title = $3 if !chapter.nil? && !chapter.empty? && pure_title && !pure_title.empty? return [chapter, pure_title] else return nil end end def chapter_to_int_array(chapter) return chapter.split('.').map { |x| x.to_i } end def title_to_docid(title) chapter, pure_title = extract_chapter(title) p title numbers = chapter_to_int_array(chapter) result = 0 bit_offset = 0 numbers.each do |num| result = result | (num << bit_offset) bit_offset += 5 end return result end end end mizuho-0.9.19/lib/mizuho.rb0000644000175000017500000000335512226725615014551 0ustar felixfelix# Copyright (c) 2008-2013 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. module Mizuho VERSION_STRING = "0.9.19" NATIVELY_PACKAGED = false if NATIVELY_PACKAGED TEMPLATES_DIR = "/usr/share/mizuho/templates" if File.exist?("/usr/share/mizuho/asciidoc") ASCIIDOC = ["/usr/bin/python", "/usr/share/mizuho/asciidoc/asciidoc.py"] else ASCIIDOC = "/usr/bin/asciidoc" end else SOURCE_ROOT = File.expand_path(File.dirname(__FILE__) + "/..") LIBDIR = "#{SOURCE_ROOT}/lib" TEMPLATES_DIR = "#{SOURCE_ROOT}/templates" ASCIIDOC = ["python", "#{SOURCE_ROOT}/asciidoc/asciidoc.py"] if $LOAD_PATH.first != LIBDIR $LOAD_PATH.unshift(LIBDIR) $LOAD_PATH.uniq! end end end if !defined?(Mizuho::VERSION_STRING) mizuho-0.9.19/debian.template/0000755000175000017500000000000012226725615015171 5ustar felixfelixmizuho-0.9.19/debian.template/changelog0000644000175000017500000000020312226725615017036 0ustar felixfelixmizuho (0.9.15-1) precise; urgency=low * Initial packaging -- Hongli Lai Fri, 26 Apr 2013 16:39:20 +0200 mizuho-0.9.19/debian.template/compat0000644000175000017500000000000212226725615016367 0ustar felixfelix7 mizuho-0.9.19/debian.template/control.template0000644000175000017500000000154712226725615020415 0ustar felixfelixSource: mizuho Section: text Priority: extra Maintainer: Hongli Lai Build-Depends: debhelper (>= 7.0.50~), gem2deb (>= 0.2.0~), sed (>= 1.0.0) Standards-Version: 3.9.3 Homepage: https://github.com/FooBarWidget/mizuho Vcs-Git: git://github.com/FooBarWidget/mizuho.git Vcs-Browser: https://github.com/FooBarWidget/mizuho XS-Ruby-Versions: all Package: mizuho Architecture: all XB-Ruby-Versions: ${ruby:Versions} #if is_distribution?('>= precise') Depends: ${shlibs:Depends}, ${misc:Depends}, ruby | ruby-interpreter, ruby-nokogiri (>= 1.4.0), source-highlight, asciidoc (>= 8.6.0) #else Depends: ${shlibs:Depends}, ${misc:Depends}, ruby | ruby-interpreter, libnokogiri-ruby (>= 1.4.0), source-highlight #endif Description: Documentation formatting tool Converts Asciidoc input files into nicely outputted HTML, possibly one file per chapter. mizuho-0.9.19/debian.template/copyright0000644000175000017500000000344512226725615017132 0ustar felixfelixFormat: http://dep.debian.net/deps/dep5 Upstream-Name: mizuho Source: https://github.com/FooBarWidget/mizuho Files: * Copyright: 2008-2013 Hongli Lai License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Files: lib/mizuho/fuzzystringmatch.rb License: Apache Copyright: 2010 Kiyoka Nishiyama Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.mizuho-0.9.19/debian.template/mizuho.install.template0000644000175000017500000000017012226725615021704 0ustar felixfelixtemplates/* usr/share/mizuho/templates #if is_distribution?('< precise') asciidoc/* usr/share/mizuho/asciidoc #endifmizuho-0.9.19/debian.template/rules0000755000175000017500000000044512226725615016254 0ustar felixfelix#!/usr/bin/make -f export DH_VERBOSE=1 %: dh $@ --buildsystem=ruby override_dh_install: dh_install sed -i 's/NATIVELY_PACKAGED = .*/NATIVELY_PACKAGED = true/' debian/mizuho/usr/lib/ruby/vendor_ruby/mizuho.rb sed -i 's/\/usr\/bin\/env ruby/\/usr\/bin\/ruby/' debian/mizuho/usr/bin/mizuho mizuho-0.9.19/debian.template/source/0000755000175000017500000000000012226725615016471 5ustar felixfelixmizuho-0.9.19/debian.template/source/format0000644000175000017500000000001412226725615017677 0ustar felixfelix3.0 (quilt) mizuho-0.9.19/test/0000755000175000017500000000000012226725615013114 5ustar felixfelixmizuho-0.9.19/test/generator_spec.rb0000644000175000017500000000442312226725615016444 0ustar felixfelixrequire File.expand_path(File.dirname(__FILE__) + "/spec_helper") require 'mizuho/parser' describe Mizuho::Generator do describe "#determine_output_filename" do before :each do @generator = Mizuho::Generator.new("unused argument") File.should_receive(:expand_path).with(an_instance_of(String)).any_number_of_times.and_return do |value| value end end describe "if chapter ID is not given" do it "changes the input filename's extension to .html, if " << "the output filename is not given and the input " << "filename has an extension" do output = @generator.send(:determine_output_filename, "/foo/input.txt") output.should == "/foo/input.html" output = @generator.send(:determine_output_filename, "/foo/input.txt.erb") output.should == "/foo/input.txt.html" end it "appends .html to the input filename, if the output " << "filename is not given and the input filename has no " << "extension" do output = @generator.send(:determine_output_filename, "/foo/input.txt.erb/abc") output.should == "/foo/input.txt.erb/abc.html" end it "uses the given output filename, if given" do output = @generator.send(:determine_output_filename, "/foo/input.txt", "/hi.jpg") output.should == "/hi.jpg" end end describe "if chapter ID is given" do it "changes the input filename's extension to .html and " << "prepends the chapter ID to the extension, if the " << "output filename is not given" do output = @generator.send(:determine_output_filename, "/foo/input.txt", nil, "123") output.should == "/foo/input-123.html" output = @generator.send(:determine_output_filename, "/foo/input.txt.erb", nil, "123") output.should == "/foo/input.txt-123.html" end it "it prepends the chapter ID in front of the extension, " << "if the output filename is given and has an extension" do value = @generator.send(:determine_output_filename, "/foo/input.txt", "/hi.jpg", "123") value.should == "/hi-123.jpg" end it "it appends the chapter ID to the filename, if the " << "output filename is given and doesn't have an extension" do value = @generator.send(:determine_output_filename, "/foo/input.txt", "/hi", "123") value.should == "/hi-123" end end end end mizuho-0.9.19/test/id_map_spec.rb0000644000175000017500000001774112226725615015716 0ustar felixfelix# Copyright (c) 2012 Hongli Lai # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require File.expand_path(File.dirname(__FILE__) + "/spec_helper") require 'stringio' require 'mizuho/id_map' module Mizuho describe IdMap do before :each do @id_map = IdMap.new end describe "#generate_associations" do describe "if no similar titles exist in the map" do before :each do @id_map.generate_associations(["Installation", "Installation on Linux", "Configuration"]) @id1 = @id_map.associations["Installation"] @id2 = @id_map.associations["Installation on Linux"] @id3 = @id_map.associations["Configuration"] end it "returns a new unique ID" do @id1.should_not == @id2 @id1.should_not == @id3 end it "marks the entry as associated" do @id_map.entries["Installation"].should be_associated @id_map.entries["Installation on Linux"].should be_associated @id_map.entries["Configuration"].should be_associated end it "doesn't mark the corresponding entry as fuzzy" do @id_map.entries["Installation"].should_not be_fuzzy @id_map.entries["Installation on Linux"].should_not be_fuzzy @id_map.entries["Configuration"].should_not be_fuzzy end end describe "if the same title exists in the map, but with a different section number" do before :each do @entry1 = @id_map.add("1.2. Installation using a tarball", nil, false, false) @entry2 = @id_map.add("5.6. Installation using a tarball", nil, false, false) @entry3 = @id_map.add("6.0. Installation using a tarball", nil, false, false) @id_map.generate_associations(["5.4. Installation using a tarball", "2.1. Installation using a tarball"]) @id1 = @id_map.associations["5.4. Installation using a tarball"] @id2 = @id_map.associations["2.1. Installation using a tarball"] end it "associates with the title whose section number is closest to the new section number" do @id1.should == @entry2.id @id2.should == @entry1.id end it "changes the original entries' titles" do @entry1.title.should == "2.1. Installation using a tarball" @entry2.title.should == "5.4. Installation using a tarball" @entry3.title.should == "6.0. Installation using a tarball" end it "marks the corresponding entry as associated" do @entry1.should be_associated @entry2.should be_associated @entry3.should_not be_associated end it "doesn't mark the corresponding entry as fuzzy" do @entry1.should_not be_fuzzy @entry2.should_not be_fuzzy @entry3.should_not be_fuzzy end end describe "if one or more similar titles exist in the map" do before :each do @entry1 = @id_map.add("Installation using a tarball", nil, false, false) @entry2 = @id_map.add("Installation using a Linux tarball", nil, false, false) end it "associates with the most similar title and returns its ID" do @id_map.generate_associations(["Installation using tarball"]) @id3 = @id_map.associations["Installation using tarball"] @id3.should == @entry1.id @entry1.title.should == "Installation using tarball" end it "only associates with a title that hasn't been associated before" do @entry1.associated = true @id_map.generate_associations(["Installation using tarball"]) @id3 = @id_map.associations["Installation using tarball"] @id3.should == @entry2.id end it "marks the corresponding entry as associated" do @id_map.generate_associations(["Installation using tarball"]) @id_map.entries["Installation using tarball"].should be_associated end it "marks the corresponding entry as fuzzy" do @id_map.generate_associations(["Installation using tarball"]) @id_map.entries["Installation using tarball"].should be_fuzzy end end describe "if a one title has a similar match, but a later title has an exact match" do it "associates the later title with the exact match, then associates the first title with the similar match" do @id_map.add("Hello Dear World", "id-1", false, false) @id_map.add("Hallaa Dear World", "id-2", false, false) @id_map.generate_associations(["Helloo Dear World", "Hello Dear World"]) @id_map.associations["Helloo Dear World"].should == "id-2" @id_map.associations["Hello Dear World"].should == "id-1" end end specify "title matching is case-insensitive" do entry1 = @id_map.add("INSTALLATION USING A TARBALL", nil, false, false) @id_map.generate_associations(["installation using tarball"]) id = @id_map.associations["installation using tarball"] id.should == entry1.id end end describe "entries" do specify "are sortable by chapter" do array = [] array << IdMap::Entry.new('1. Extra chapter') array << IdMap::Entry.new('10. Under the hood') array << IdMap::Entry.new('2.1. Generic installation instructions') array.sort! array[0].title.should == '1. Extra chapter' array[1].title.should == '2.1. Generic installation instructions' array[2].title.should == '10. Under the hood' end end describe "loading" do before :each do @io = StringIO.new @io.puts "# This is a comment." @io.puts "" @io.puts "Installation => installation-1" @io.puts "Configuration => configuration-2" @io.puts "# fuzzy" @io.puts "Troubleshooting => troubleshooting-1" @io.rewind end it "marks all entries as 'not associated'" do @id_map.load(@io) @id_map.entries.each_value { |entry| entry.should_not be_associated } end it "works" do @id_map.load(@io) @id_map.entries.should have(3).items entry = @id_map.entries["Installation"] entry.title.should == "Installation" entry.id.should == "installation-1" entry.should_not be_fuzzy entry = @id_map.entries["Configuration"] entry.title.should == "Configuration" entry.id.should == "configuration-2" entry.should_not be_fuzzy entry = @id_map.entries["Troubleshooting"] entry.title.should == "Troubleshooting" entry.id.should == "troubleshooting-1" entry.should be_fuzzy end end describe "saving" do before :each do @io = StringIO.new @id_map.add "1. Installation", "installation-1", false, true @id_map.add "2. Configuration", "configuration-2", false, true @id_map.add "3. Troubleshooting", "troubleshooting-1", true, true @id_map.add "4. Administration", "administration-1", true, false @id_map.add "5. Uninstallation", "uninstallation-1", false, false @id_map.add "0. Introduction", "intro", false, true end it "saves all entries in alphabetical order, marks fuzzy entries as such and puts unassociated (orphaned) entries at the bottom" do @id_map.save(@io) @io.string.should == IdMap::BANNER + "0. Introduction => intro\n\n" + "1. Installation => installation-1\n\n" + "2. Configuration => configuration-2\n\n" + "# fuzzy\n" + "3. Troubleshooting => troubleshooting-1\n\n" + "\n" + "### These sections appear to have been removed. Please check.\n\n" + "# fuzzy\n" + "4. Administration => administration-1\n\n" + "5. Uninstallation => uninstallation-1\n\n" end end end end # module Mizuho mizuho-0.9.19/test/parser_spec.rb0000644000175000017500000001531012226725615015747 0ustar felixfelixrequire File.expand_path(File.dirname(__FILE__) + "/spec_helper") require 'mizuho/parser' shared_examples_for "an Asciidoc document with 3 chapters" do it "extracts the chapter contents" do @chapter_one.contents.should =~ /Chapter 1 contents/ @chapter_two.contents.should =~ /Chapter 2 contents/ end specify "the extracted chapter contents include (sub)section contents as well" do @chapter_two.contents.should =~ /Subsection/ @chapter_two.contents.should =~ /This is a subsection/ end it "doesn't HTML-escape auto-generated HTML formatting tags in the title" do @html_chapter.title.should =~ %r(Look) end it "HTML-escapes non-autogenerated HTML tags in the title" do @html_chapter.title.should =~ %r(<i>hurray</i>) end it "HTML-escapes non-HTML special characters in the title" do @html_chapter.title.should =~ %r(<3) end end describe Mizuho::Parser do it "extracts the title" do parser = generate_and_parse(%Q{ = Hello world A sample document. }) parser.title.should == "Hello world" end specify "the extracted title is not HTML escaped" do parser = generate_and_parse(%Q{ = *Look at this!* 2 < 1! A sample document. }) parser.title.should == "Look at this! 2 < 1!" end describe "construction of table of contents" do before :each do @parser = generate_and_parse(%Q{ = Hello world A sample document. == Scientists Erase Specific Memories In Mice It sounds like science fiction, but scientists say it might one day be possible to erase undesirable memories from the brain, selectively and safely. === How it works After exposing mice to emotionally powerful stimuli, such as a mild shock to their paws, the scientists then observed how well or poorly the animals subsequently recalled the particular trauma as their brain's expression of CaMKII was manipulated up and down. When the brain was made to overproduce CaMKII at the exact moment the mouse was prodded to retrieve the traumatic memory, the memory wasn't just blocked, it appeared to be fully erased. == Researchers Developing Cancer-Fighting Beer Ever picked up a cold, frosty beer on a hot summer's day and thought that it simply couldn't get any better? Well, think again. A team of researchers at Rice University in Houston is working on helping Joe Six Pack fight aging and cancer with every swill of beer. === Comment by samzenpus Thank you science! Now we just need cigarettes that cure baldness. == *Look*, non-HTML special characters <3, hurray }) @toc = @parser.table_of_contents end it "contains all headers" do @toc.should have(3).items @toc[0].title.should =~ /Scientists Erase Specific Memories In Mice/ @toc[0].children.should have(1).item @toc[0].children[0].title.should =~ /How it works/ @toc[1].title.should =~ /Researchers Developing Cancer-Fighting Beer/ @toc[1].children.should have(1).item @toc[1].children[0].title.should =~ /Comment by samzenpus/ @toc[2].title.should =~ /Look/ @toc[2].children.should be_empty end it "records the corresponding header levels" do @toc[0].level.should == 2 @toc[0].children[0].level.should == 3 @toc[1].level.should == 2 @toc[1].children[0].level.should == 3 @toc[2].level.should == 2 end it "doesn't HTML-escape auto-generated HTML formatting tags in the title" do @toc[2].title.should =~ %r(Look) end it "HTML-escapes non-autogenerated HTML tags in the title" do @toc[2].title.should =~ %r(<i>hurray</i>) end it "HTML-escapes non-HTML special characters in the title" do @toc[2].title.should =~ %r(<3) end it "prepends heading titles with a corresponding section number" do @toc[0].title.should =~ /^1\. / @toc[0].children[0].title.should =~ /^1\.1\. / @toc[1].title.should =~ /^2\. / @toc[1].children[0].title.should =~ /^2\.1\. / @toc[2].title.should =~ /^3\. / end end describe "chapter extraction" do def test_input(with_preamble) return %Q{ = Hello world #{"A preamble." if with_preamble} == Chapter 1 Chapter 1 contents. == Chapter 2 Chapter 2 contents. === Subsection This is a subsection. == *Look*, non-HTML special characters <3, hurray } end describe "when there is a premable" do before :each do @parser = generate_and_parse(test_input(true)) @chapters = @parser.chapters @chapter_one = @chapters[1] @chapter_two = @chapters[2] @html_chapter = @chapters[3] end it "consists of a preamble followed by level 2 headings" do @chapters.should have(4).items end specify "the preamble chapter has no title" do @chapters.first.title.should be_nil end it_should_behave_like "an Asciidoc document with 3 chapters" end describe "when there is no preamble" do def default_test_input return test_input(false) end before :each do @parser = generate_and_parse(test_input(false)) @chapters = @parser.chapters @chapter_one = @chapters[0] @chapter_two = @chapters[1] @html_chapter = @chapters[2] end it "consists of only level 2 headings" do @chapters.should have(3).items end it_should_behave_like "an Asciidoc document with 3 chapters" end end describe "content extraction" do describe "when there is a preamble" do before :each do @parser = generate_and_parse(%Q{ = Ruby Enterprise Edition Features Guide Today Hello world == Overview Ruby Enterprise Edition (REE) is a server-oriented distribution of the official Ruby interpreter, and includes various additional enhancements. }) end it "extracts the contents" do @parser.contents.should include("various additional enhancements.") end it "strips away the irrelevant HTML that come before the actual content" do @parser.contents.should_not include("") end end describe "when there is no preamble" do before :each do @parser = generate_and_parse(%Q{ = Ruby Enterprise Edition Features Guide == Overview Ruby Enterprise Edition (REE) is a server-oriented distribution of the official Ruby interpreter, and includes various additional enhancements. }) end it "extracts the contents" do @parser.contents.should include("various additional enhancements.") end it "strips away the irrelevant HTML that come before the actual content" do @parser.contents.should_not include("<title>") end end end it "fixes cross-chapter references when in multi-page output mode" end ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/test/spec_helper.rb�������������������������������������������������������������������0000644�0001750�0001750�00000002622�12226725615�015734� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������require File.expand_path(File.dirname(__FILE__) + "/../lib/mizuho") require 'digest/md5' require 'mizuho/generator' CACHE_DIR = "#{Mizuho::SOURCE_ROOT}/test/cache" def generate_and_parse(text) Dir.mkdir(CACHE_DIR) if !File.exist?(CACHE_DIR) # Unindent text. lines = text.split(/\r?\n/) min_indenting = nil lines.each do |line| next if line.strip.empty? line =~ /\A([\t\s]*)/ if min_indenting.nil? || $1.size < min_indenting min_indenting = $1.size end end if min_indenting lines.map! do |line| line[min_indenting..-1] end end text = lines.join("\n") output_filename = File.join(CACHE_DIR, Digest::MD5.hexdigest(text)) + ".html" # Generate Asciidoc output if it isn't cached, otherwise use cached version. # Also check whether the cache is newer than Asciidoc; we want to invalidate # the cache upon upgrading Asciidoc. if !File.exist?(output_filename) || asciidoc_newer_than?(output_filename) input_filename = File.join(CACHE_DIR, "input.#{Process.pid}.txt") begin File.open(input_filename, 'w') do |f| f.write(text) end Mizuho::Generator.run_asciidoc(input_filename, output_filename) ensure File.unlink(input_filename) rescue nil end end return Mizuho::Parser.new(output_filename) end def asciidoc_newer_than?(filename) asciidoc_mtime = File.stat("#{Mizuho::SOURCE_ROOT}/asciidoc/asciidoc.py").mtime return asciidoc_mtime > File.stat(filename).mtime end ��������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12231154732�014123� 5����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/arrow-up.png����������������������������������������������������������������0000644�0001750�0001750�00000000423�12226725615�016414� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��� ��� �����sRGB����bKGD������ pHYs�� �� ����tIME � ���"tEXtComment�Created with GIMP on a MacwC���eIDAT}K "W򀾞<]Rs68al*�!Q 6{4xlUl̺/ 5<1n֐" in?(U>W}®|,}�}}gOh<����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/balloon.png�����������������������������������������������������������������0000644�0001750�0001750�00000002446�12226725615�016275� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���$��� ���zڎ���sBIT|d��� pHYs����soz���tEXtSoftware�www.inkscape.org<��IDATXOhU?olmwKXBmQ bj)GAj{RPH٫O%wo%SXiƅvukٙy2o}yVgg}~yRJtBDhZ �j$KRӯe2R p[ 8AVeaanj�Ot0!T0ŋ'OPR@0 ÐFWܼw҅ h"@J)]._6Ϗ1ߡ.`~^kڃg~2АRBro B>H˲, ۶m{[tum`}9bqҥKI!p�k~~IucoꥎeY2CA>w<x(O,@߿t:njJwSSnJT*MOOO{�abddUu;:A)022NMMM j~ q vL�nnؼڸ{͙ H„M)`{7~8q ?5>R~0f~)S@q0@{E-e F-l`|(]AQH=: cMev(3nUZ_ ]^0qPӡ6 [(d&zӁ<'Q;_zA=|psyyysl6LL7`[?~쯬-@:@877Ñ#GM^ V&Fǩw=8 =[Cquuu@xqnnn>;H$<u6LڮZB80 yQjZJrcaaa14^XRizlll2/>L&gff(/ L&cVO\XV+;! A.[@2[7]RΝr gYs֭qhI b/SJz(0v̙;q6͍7MRܼ|g@ S dG`i {'N$M�ˋ_QixVstTի7]Cf `u/b<`/PԩSD@_OY/ҩ6Vn*e+1} mqF5]����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/balloon.svg�����������������������������������������������������������������0000644�0001750�0001750�00000013401�12226725615�016301� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="744.09448819" height="1052.3622047" id="svg2" version="1.1" inkscape:version="0.48.1 r9760" sodipodi:docname="balloon.svg" inkscape:export-filename="/Users/hongli/balloon.png" inkscape:export-xdpi="11.859613" inkscape:export-ydpi="11.859613"> <defs id="defs4"> <linearGradient id="linearGradient3829"> <stop style="stop-color:#adadad;stop-opacity:1;" offset="0" id="stop3831" /> <stop style="stop-color:#a5a5a5;stop-opacity:1;" offset="1" id="stop3833" /> </linearGradient> <linearGradient id="linearGradient3763"> <stop style="stop-color:#d3d3d3;stop-opacity:1;" offset="0" id="stop3765" /> <stop style="stop-color:#a7a7a7;stop-opacity:1;" offset="1" id="stop3767" /> </linearGradient> <linearGradient id="linearGradient3755"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3757" /> <stop style="stop-color:#b9b9b9;stop-opacity:1;" offset="1" id="stop3759" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3755" id="radialGradient3761" cx="241.01582" cy="453.14914" fx="241.01582" fy="453.14914" r="102.5" gradientTransform="matrix(0.01700775,1.83415,-3.2474978,0.02941844,1719.7046,-15.170757)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3763" id="linearGradient3769" x1="175.64285" y1="418.21936" x2="325.64285" y2="546.21936" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.19,0,0,1,-32.707142,0)" /> <filter inkscape:collect="always" id="filter3810"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.57554836" id="feGaussianBlur3812" /> </filter> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3829" id="linearGradient3835" x1="304.98007" y1="571.18542" x2="395.5" y2="571.36218" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter3886"> <feGaussianBlur inkscape:collect="always" stdDeviation="6.6075" id="feGaussianBlur3888" /> </filter> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="325.85426" inkscape:cy="645" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1323" inkscape:window-height="851" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="0" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g3843" transform="translate(5,3)" style="opacity:0.69999999999999996;fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;filter:url(#filter3886)"> <path style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-opacity:1" d="m 212.14285,389.36218 158,0 c 22.16,0 40,17.84 40,40 l 0,85.71428 c 0,22.16 -17.84,40 -40,40 l -158,0 c -22.16,0 -40,-17.84 -40,-40 l 0,-85.71428 c 0,-22.16 17.84,-40 40,-40 z" id="path3837" inkscape:connector-curvature="0" /> <path style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" d="m 364,551.86218 29,40 -91,-41" id="path3839" inkscape:connector-curvature="0" /> <rect style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1" id="rect3841" width="85.25" height="4.6035533" x="284" y="548.11218" /> </g> <path style="fill:url(#radialGradient3761);fill-opacity:1;stroke:url(#linearGradient3769);stroke-width:5;stroke-miterlimit:4;stroke-opacity:1" d="m 212.14285,389.36218 158,0 c 22.16,0 40,17.84 40,40 l 0,85.71428 c 0,22.16 -17.84,40 -40,40 l -158,0 c -22.16,0 -40,-17.84 -40,-40 l 0,-85.71428 c 0,-22.16 17.84,-40 40,-40 z" id="rect2985" /> <path style="fill:#d1d1d1;fill-opacity:1;stroke:url(#linearGradient3835);stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" d="m 364,551.86218 29,40 -91,-41" id="path3815" inkscape:connector-curvature="0" /> <rect style="fill:#d1d1d1;fill-opacity:1;stroke:none" id="rect3827" width="85.25" height="4.6035533" x="284" y="548.11218" /> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/jquery.hashchange-1.0.0.js��������������������������������������������������0000644�0001750�0001750�00000006055�12226725615�020540� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jQuery hashchange 1.0.0 * * (based on jquery.history) * * Copyright (c) 2008 Chris Leishman (chrisleishman.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. */ (function($) { $.fn.extend({ hashchange: function(callback) { this.bind('hashchange', callback) }, openOnClick: function(href) { if (href === undefined || href.length == 0) href = '#'; return this.click(function(ev) { if (href && href.charAt(0) == '#') { // execute load in separate call stack window.setTimeout(function() { $.locationHash(href) }, 0); } else { window.location(href); } ev.stopPropagation(); return false; }); } }); // IE 8 introduces the hashchange event natively - so nothing more to do if ($.browser.msie && document.documentMode && document.documentMode >= 8) { $.extend({ locationHash: function(hash) { if (!hash) hash = '#'; else if (hash.charAt(0) != '#') hash = '#' + hash; location.hash = hash; } }); return; } var curHash; // hidden iframe for IE (earlier than 8) var iframe; $.extend({ locationHash: function(hash) { if (curHash === undefined) return; if (!hash) hash = '#'; else if (hash.charAt(0) != '#') hash = '#' + hash; location.hash = hash; if (curHash == hash) return; curHash = hash; if ($.browser.msie) updateIEFrame(hash); $.event.trigger('hashchange'); } }); $(document).ready(function() { curHash = location.hash; if ($.browser.msie) { // stop the callback firing twice during init if no hash present if (curHash == '') curHash = '#'; // add hidden iframe for IE iframe = $('<iframe />').hide().get(0); $('body').prepend(iframe); updateIEFrame(location.hash); setInterval(checkHashIE, 100); } else { setInterval(checkHash, 100); } }); $(window).unload(function() { iframe = null }); function checkHash() { var hash = location.hash; if (hash != curHash) { curHash = hash; $.event.trigger('hashchange'); } } if ($.browser.msie) { // Attach a live handler for any anchor links $('a[href^=#]').live('click', function() { var hash = $(this).attr('href'); // Don't intercept the click if there is an existing anchor on the page // that matches this hash if ($(hash).length == 0 && $('a[name='+hash.slice(1)+']').length == 0) { $.locationHash(hash); return false; } }); } function checkHashIE() { // On IE, check for location.hash of iframe var idoc = iframe.contentDocument || iframe.contentWindow.document; var hash = idoc.location.hash; if (hash == '') hash = '#'; if (hash != curHash) { if (location.hash != hash) location.hash = hash; curHash = hash; $.event.trigger('hashchange'); } } function updateIEFrame(hash) { if (hash == '#') hash = ''; var idoc = iframe.contentWindow.document; idoc.open(); idoc.close(); if (idoc.location.hash != hash) idoc.location.hash = hash; } })(jQuery);�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/juvia.js��������������������������������������������������������������������0000644�0001750�0001750�00000010645�12226725615�015615� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������var disqus_identifier; var disqus_title; var disqus_url; var disqus_developer = 1; Mizuho.initializeCommenting = $.proxy(function() { var self = this; this.commentBalloons = $('.comments'); this.commentBalloons.click(function() { self.showCommentsPopup(this); }); this.reloadCommentCount(); }, Mizuho); Mizuho.showLightbox = $.proxy(function(creationCallback, closeCallback) { var lightbox = $( '<div id="comments_lightbox">' + ' <div id="comments_lightbox_shadow"></div>' + ' <div id="comments_lightbox_contents"><div class="shell"></div></div>' + '</div>'); var shadow = $('#comments_lightbox_shadow', lightbox); var contents = $('#comments_lightbox_contents > .shell', lightbox); function close() { if (lightbox) { lightbox.remove(); lightbox = undefined; if (closeCallback) { closeCallback(); } } } shadow.click(close); lightbox.bind('lightbox:close', close); lightbox.appendTo(document.body); creationCallback(contents); }, Mizuho); Mizuho.getCommentThreadInfo = $.proxy(function(balloon) { var info = {}; if ($(balloon).closest('#toc').length > 0) { info.id = 'toctitle'; info.topic = 'toctitle'; info.title = $('#header h1').text() + " - " + $('#toctitle').text(); } else { var header = $(balloon).next('h2, h3, h4'); if (header.length > 0) { info.id = header.attr('id'); info.topic = header.data('comment-topic'); info.title = $('#header h1').text() + " - " + header.text(); } else { info = undefined; } } return info; }, Mizuho); Mizuho.callJuviaApi = function(action, options) { function makeQueryString(options) { var key, params = []; for (key in options) { params.push( encodeURIComponent(key) + '=' + encodeURIComponent(options[key])); } return params.join('&'); } // Makes sure that each call generates a unique URL, otherwise // the browser may not actually perform the request. if (!('_juviaRequestCounter' in window)) { window._juviaRequestCounter = 0; } var url = JUVIA_URL + '/api/' + action + '?_c=' + window._juviaRequestCounter + '&' + makeQueryString(options); window._juviaRequestCounter++; var s = document.createElement('script'); s.async = true; s.type = 'text/javascript'; s.className = 'juvia'; s.src = url; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s); } Mizuho.showCommentsPopup = $.proxy(function(balloon) { var info = this.getCommentThreadInfo(balloon); if (!info) { return; } var self = this; this.showLightbox(function(element) { // We install a 'Close' button in the Juvia comment form after it has loaded. function installCloseButton() { if ($('#comments .juvia-form-actions').size() > 0) { // The Juvia form is now loaded. Install the button. var div = $('<div class="juvia-action" style="margin-left: 0.5em"></div>'); var button = $('<input type="button" value="Cancel"></div>').appendTo(div); div.insertBefore('#comments .juvia-form-actions .juvia-error'); button.click(function() { $(element).trigger('lightbox:close'); }); } else { // Continue polling. setTimeout(installCloseButton, 50); } } setTimeout(installCloseButton, 50); // Now load the Juvia comments form. element.html('<div id="comments">Loading comments...</div>'); self.changingHash = true; location.hash = '#!/' + info.id; self.callJuviaApi('show_topic.js', { container : '#comments', site_key : JUVIA_SITE_KEY, topic_key : info.topic, topic_url : location.href, topic_title : info.topic, include_base: !window.Juvia, include_css : !window.Juvia }); }, function() { self.reloadCommentCount(); }); }, Mizuho); Mizuho.reloadCommentCount = $.proxy(function() { this.callJuviaApi('list_topics.jsonp', { site_key: JUVIA_SITE_KEY, jsonp : 'Mizuho.topicListReceived' }); }, Mizuho); Mizuho.topicListReceived = $.proxy(function(result) { var self = this; var i, topic, map = {}; for (i = 0; i < result.topics.length; i++) { topic = result.topics[i]; map[topic.key] = topic; } this.commentBalloons.each(function() { var info = self.getCommentThreadInfo(this); if (info) { topic = map[info.topic]; if (topic) { var balloon = $(this); $('.count', balloon).text(topic.comment_count); balloon.removeClass('empty'); balloon.addClass('nonempty'); balloon.attr('title', null); } } }); }, Mizuho); $(document).ready(Mizuho.initializeCommenting); �������������������������������������������������������������������������������������������mizuho-0.9.19/templates/mizuho.css������������������������������������������������������������������0000644�0001750�0001750�00000003067�12226725615�016166� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������body { margin: 1em auto 1em auto; padding: 0 1em 0 1em; max-width: 800px; } a.image { border: none; } .comments { display: block; background: url('balloon.png') top left no-repeat; float: left; margin-left: -55px; width: 36px; height: 48px; line-height: 0; color: black; text-decoration: none !important; border: none !important; } #toc .comments { margin-top: 0.25em; } .sect1 .comments { margin-top: 0.5em; } .sect2 .comments { margin-top: 1.15em; } .sect3 .comments { margin-top: -1em; } .comments.empty { opacity: 0.2; } .comments.empty:hover, .comments.nonempty { opacity: 1; } .comments .count { display: block; font-size: 80%; padding-top: 12px; text-align: center; text-shadow: 1px 1px 2px white; } #comments_lightbox_shadow { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: black; opacity: 0.7; z-index: 10; } #comments_lightbox_contents { position: fixed; top: 10%; left: 20%; right: 20%; bottom: 10%; background: white; overflow: auto; z-index: 11; } #comments_lightbox_contents > .shell { margin: 2em; } pre { overflow: auto; } @media print { body { font-size: 18pt; } #header h1 { page-break-after: always; font-size: 500%; vertical-align: middle; } #header { page-break-after: always; } #toctitle { font-size: 200%; margin-bottom: 1em; } div.toclevel1 { font-size: 100%; } div.toclevel2 { font-size: 90%; } div.toclevel3 { font-size: 80%; } #content .comments { display: none; } @page :left { @bottom-left { content: counter(page); } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/mizuho.js�������������������������������������������������������������������0000644�0001750�0001750�00000011411�12226725615�016002� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// IE... if (!Date.now) { Date.now = function() { return new Date().getTime(); } } var Mizuho = { /** Cached DOM elements so that we don't have to re-find them over and over. */ $document: undefined, $window: undefined, $mainSections: undefined, $sectionHeaders: undefined, /** Constants */ MAX_TOC_LEVEL: 3, sectionHeadersSelector: undefined, scrollMemory: {}, changingHash: false, activeHash: undefined, /** Whether in single-page or multi-page mode. Either 'single' or 'multi'. */ mode: 'single', /** Whether smooth scrolling is enabled. It is always enabled except right * after page load: when the page is scrolled to the section as pointed to * by location.hash. */ smoothScrolling: true, initialize: function() { this.sectionHeadersSelector = ''; for (var i = 0; i < this.MAX_TOC_LEVEL; i++) { if (i != 0) { this.sectionHeadersSelector += ', '; } this.sectionHeadersSelector += 'h' + (i + 2); } this.$document = $(document); this.$window = $(window); this.$mainSections = $('.sect1'); this.$sectionHeaders = $(this.sectionHeadersSelector, '#content'); this.$sectionHeaders.sort(function(a, b) { var off_a = $(a).offset(); var off_b = $(b).offset(); return off_a.top - off_b.top; }); if (this.isMobileDevice()) { $(document.body).addClass('mobile'); } }, /********* Generic utility functions *********/ isMobileDevice: function() { return navigator.userAgent.match( /(IEMobile|Windows CE|NetFront|PlayStation|PLAYSTATION|like Mac OS X|MIDP|UP\.Browser|Symbian|Nintendo|Android)/ ); }, virtualAnimate: function(options) { var options = $.extend({ duration: 1000 }, options || {}); var animation_start = Date.now(); var animation_end = Date.now() + options.duration; var interval = animation_end - animation_start; this._virtualAnimate_step(animation_start, animation_end, interval, options); }, _virtualAnimate_step: function(animation_start, animation_end, interval, options) { var self = this; var now = new Date(); var progress = (now - animation_start) / interval; if (progress > 1) { progress = 1; } progress = (1 + Math.sin(-Math.PI / 2 + progress * Math.PI)) / 2; options.step(progress); if (now < animation_end) { setTimeout(function() { self._virtualAnimate_step(animation_start, animation_end, interval, options); }, 15); } else { options.step(1); if (options.finish) { options.finish(); } } }, smoothlyScrollTo: function(top) { if (!this.smoothScrolling) { return this.setScrollTop(top); } var self = this; var $document = this.$document; var current = $document.scrollTop(); this.virtualAnimate({ duration: 300, step: function(x) { $document.scrollTop(Math.floor( top + (1 - x) * (current - top) )); }, finish: function() { self.setScrollTop(top); } }); }, smoothlyScrollToToc: function() { this.smoothlyScrollTo($('#toc').position().top); }, scrollToHeader: function(header) { this.smoothlyScrollTo($(header).offset().top - 50); }, setScrollTop: function(top, element) { // Browsers don't always scroll properly so work around // this with a few timers. var self = this; element = element || this.$document; element = $(element); element.scrollTop(top); setTimeout(function() { element.scrollTop(top); }, 1); setTimeout(function() { element.scrollTop(top); self.$document.trigger('mizuho:updateTopBar'); }, 20); }, /********* Mizuho-specific functions *********/ /** Returns the currently displayed section's header DOM element. */ currentSubsection: function() { var $sectionHeaders = this.$sectionHeaders; var scrollTop = this.$document.scrollTop(); var windowHeight = this.$window.height(); var offset; var low = 0; var high = this.$sectionHeaders.length - 1; var mid = 0; while (low <= high) { mid = Math.floor((low + high) / 2); offset = $($sectionHeaders[mid]).offset(); if (offset.top >= scrollTop) { high = mid - 1; } else { low = mid + 1; } } var $found = $($sectionHeaders[low]); if ($found.offset().top > scrollTop + windowHeight) { if (low > 0) { return $sectionHeaders[low - 1]; } else { return undefined; } } else { return $sectionHeaders[low]; } }, /** Looks up a section's header DOM element corresponding to a hash name. */ lookupHeader: function(hash) { var id = hash.replace(/^#!\//, '#'); if (id == '') { return undefined; } else { var header = $(id); if (header.length == 0) { return undefined; } else { return header; } } } }; for (var key in Mizuho) { if (typeof(Mizuho[key]) == 'function') { Mizuho[key] = $.proxy(Mizuho[key], Mizuho); } } $(document).ready(Mizuho.initialize); //$(document).ready(Mizuho.installHashbangLinks); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/toc.html��������������������������������������������������������������������0000644�0001750�0001750�00000000000�12226725615�015574� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/topbar.css������������������������������������������������������������������0000644�0001750�0001750�00000004714�12226725615�016142� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#topbar { position: fixed; left: 0; top: 0; right: 0; height: 2.5em; padding-left: 10%; padding-right: 10%; z-index: 1; background: #880000; overflow: hidden; white-space: nowrap; box-shadow: 0px 3px 6px #555555; -moz-box-shadow: 0px 3px 6px #555555; -webkit-box-shadow: 0px 3px 6px #555555; -o-box-shadow: 0px 3px 6px #555555; } #topbar .title { display: inline-block; margin: 0.6em 1em 0 0; vertical-align: top; } #topbar .title img { display: none; margin-right: 6px; vertical-align: middle; } #topbar .title a { color: #fffafa; border: 0; } #topbar .title:hover img, .mobile #topbar .title img { display: inline-block; margin-left: -17px; } #topbar .title:hover a, .mobile #topbar .title a { color: #ffffdd; } #floattoc { position: fixed; z-index: 1; top: 2em; bottom: 20%; width: 50%; background: #f0f0f0; color: black; box-shadow: 0px 6px 6px #555555; -moz-box-shadow: 0px 6px 6px #555555; -webkit-box-shadow: 0px 6px 6px #555555; -o-box-shadow: 0px 6px 6px #555555; overflow: auto; padding: 1em; border-radius: 6px; -webkit-border-radius: 8px; -webkit-border-top-left-radius: 0; -webkit-border-top-right-radius: 0; -moz-border-radius: 8px; -moz-border-radius-topleft: 0; -moz-border-top-right-radius: 0; -o-border-radius: 8px; -o-border-radius-topleft: 0; -o-border-top-right-radius: 0; border-radius: 8px; border-top-left-radius: 0; border-top-right-radius: 0; } #floattoc a.current { font-weight: bold; color: black; } #current_section { display: inline-block; margin: 0.5em 0 0 0; padding: 0.2em 0.5em 0.2em 0.5em; background: #550000; font-size: 90%; vertical-align: top; color: white; border: none; -webkit-border-radius: 8px; -moz-border-radius: 8px; -o-border-radius: 8px; border-radius: 8px; } #current_section:hover { text-decoration: none; border: none; } #current_section.pressed { background: #f0f0f0; color: black; -webkit-border-top-left-radius: 8px; -webkit-border-top-right-radius: 8px; -webkit-border-bottom-left-radius: 0; -webkit-border-bottom-right-radius: 0; -moz-border-radius-topleft: 8px; -moz-border-radius-topright: 8px; -moz-border-bottom-left-radius: 0; -moz-border-bottom-right-radius: 0; border-top-left-radius: 8px; border-top-right-radius: 8px; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } /* http://nicolasgallagher.com/jump-links-and-viewport-positioning/ */ .anchor_helper { position: relative; display: block; top: -50px; width: 1px; height: 1px; } ����������������������������������������������������mizuho-0.9.19/templates/topbar.html�����������������������������������������������������������������0000644�0001750�0001750�00000000421�12226725615�016305� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div id="topbar" style="display: none"> <div class="title"> <img src="{INLINE_IMAGE:arrow-up.png}" width="11" height="10" alt=""> <a href="javascript:void(Mizuho.smoothlyScrollToToc())">{TITLE}</a> </div> <a href="javascript:void(0)" id="current_section"></a> </div>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/templates/topbar.js�������������������������������������������������������������������0000644�0001750�0001750�00000011561�12226725615�015764� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mizuho.initializeTopBar = $.proxy(function() { var $window = this.$window; var $document = this.$document; var self = this; var $topbar = $('#topbar'); var $title = $('#header h1'); var $currentSection = $('#current_section'); var isMobileDevice = this.isMobileDevice(); var timerId; // Create the floating table of contents used in the top bar. var $floattoc = $('<div id="floattoc"></div>').html($('#toc').html()); $floattoc.find('#toctitle').remove(); $floattoc.find('.comments').remove(); $floattoc.css('visibility', 'hidden'); $floattoc.insertAfter($topbar); var $floattoclinks = $floattoc.find('a'); $floattoclinks.each(function() { // Firefox changes '#!' to '#%21' so change that back. var $this = $(this); var href = $this.attr('href'); if (href.match(/^#%21/)) { $this.attr('href', href.replace(/^#%21/, '#!')); } }); $floattoclinks.click(function(event) { self.internalLinkClicked(this, event); }); // Callback for when the user clicks on the Table of Contents // button on the top bar. function showFloatingToc() { var scrollUpdateTimerId; function reposition() { if (isMobileDevice) { $floattoc.css({ top: $currentSection.offset().top + $currentSection.innerHeight() + 'px', height: $window.height() * 0.7 + 'px' }); } } function highlightCurrentTocEntry() { var currentSubsection = self.currentSubsection(); $floattoclinks.removeClass('current'); if (currentSubsection) { var currentSubsectionTitle = $(currentSubsection).text(); var $link; $floattoclinks.each(function() { if ($(this).text() == currentSubsectionTitle) { $link = $(this); return false; } }); if ($link) { $link.addClass('current'); self.setScrollTop( $floattoc.scrollTop() + $link.position().top - $floattoc.height() * 0.45, $floattoc); return false; } } } function hideFloatingToc() { $currentSection.removeClass('pressed'); $floattoc.css('visibility', 'hidden'); $floattoclinks.unbind('click', hideFloatingToc); $document.unbind('mousedown', onMouseDown); $document.unbind('touchdown', onMouseDown); $document.unbind('mizuho:hideTopBar', hideFloatingToc); $window.unbind('scroll', onScroll); if (scrollUpdateTimerId !== undefined) { clearTimeout(scrollUpdateTimerId); scrollUpdateTimerId = undefined; } } function onMouseDown(event) { if (event.target != $floattoc[0] && $(event.target).closest('#floattoc').length == 0) { hideFloatingToc(); } } function onScroll(event) { if (scrollUpdateTimerId === undefined) { scrollUpdateTimerId = setTimeout(function() { scrollUpdateTimerId = undefined; reposition(); highlightCurrentTocEntry(); }, 100); } } // Layout and display floating TOC. highlightCurrentTocEntry(); var origScrollTop = $document.scrollTop(); var windowWidth = $window.width(); var maxRight = windowWidth - Math.floor(windowWidth * 0.1); if ($currentSection.offset().left + $floattoc.outerWidth() > maxRight) { $floattoc.css('left', maxRight - $floattoc.outerWidth()); } else { $floattoc.css('left', $currentSection.offset().left + 'px'); } reposition(); $floattoc.css('visibility', 'visible'); $currentSection.addClass('pressed'); $floattoclinks.bind('click', hideFloatingToc); $document.bind('mousedown', onMouseDown) $document.bind('touchdown', onMouseDown); $document.bind('mizuho:hideTopBar', hideFloatingToc); $window.bind('scroll', onScroll); } // Called whenever the user scrolls. Updates the title of the // Table of Contents button in the top bar to the section that // the user is currently reading. function update() { if ($title.offset().top + $title.height() < $document.scrollTop()) { if (!$topbar.is(':visible')) { $topbar.slideDown(250); $document.trigger('mizuho:showTopBar'); } } else { if ($topbar.is(':visible')) { $topbar.slideUp(); $document.trigger('mizuho:hideTopBar'); } } if (isMobileDevice) { $topbar.css({ top: $document.scrollTop() + 'px', width: $window.width() - parseInt($topbar.css('padding-left')) - parseInt($topbar.css('padding-right')) + 'px' }); } var header = self.currentSubsection(); var name; if (header) { name = $(header).text(); } else { name = 'Preamble'; } $currentSection.text(name); } function scheduleUpdate() { if (timerId !== undefined) { return; } timerId = setTimeout(function() { timerId = undefined; update(); }, 100); } if (isMobileDevice) { // Mobile devices don't support position fixed. $topbar.css('position', 'absolute'); $floattoc.css('position', 'absolute'); } $currentSection.click(showFloatingToc); $window.scroll(scheduleUpdate); $document.bind('mizuho:updateTopBar', update); }, Mizuho); $(document).ready(Mizuho.initializeTopBar); �����������������������������������������������������������������������������������������������������������������������������������������������mizuho-0.9.19/metadata.yml��������������������������������������������������������������������������0000644�0001750�0001750�00000032177�12226725615�014452� 0����������������������������������������������������������������������������������������������������ustar �felix���������������������������felix������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- !ruby/object:Gem::Specification name: mizuho version: !ruby/object:Gem::Version version: 0.9.19 prerelease: platform: ruby authors: - Hongli Lai autorequire: bindir: bin cert_chain: [] date: 2013-05-01 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: nokogiri requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.4.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.4.0 - !ruby/object:Gem::Dependency name: sqlite3 requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' description: A documentation formatting tool. Mizuho converts Asciidoc input files into nicely outputted HTML, possibly one file per chapter. Multiple templates are supported, so you can write your own. email: software-signing@phusion.nl executables: - mizuho - mizuho-asciidoc extensions: [] extra_rdoc_files: [] files: - README.markdown - LICENSE.txt - Rakefile - bin/mizuho - bin/mizuho-asciidoc - lib/mizuho/fuzzystringmatch.rb - lib/mizuho/generator.rb - lib/mizuho/id_map.rb - lib/mizuho/packaging.rb - lib/mizuho/source_highlight.rb - lib/mizuho/utils.rb - lib/mizuho.rb - debian.template/changelog - debian.template/compat - debian.template/control.template - debian.template/copyright - debian.template/mizuho.install.template - debian.template/rules - debian.template/source/format - test/generator_spec.rb - test/id_map_spec.rb - test/parser_spec.rb - test/spec_helper.rb - templates/arrow-up.png - templates/balloon.png - templates/balloon.svg - templates/jquery-1.6.1.min.js - templates/jquery-1.7.1.min.js - templates/jquery.hashchange-1.0.0.js - templates/juvia.js - templates/mizuho.css - templates/mizuho.js - templates/toc.html - templates/topbar.css - templates/topbar.html - templates/topbar.js - asciidoc/a2x.py - asciidoc/asciidoc.conf - asciidoc/asciidoc.py - asciidoc/asciidocapi.py - asciidoc/BUGS - asciidoc/BUGS.txt - asciidoc/CHANGELOG - asciidoc/CHANGELOG.txt - asciidoc/common.aap - asciidoc/configure - asciidoc/configure.ac - asciidoc/COPYING - asciidoc/COPYRIGHT - asciidoc/dblatex/asciidoc-dblatex.sty - asciidoc/dblatex/asciidoc-dblatex.xsl - asciidoc/dblatex/dblatex-readme.txt - asciidoc/doc/a2x.1 - asciidoc/doc/a2x.1.txt - asciidoc/doc/article-docinfo.xml - asciidoc/doc/article.pdf - asciidoc/doc/article.txt - asciidoc/doc/asciidoc.1 - asciidoc/doc/asciidoc.1.txt - asciidoc/doc/asciidoc.conf - asciidoc/doc/asciidoc.dict - asciidoc/doc/asciidoc.txt - asciidoc/doc/asciidocapi.txt - asciidoc/doc/asciimathml.txt - asciidoc/doc/book-multi.txt - asciidoc/doc/book.epub - asciidoc/doc/book.txt - asciidoc/doc/customers.csv - asciidoc/doc/epub-notes.txt - asciidoc/doc/faq.txt - asciidoc/doc/latex-backend.txt - asciidoc/doc/latex-bugs.txt - asciidoc/doc/latex-filter.pdf - asciidoc/doc/latex-filter.txt - asciidoc/doc/latexmath.txt - asciidoc/doc/latexmathml.txt - asciidoc/doc/main.aap - asciidoc/doc/music-filter.pdf - asciidoc/doc/music-filter.txt - asciidoc/doc/publishing-ebooks-with-asciidoc.txt - asciidoc/doc/slidy-example.txt - asciidoc/doc/slidy.txt - asciidoc/doc/source-highlight-filter.pdf - asciidoc/doc/source-highlight-filter.txt - asciidoc/doc/testasciidoc.txt - asciidoc/docbook-xsl/asciidoc-docbook-xsl.txt - asciidoc/docbook-xsl/chunked.xsl - asciidoc/docbook-xsl/common.xsl - asciidoc/docbook-xsl/epub.xsl - asciidoc/docbook-xsl/fo.xsl - asciidoc/docbook-xsl/htmlhelp.xsl - asciidoc/docbook-xsl/manpage.xsl - asciidoc/docbook-xsl/text.xsl - asciidoc/docbook-xsl/xhtml.xsl - asciidoc/docbook45.conf - asciidoc/examples/website/a2x.1.txt - asciidoc/examples/website/asciidoc-docbook-xsl.txt - asciidoc/examples/website/asciidoc-graphviz-sample.txt - asciidoc/examples/website/asciidoc.css - asciidoc/examples/website/asciidoc.js - asciidoc/examples/website/asciidocapi.txt - asciidoc/examples/website/ASCIIMathML.js - asciidoc/examples/website/asciimathml.txt - asciidoc/examples/website/build-website.sh - asciidoc/examples/website/CHANGELOG.txt - asciidoc/examples/website/customers.csv - asciidoc/examples/website/epub-notes.txt - asciidoc/examples/website/faq.txt - asciidoc/examples/website/index.txt - asciidoc/examples/website/INSTALL.txt - asciidoc/examples/website/latex-backend.txt - asciidoc/examples/website/latex-bugs.txt - asciidoc/examples/website/latex-filter.txt - asciidoc/examples/website/LaTeXMathML.js - asciidoc/examples/website/latexmathml.txt - asciidoc/examples/website/layout1.conf - asciidoc/examples/website/layout1.css - asciidoc/examples/website/layout2.conf - asciidoc/examples/website/layout2.css - asciidoc/examples/website/main.aap - asciidoc/examples/website/manpage.txt - asciidoc/examples/website/music-filter.txt - asciidoc/examples/website/newlists.txt - asciidoc/examples/website/newtables.txt - asciidoc/examples/website/plugins.txt - asciidoc/examples/website/publishing-ebooks-with-asciidoc.txt - asciidoc/examples/website/README-website.txt - asciidoc/examples/website/README.txt - asciidoc/examples/website/slidy-example.txt - asciidoc/examples/website/slidy.txt - asciidoc/examples/website/source-highlight-filter.txt - asciidoc/examples/website/support.txt - asciidoc/examples/website/testasciidoc.txt - asciidoc/examples/website/userguide.txt - asciidoc/examples/website/version83.txt - asciidoc/examples/website/xhtml11-quirks.css - asciidoc/filters/code/code-filter-readme.txt - asciidoc/filters/code/code-filter-test.txt - asciidoc/filters/code/code-filter.conf - asciidoc/filters/code/code-filter.py - asciidoc/filters/graphviz/asciidoc-graphviz-sample.txt - asciidoc/filters/graphviz/graphviz-filter.conf - asciidoc/filters/graphviz/graphviz2png.py - asciidoc/filters/latex/latex-filter.conf - asciidoc/filters/latex/latex2png.py - asciidoc/filters/music/music-filter-test.txt - asciidoc/filters/music/music-filter.conf - asciidoc/filters/music/music2png.py - asciidoc/filters/source/source-highlight-filter-test.txt - asciidoc/filters/source/source-highlight-filter.conf - asciidoc/help.conf - asciidoc/html4.conf - asciidoc/html5.conf - asciidoc/images/highlighter.png - asciidoc/images/icons/callouts/1.png - asciidoc/images/icons/callouts/10.png - asciidoc/images/icons/callouts/11.png - asciidoc/images/icons/callouts/12.png - asciidoc/images/icons/callouts/13.png - asciidoc/images/icons/callouts/14.png - asciidoc/images/icons/callouts/15.png - asciidoc/images/icons/callouts/2.png - asciidoc/images/icons/callouts/3.png - asciidoc/images/icons/callouts/4.png - asciidoc/images/icons/callouts/5.png - asciidoc/images/icons/callouts/6.png - asciidoc/images/icons/callouts/7.png - asciidoc/images/icons/callouts/8.png - asciidoc/images/icons/callouts/9.png - asciidoc/images/icons/caution.png - asciidoc/images/icons/example.png - asciidoc/images/icons/home.png - asciidoc/images/icons/important.png - asciidoc/images/icons/next.png - asciidoc/images/icons/note.png - asciidoc/images/icons/prev.png - asciidoc/images/icons/README - asciidoc/images/icons/tip.png - asciidoc/images/icons/up.png - asciidoc/images/icons/warning.png - asciidoc/images/smallnew.png - asciidoc/images/tiger.png - asciidoc/INSTALL - asciidoc/install-sh - asciidoc/INSTALL.txt - asciidoc/javascripts/asciidoc.js - asciidoc/javascripts/ASCIIMathML.js - asciidoc/javascripts/LaTeXMathML.js - asciidoc/javascripts/slidy.js - asciidoc/javascripts/toc.js - asciidoc/lang-de.conf - asciidoc/lang-en.conf - asciidoc/lang-es.conf - asciidoc/lang-fr.conf - asciidoc/lang-hu.conf - asciidoc/lang-it.conf - asciidoc/lang-nl.conf - asciidoc/lang-pt-BR.conf - asciidoc/lang-ru.conf - asciidoc/lang-uk.conf - asciidoc/latex.conf - asciidoc/main.aap - asciidoc/Makefile.in - asciidoc/MANIFEST - asciidoc/README - asciidoc/README.txt - asciidoc/slidy.conf - asciidoc/stylesheets/asciidoc.css - asciidoc/stylesheets/docbook-xsl.css - asciidoc/stylesheets/pygments.css - asciidoc/stylesheets/slidy.css - asciidoc/stylesheets/toc2.css - asciidoc/stylesheets/xhtml11-quirks.css - asciidoc/tests/asciidocapi.py - asciidoc/tests/data/deprecated-quotes.txt - asciidoc/tests/data/filters-test.txt - asciidoc/tests/data/lang-de-man-test.txt - asciidoc/tests/data/lang-de-test.txt - asciidoc/tests/data/lang-en-man-test.txt - asciidoc/tests/data/lang-en-test.txt - asciidoc/tests/data/lang-es-man-test.txt - asciidoc/tests/data/lang-es-test.txt - asciidoc/tests/data/lang-fr-man-test.txt - asciidoc/tests/data/lang-fr-test.txt - asciidoc/tests/data/lang-hu-man-test.txt - asciidoc/tests/data/lang-hu-test.txt - asciidoc/tests/data/lang-it-man-test.txt - asciidoc/tests/data/lang-it-test.txt - asciidoc/tests/data/lang-nl-man-test.txt - asciidoc/tests/data/lang-nl-test.txt - asciidoc/tests/data/lang-pt-BR-man-test.txt - asciidoc/tests/data/lang-pt-BR-test.txt - asciidoc/tests/data/lang-ru-man-test.txt - asciidoc/tests/data/lang-ru-test.txt - asciidoc/tests/data/lang-uk-man-test.txt - asciidoc/tests/data/lang-uk-test.txt - asciidoc/tests/data/oldtables.txt - asciidoc/tests/data/rcs-id-marker-test.txt - asciidoc/tests/data/testcases.conf - asciidoc/tests/data/testcases.txt - asciidoc/tests/data/utf8-bom-test.txt - asciidoc/tests/data/utf8-examples.txt - asciidoc/tests/testasciidoc.conf - asciidoc/tests/testasciidoc.py - asciidoc/text.conf - asciidoc/themes/flask/flask.css - asciidoc/themes/volnitsky/volnitsky.css - asciidoc/vim/ftdetect/asciidoc_filetype.vim - asciidoc/vim/syntax/asciidoc.vim - asciidoc/wordpress.conf - asciidoc/xhtml11-quirks.conf - asciidoc/xhtml11.conf - source-highlight/ada.lang - source-highlight/bib.lang - source-highlight/bison.lang - source-highlight/c.lang - source-highlight/c_comment.lang - source-highlight/c_string.lang - source-highlight/caml.lang - source-highlight/changelog.lang - source-highlight/clike_vardeclaration.lang - source-highlight/cpp.lang - source-highlight/csharp.lang - source-highlight/css.lang - source-highlight/css_common.outlang - source-highlight/darwin/source-highlight - source-highlight/default.css - source-highlight/default.lang - source-highlight/default.style - source-highlight/desktop.lang - source-highlight/diff.lang - source-highlight/docbook.outlang - source-highlight/esc.outlang - source-highlight/esc.style - source-highlight/extreme_comment.lang - source-highlight/extreme_comment2.lang - source-highlight/extreme_comment3.lang - source-highlight/fixed-fortran.lang - source-highlight/flex.lang - source-highlight/fortran.lang - source-highlight/function.lang - source-highlight/glsl.lang - source-highlight/haxe.lang - source-highlight/html.lang - source-highlight/html.outlang - source-highlight/html_common.outlang - source-highlight/html_notfixed.outlang - source-highlight/html_ref.outlang - source-highlight/htmlcss.outlang - source-highlight/htmltable.outlang - source-highlight/htmltablelinenum.outlang - source-highlight/java.lang - source-highlight/javadoc.outlang - source-highlight/javascript.lang - source-highlight/key_string.lang - source-highlight/lang.map - source-highlight/langdef.lang - source-highlight/latex.lang - source-highlight/latex.outlang - source-highlight/latexcolor.outlang - source-highlight/ldap.lang - source-highlight/log.lang - source-highlight/logtalk.lang - source-highlight/lsm.lang - source-highlight/lua.lang - source-highlight/m4.lang - source-highlight/makefile.lang - source-highlight/nohilite.lang - source-highlight/number.lang - source-highlight/outlang.lang - source-highlight/outlang.map - source-highlight/pascal.lang - source-highlight/perl.lang - source-highlight/php.lang - source-highlight/postscript.lang - source-highlight/prolog.lang - source-highlight/properties.lang - source-highlight/python.lang - source-highlight/ruby.lang - source-highlight/scala.lang - source-highlight/script_comment.lang - source-highlight/sh.lang - source-highlight/slang.lang - source-highlight/sml.lang - source-highlight/source-highlight - source-highlight/spec.lang - source-highlight/sql.lang - source-highlight/style.defaults - source-highlight/style.lang - source-highlight/style2.style - source-highlight/style3.style - source-highlight/symbols.lang - source-highlight/tcl.lang - source-highlight/texinfo.outlang - source-highlight/texinfo.style - source-highlight/url.lang - source-highlight/xhtml.outlang - source-highlight/xhtml_common.outlang - source-highlight/xhtml_notfixed.outlang - source-highlight/xhtmlcss.outlang - source-highlight/xhtmltable.outlang - source-highlight/xml.lang - source-highlight/xorg.lang homepage: https://github.com/FooBarWidget/mizuho licenses: - MIT post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 1.8.25 signing_key: specification_version: 3 summary: Mizuho documentation formatting tool test_files: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������