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
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 |