You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

118 lines
3.0 KiB

require 'squib/constants'
module Squib
#@api private
module Args
# Internal class for handling arguments
#@api private
class Typographer
def initialize(config = Conf::DEFAULTS)
%w(lsquote ldquote rsquote rdquote smart_quotes
em_dash en_dash ellipsis).each do |var|
instance_variable_set("@#{var}", config[var])
end
end
def process(str)
str = explicit_replacements(str.to_s)
str = smart_quotes(str) if @smart_quotes
str
end
def explicit_replacements(str)
[ :left_curly, :right_curly, :apostraphize,
:ellipsificate, :em_dash, :en_dash ].each do |sym|
str = each_non_tag(str) do |token|
self.method(sym).call(token)
end
end
str
end
def smart_quotes(str)
[ :single_inside_double_quote,
:right_double_quote,
:left_double_quote,
:right_single_quote,
:left_single_quote].each do |sym|
str = each_non_tag(str) do |token|
self.method(sym).call(token)
end
end
str
end
# Iterate over each non-tag for processing
# Allows us to ignore anything inside < and >
def each_non_tag(str)
full_str = ''
tag_delimit = /(<(?:(?!<).)*>)/ # use non-capturing group w/ negative lookahead
str.split(tag_delimit).each do |token|
if token.start_with? '<'
full_str << token # don't process tags
else
full_str << yield(token)
end
end
return full_str
end
# Straightforward replace
def left_curly(str)
str.gsub('``', @ldquote)
end
# Straightforward replace
def right_curly(str)
str.gsub(%{''}, @rdquote)
end
# A quote between two letters is an apostraphe
def apostraphize(str)
str.gsub(/(\w)(\')(\w)/, '\1' + @rsquote + '\3')
end
# Straightforward replace
def ellipsificate(str)
str.gsub('...', @ellipsis)
end
# Straightforward replace
def en_dash(str)
str.gsub('--', @en_dash)
end
# Straightforward replace
def em_dash(str)
str.gsub('---', @em_dash)
end
# Quote next to non-whitespace curls
def right_double_quote(str)
str.gsub(/(\S)(\")/, '\1' + @rdquote)
end
# Quote next to non-whitespace curls
def left_double_quote(str)
str.gsub(/(\")(\S)/, @ldquote + '\2')
end
# Handle the cases where a double quote is next to a single quote
def single_inside_double_quote(str)
str.gsub(/(\")(\')(\S)/, @ldquote + @lsquote + '\3')
.gsub(/(\")(\')(\S)/, '\1' + @rsquote + @rdquote)
end
# Quote next to non-whitespace curls
def right_single_quote(str)
str.gsub(/(\S)(\')/, '\1' + @rsquote)
end
# Quote next to non-whitespace curls
def left_single_quote(str)
str.gsub(/(\')(\S)/, @lsquote + '\2')
end
end
end
end