Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

XML/HTML code now cleaned up using Nokogiri by default

Closes #208.
  • Loading branch information...
commit 98074e24368fa405c95cbfff217c6a5870975a5e 1 parent eb1d94b
@h3rald authored
View
3  book/text/macros/macros_core.glyph
@@ -2,7 +2,6 @@
ref_macro[
@n[add]
@desc[Adds two or more integers together.]
- @params[Two or more integer values.]
@example[=add[2\|5\|7]=]
]
@@ -227,7 +226,6 @@ Checks a string against a regular expression.
ref_macro[
@n[multiply]
@desc[Multiplies two or more integers together.]
- @params[Two or more integer values.]
@example[=add[3\|5\|9]=]
]
@@ -325,7 +323,6 @@ s/sub[This is a test string\|/a test/\|another test]
ref_macro[
@n[subtract]
@desc[Subtracts two or more integers together.]
- @params[Two or more integer values.]
@example[=add[10\|5\|2]=]
]
View
4 book/text/text_editing/code.glyph
@@ -3,7 +3,7 @@ If you're a programmer, chances are that you're going to include some source cod
Cosider the following piece of ruby code:
]
- highlight[=mediawiki|
+ highlight[=text|
def find_child(&block)
children.each do \|c\|
c.descend do \|node, level\|
@@ -14,7 +14,7 @@ def find_child(&block)
end
=]
p[It can be wrapped in a highlight macro, like so:]
- highlight[=mediawiki|
+ highlight[=text|
highlight[\=ruby\|
def find_child(&block)
children.each do \\\/\|c\\\/\|
View
7 config.yml
@@ -37,11 +37,13 @@
:extension: .html
:filter_target: html
:macro_reps: html
+ :clean_source: true
:html5:
:multifile: false
:extension: .html
:filter_target: html
:macro_reps: html5
+ :clean_source: true
:pdf:
:multifile: false
:extension: .pdf
@@ -49,11 +51,13 @@
:through: html
:generator: prince
:macro_reps: html
+ :clean_source: false
:web:
:multifile: true
:extension: .html
:filter_target: html
:macro_reps: html
+ :clean_source: true
:layout_dir: web
:layouts:
:topic: topic
@@ -64,6 +68,7 @@
:extension: .html
:filter_target: html
:macro_reps: html5
+ :clean_source: true
:layout_dir: web5
:layouts:
:topic: topic
@@ -74,6 +79,7 @@
:extension: .epub
:filter_target: html
:generator: calibre
+ :clean_source: false
:calibre:
# See options at http://calibre-ebook.com/user_manual/cli/ebook-convert-3.html
"output-profile": nook
@@ -83,6 +89,7 @@
:extension: .mobi
:filter_target: html
:generator: calibre
+ :clean_source: false
:calibre:
# See options at http://calibre-ebook.com/user_manual/cli/ebook-convert-3.html
"no-inline-toc":
View
379 lib/glyph/utils.rb
@@ -1,180 +1,207 @@
# encoding: utf-8
module Glyph
- #@since 0.4.0
- module Utils
-
- # Prints a message
- # @param [String] message the message to print
- def msg(message)
- puts message unless Glyph['system.quiet']
- end
-
- # Prints an informational message
- # @param [String] message the message to print
- def info(message)
- puts "-- #{message}" unless Glyph['system.quiet']
- end
-
- # Prints a warning
- # @param [String] message the message to print
- def warning(message)
- puts "-> warning: #{message}" unless Glyph['system.quiet']
- end
-
- # Prints an error
- # @param [String] message the message to print
- def error(message)
- puts "=> error: #{message}" unless Glyph['system.quiet']
- end
-
- # Prints a message if running in debug mode
- # @param [String] message the message to print
- def debug(message)
- puts message if Glyph.debug?
- end
-
- # Dumps and serialize an object to a YAML file
- # @param [#to_s] file the file to write to
- # @param [Object] obj the object to serialize
- def yaml_dump(file, obj)
- File.open(file.to_s, 'w+') {|f| f.write obj.to_yaml}
- end
-
- # Loads and deserialiaze the contents of a YAML file
- # @param [#to_s] file the YAML file to load
- # @return [Object] the contents of the YAML file, deserialized
- def yaml_load(file)
- YAML.load_file(file.to_s)
- end
-
- # Loads the contents of a file
- # @param [#to_s] file the file to load
- # @return [String] the contents of the file
- def file_load(file)
- result = ""
- File.open(file.to_s, 'r:utf-8') do |f|
- while l = f.gets
- result << l
- end
- end
- result
- end
-
- # Writes a string to a file
- # @param [#to_s] file the file to write
- # @param [String] contents the string to write
- # @return [String] the string written to the file
- def file_write(file, contents="")
- File.open(file.to_s, 'w+:utf-8') do |f|
- f.print contents
- end
- contents
- end
-
- # An alias for FileUtils#cp
- # @param [String] source the source file
- # @param [String] dest the destination file or directory
- # @param [Hash] options copy options
- def file_copy(source, dest, options={})
- FileUtils.cp source, dest, options
- end
-
- # Loads all child elements of the given directory, matching a given extension
- # @param [Pathname] dir the directory containing the files
- # @param [String] extension the file extension to check
- # @yield [file, contents] the file (Pathname) and its contents
- # @since 0.4.0
- def load_files_from_dir(dir, extension, &block)
- if dir.exist? then
- dir.children.each do |c|
- block.call(c, file_load(c)) unless c.directory? || c.extname != extension
- end
- end
- end
-
- # Iterates through the files in a source directory recursively
- # @param [String] dir the directory to operate on (mirrored in the output directory)
- # @yield [src, dest] the source file and the corresponding output file
- # @since 0.4.0
- def with_files_from(dir, &block)
- output = complex_output? ? 'tmp' : Glyph['document.output']
- dir_path = Glyph::PROJECT/"output/#{output}/#{dir}"
- dir_path.mkpath
- (Glyph::PROJECT/dir).find do |i|
- if i.file? then
- dest = "#{Glyph::PROJECT/"output/#{output}/#{dir}"}/#{i.relative_path_from(Glyph::PROJECT/dir)}"
- src = i.to_s
- Pathname.new(dest).parent.mkpath
- block.call src, dest
- end
- end
- end
-
- # Returns true if Glyph['document.output'] requires two or more conversions
- # @since 0.5.0
- def complex_output?
- out = Glyph['document.output']
- !Glyph["output.#{out}.generator"].blank? || !Glyph["output.#{out}.through"].blank?
- end
-
- # Returns true if the macro name is used as an alias
- # @param [String, Symbol] name the macro name to check
- def macro_alias?(name)
- ALIASES[:by_alias].include? name.to_sym
- end
-
- # Returns the name of the macro definition referenced by the supplied alias
- # @param [String, Symbol] name the alias name to check
- def macro_definition_for(name)
- ALIASES[:by_alias][name.to_sym]
- end
-
- # Returns the names of the macro aliases referencing the supplied definition
- # @param [String, Symbol] name the macro name to check
- def macro_aliases_for(name)
- ALIASES[:by_def][name.to_sym]
- end
-
- # Returns a list of macro names corresponding to sections
- # that commonly have a title
- def titled_sections
- (Glyph['system.structure.frontmatter']+
- Glyph['system.structure.bodymatter']+
- Glyph['system.structure.backmatter']+
- Glyph.macro_aliases_for(:section)+
- [:section]).uniq
- end
-
- # Returns true if the macro names point to the same definition
- # @param [String, Symbol] ident1 the first macro to compare
- # @param [String, Symbol] ident2 the second macro to compare
- def macro_eq?(ident1, ident2)
- Glyph::MACROS[ident1.to_sym] == Glyph::MACROS[ident2.to_sym]
- end
-
- # Returns true if the PROJECT constant is set to a valid Glyph project directory
- def project?
- children = ["text", "config.yml", "document.glyph"].sort
- actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
- (actual_children & children) == children
- end
-
- # Returns true if multiple output files are being generated
- def multiple_output_files?
- Glyph["output.#{Glyph['document.output']}.multifile"]
- end
-
- # Execute an external command
- # @since 0.5.0
- def run_external_command(cmd)
- IO.popen(cmd+" 2>&1") do |pipe|
- pipe.sync = true
- while str = pipe.gets do
- puts str
- end
- end
- end
-
- end
+ #@since 0.4.0
+ module Utils
+
+ # Prints a message
+ # @param [String] message the message to print
+ def msg(message)
+ puts message unless Glyph['system.quiet']
+ end
+
+ # Prints an informational message
+ # @param [String] message the message to print
+ def info(message)
+ puts "-- #{message}" unless Glyph['system.quiet']
+ end
+
+ # Prints a warning
+ # @param [String] message the message to print
+ def warning(message)
+ puts "-> warning: #{message}" unless Glyph['system.quiet']
+ end
+
+ # Prints an error
+ # @param [String] message the message to print
+ def error(message)
+ puts "=> error: #{message}" unless Glyph['system.quiet']
+ end
+
+ # Prints a message if running in debug mode
+ # @param [String] message the message to print
+ def debug(message)
+ puts message if Glyph.debug?
+ end
+
+ # Dumps and serialize an object to a YAML file
+ # @param [#to_s] file the file to write to
+ # @param [Object] obj the object to serialize
+ def yaml_dump(file, obj)
+ File.open(file.to_s, 'w+') {|f| f.write obj.to_yaml}
+ end
+
+ # Loads and deserialiaze the contents of a YAML file
+ # @param [#to_s] file the YAML file to load
+ # @return [Object] the contents of the YAML file, deserialized
+ def yaml_load(file)
+ YAML.load_file(file.to_s)
+ end
+
+ # Loads the contents of a file
+ # @param [#to_s] file the file to load
+ # @return [String] the contents of the file
+ def file_load(file)
+ result = ""
+ File.open(file.to_s, 'r:utf-8') do |f|
+ while l = f.gets
+ result << l
+ end
+ end
+ result
+ end
+
+ # Writes a string to a file
+ # @param [#to_s] file the file to write
+ # @param [String] contents the string to write
+ # @return [String] the string written to the file
+ def file_write(file, contents="")
+ File.open(file.to_s, 'w+:utf-8') do |f|
+ f.print contents
+ end
+ contents
+ end
+
+ # An alias for FileUtils#cp
+ # @param [String] source the source file
+ # @param [String] dest the destination file or directory
+ # @param [Hash] options copy options
+ def file_copy(source, dest, options={})
+ FileUtils.cp source, dest, options
+ end
+
+ # Loads all child elements of the given directory, matching a given extension
+ # @param [Pathname] dir the directory containing the files
+ # @param [String] extension the file extension to check
+ # @yield [file, contents] the file (Pathname) and its contents
+ # @since 0.4.0
+ def load_files_from_dir(dir, extension, &block)
+ if dir.exist? then
+ dir.children.each do |c|
+ block.call(c, file_load(c)) unless c.directory? || c.extname != extension
+ end
+ end
+ end
+
+ # Iterates through the files in a source directory recursively
+ # @param [String] dir the directory to operate on (mirrored in the output directory)
+ # @yield [src, dest] the source file and the corresponding output file
+ # @since 0.4.0
+ def with_files_from(dir, &block)
+ output = complex_output? ? 'tmp' : Glyph['document.output']
+ dir_path = Glyph::PROJECT/"output/#{output}/#{dir}"
+ dir_path.mkpath
+ (Glyph::PROJECT/dir).find do |i|
+ if i.file? then
+ dest = "#{Glyph::PROJECT/"output/#{output}/#{dir}"}/#{i.relative_path_from(Glyph::PROJECT/dir)}"
+ src = i.to_s
+ Pathname.new(dest).parent.mkpath
+ block.call src, dest
+ end
+ end
+ end
+
+ # Returns the value of a setting referred to the current output format
+ # @param [String, Symbol] the name of the setting to retrieve
+ # @since 0.6.0
+ def current_output_setting(setting)
+ Glyph["output.#{Glyph['document.output']}.#{setting}"]
+ end
+
+ # Returns true if Glyph['document.output'] requires two or more conversions
+ # @since 0.5.0
+ def complex_output?
+ out = Glyph['document.output']
+ !Glyph["output.#{out}.generator"].blank? || !Glyph["output.#{out}.through"].blank?
+ end
+
+ # Returns true if the macro name is used as an alias
+ # @param [String, Symbol] name the macro name to check
+ def macro_alias?(name)
+ ALIASES[:by_alias].include? name.to_sym
+ end
+
+ # Returns the name of the macro definition referenced by the supplied alias
+ # @param [String, Symbol] name the alias name to check
+ def macro_definition_for(name)
+ ALIASES[:by_alias][name.to_sym]
+ end
+
+ # Returns the names of the macro aliases referencing the supplied definition
+ # @param [String, Symbol] name the macro name to check
+ def macro_aliases_for(name)
+ ALIASES[:by_def][name.to_sym]
+ end
+
+ # Returns a list of macro names corresponding to sections
+ # that commonly have a title
+ def titled_sections
+ (Glyph['system.structure.frontmatter']+
+ Glyph['system.structure.bodymatter']+
+ Glyph['system.structure.backmatter']+
+ Glyph.macro_aliases_for(:section)+
+ [:section]).uniq
+ end
+
+ # Returns true if the macro names point to the same definition
+ # @param [String, Symbol] ident1 the first macro to compare
+ # @param [String, Symbol] ident2 the second macro to compare
+ def macro_eq?(ident1, ident2)
+ Glyph::MACROS[ident1.to_sym] == Glyph::MACROS[ident2.to_sym]
+ end
+
+ # Returns true if the PROJECT constant is set to a valid Glyph project directory
+ def project?
+ children = ["text", "config.yml", "document.glyph"].sort
+ actual_children = PROJECT.children.map{|c| c.basename.to_s}.sort
+ (actual_children & children) == children
+ end
+
+ # Returns true if multiple output files are being generated
+ def multiple_output_files?
+ Glyph["output.#{Glyph['document.output']}.multifile"]
+ end
+
+ # Execute an external command
+ # @since 0.5.0
+ def run_external_command(cmd)
+ IO.popen(cmd+" 2>&1") do |pipe|
+ pipe.sync = true
+ while str = pipe.gets do
+ puts str
+ end
+ end
+ end
+
+ # Re-indents source code and removes unnecessary spacing
+ # @param [String] the XML document to clean up
+ # @since 0.6.0
+ def clean_xml_document(doc)
+ return doc unless current_output_setting :clean_source
+ begin
+ require 'nokogiri'
+ rescue Exception
+ warning "Cannot clean source because Nokogiri is not installed. Please run: gem install nokogiri"
+ return doc
+ end
+ begin
+ Nokogiri.XML(doc.to_s, &:noblanks).to_xml :indent => 2
+ rescue Exception => e
+ warning "Unable to clean up source"
+ debug e.message
+ debug e.backtrace.join("\n")
+ doc
+ end
+ end
+ end
end
View
8 spec/lib/commands_spec.rb
@@ -149,7 +149,7 @@
Pathname.new('article.html').exist?.should == true
file_load('article.html').gsub(/\t|\n/, '').should == %{
<div class="section">
- 改善 Test -- Test Snippet
+ &#25913;&#21892; Test -- Test Snippet
</div>
}.gsub(/\t|\n/, '')
(Glyph::PROJECT/'article.html').unlink
@@ -184,11 +184,7 @@
err = "Document cannot be finalized due to previous errors"
res = run_command(["compile"])
out = file_load Glyph::PROJECT/'output/html/test_project.html'
- out.should == %{<div class="section">
-<h2 id="h_1">Test</h2>
-
-
-</div>}
+ out.gsub(/\t|\n/, '').should == %{<div class="section"> <h2 id="h_1">Test</h2></div>}
res.match("error: #{err}").should == nil
end
View
8 spec/macros/web5_spec.rb
@@ -24,9 +24,9 @@
it "navigation" do
Glyph.run! 'generate:web5'
- web1 = Glyph.file_load(Glyph::PROJECT/'output/web5/a/web1.html')
- web2 = Glyph.file_load(Glyph::PROJECT/'output/web5/a/b/web2.html')
- web1.match(%{<nav> | <a href="/index.html">Contents</a> | <a href="/a/b/web2.html">&rarr; Topic #2</a></nav>}).blank?.should == false
- web2.match(%{<nav><a href="/a/web1.html">Topic #1</a> | <a href="/index.html">Contents</a> | </nav>}).blank?.should == false
+ web1 = Glyph.file_load(Glyph::PROJECT/'output/web5/a/web1.html').gsub(/\n|\t| /, '')
+ web2 = Glyph.file_load(Glyph::PROJECT/'output/web5/a/b/web2.html').gsub(/\n|\t| /, '')
+ web1.should match(%{<nav>|<a href="/index.html">Contents</a>|<a href="/a/b/web2.html">&rarr; Topic #2</a></nav>})
+ web2.should match(%{<nav><a href="/a/web1.html">Topic #1</a>|<a href="/index.html">Contents</a>|</nav>})
end
end
View
6 spec/macros/web_spec.rb
@@ -31,8 +31,8 @@
it "navigation" do
Glyph.run! 'generate:web'
- web1 = Glyph.file_load(Glyph::PROJECT/'output/web/a/web1.html')
- web2 = Glyph.file_load(Glyph::PROJECT/'output/web/a/b/web2.html')
+ web1 = Glyph.file_load(Glyph::PROJECT/'output/web/a/web1.html').gsub /\n|\t/, ''
+ web2 = Glyph.file_load(Glyph::PROJECT/'output/web/a/b/web2.html').gsub /\n|\t/, ''
web1.match(%{<div class="navigation"> | <a href="/index.html">Contents</a> | <a href="/a/b/web2.html">Topic #2</a></div>}).blank?.should == false
web2.match(%{<div class="navigation"><a href="/a/web1.html">Topic #1</a> | <a href="/index.html">Contents</a> | </div>}).blank?.should == false
end
@@ -50,7 +50,7 @@
create_web_project
Glyph['document.output'] = 'html'
Glyph.run! 'generate:html'
- index = Glyph.file_load(Glyph::PROJECT/'output/html/test_project.html')
+ index = Glyph.file_load(Glyph::PROJECT/'output/html/test_project.html').gsub /\n|\t| | /, ''
index.should match(%{<li class="section"><a href="#h_3">Topic #1</a></li><li><ol><li class="section"><a href="#h_4">Test #1a</a></li>})
index.match(%{href="a/web1.html#h_3"}).blank?.should == true
index.match(%{href="a/b/web2.html#h_7"}).blank?.should == true
View
2  spec/tasks/generate_spec.rb
@@ -104,7 +104,7 @@
# check that index.html is created
index = (Glyph::PROJECT/'output/web/index.html')
index.exist?.should == true
- file_load(index).should match(/<li class="section"><a href="\/test\/a\/b\/web2.html#h_7">Topic #2<\/a>/)
+ file_load(index).gsub(/\n|\t| /, '').should match(/<li class="section"><a href="\/test\/a\/b\/web2.html#h_7">Topic #2<\/a>/)
# check that topics are copied in the proper directories
web1 = (Glyph::PROJECT/'output/web/a/web1.html')
web1.exist?.should == true
View
6 tasks/generate.rake
@@ -70,7 +70,7 @@ namespace :generate do
file = "#{Glyph['document.filename']}#{extension}"
end
out.mkpath
- file_write out/file, Glyph.document.output
+ file_write out/file, clean_xml_document(Glyph.document.output)
info "'#{file}' generated successfully."
end
@@ -133,7 +133,7 @@ namespace :generate do
Glyph['system.quiet'] = true
index_topic = Glyph::Interpreter.new("layout/#{index_layout}[]", context).document.output
Glyph['system.quiet'] = q
- file_write out/"index.html", index_topic
+ file_write out/"index.html", clean_xml_document(index_topic)
# Generate all topics
Glyph.document.topics.each do |topic|
extension = "#{Glyph["output.#{Glyph['document.output']}.extension"]}"
@@ -141,7 +141,7 @@ namespace :generate do
file += extension unless file.match /#{Regexp.escape(extension)}$/
info "Generating topic '#{file}'"
(out/file).parent.mkpath
- file_write out/file, topic[:contents]
+ file_write out/file, clean_xml_document(topic[:contents])
end
info "Web output generated successfully."
end
Please sign in to comment.
Something went wrong with that request. Please try again.