Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

separating the helper methods #820

Merged
merged 2 commits into from
Jun 19, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lucky/html_builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Lucky::HTMLBuilder
include Lucky::AssetHelpers
include Lucky::NumberToCurrency
include Lucky::TextHelpers
include Lucky::HTMLHelpers
include Lucky::TimeHelpers
include Lucky::ForgeryProtectionHelpers
include Lucky::MountComponent
Expand Down
159 changes: 159 additions & 0 deletions src/lucky/page_helpers/html_helpers.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# These helper methods will write directly to the view.
module Lucky::HTMLHelpers
jwoertink marked this conversation as resolved.
Show resolved Hide resolved
# Shortens text after a length point and inserts content afterward
#
# **Note: This method writes HTML directly to the page. It does not return a
# String.**
#
# This is ideal if you want an action associated with shortened text, like
# "Read more".
#
# * `length` (default: `30`) will control the maximum length of the text,
# including the `omission`.
# * `omission` (default: `...`) will insert itself at the end of the
# truncated text.
# * `separator` (default: nil) is where words are cut off. This is often
# overridden to break on word boundries by setting the separator to a space
# `" "`. Keep in mind this, may cause your text to be truncated before your
# `length` value if the `length` - `omission` is before the `separator`.
# * `escape` (default: false) weather or not to HTML escape the truncated
# string.
# * `blk` (default: nil) A block to run after the text has been truncated.
# Often used to add an action to read more text, like a "Read more" link.
#
# ```crystal
# truncate("Four score and seven years ago", length: 20) do
# link "Read more", to: "#"
# end
# ```
# outputs:
# ```html
# "Four score and se...<a href="#">Read more</a>"
# ```
def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String | Nil = nil, escape : Bool = false, blk : Nil | Proc = nil) : Nil
content = truncate_text(text, length, omission, separator)
raw (escape ? HTML.escape(content) : content)
blk.call if !blk.nil? && text.size > length
end

def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String | Nil = nil, escape : Bool = true, &block : -> _) : Nil
truncate(text, length, omission, separator, escape, blk: block)
end

# Wrap phrases to make them stand out
#
# This will wrap all the phrases inside a piece of `text` specified by the
# `phrases` array. The default is to wrap each with the `<mark>` element.
# This can be customized with the `highlighter` argument.
#
# **Note: This method writes HTML directly to the page. It does not return a
# String**
#
# ```crystal
# highlight("Crystal is type-safe and compiled.", phrases: ["type-safe", "compiled"])
# ```
# outputs:
# ```html
# Crystal is <mark>type-safe</mark> and <mark>compiled</mark>.
# ```
#
# **With a custom highlighter**
#
# ```crystal
# highlight(
# "You're such a nice and attractive person.",
# phrases: ["nice", "attractive"],
# highlighter: "<strong>\\1</strong>"
# )
# ```
# outputs:
# ```html
# You're such a <strong>nice</strong> and <strong>attractive</strong> person.
# ```
def highlight(text : String, phrases : Array(String | Regex), highlighter : Proc | String = "<mark>\\1</mark>")
if text.blank? || phrases.all?(&.to_s.blank?)
raw (text || "")
else
match = phrases.map do |p|
p.is_a?(Regex) ? p.to_s : Regex.escape(p.to_s)
end.join("|")

if highlighter.is_a?(Proc)
raw text.gsub(/(#{match})(?![^<]*?>)/i, &highlighter)
else
raw text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
end
end
end

# Highlight a single phrase
#
# Exactly the same as the `highlight` that takes multiple phrases, but with a
# singular `phrase` argument for readability.
# ```
def highlight(text : String, phrases : Array(String | Regex), &block : String -> _)
highlight(text, phrases, highlighter: block)
end

def highlight(text : String, phrase : String | Regex, highlighter : Proc | String = "<mark>\\1</mark>")
phrases = [phrase] of String | Regex
highlight(text, phrases, highlighter: highlighter)
end

def highlight(text : String, phrase : String | Regex, &block : String -> _)
phrases = [phrase] of String | Regex
highlight(text, phrases, highlighter: block)
end

# Wraps text in whatever you'd like based on line breaks
#
# **Note: This method writes HTML directly to the page. It does not return a
# String**
#
# ```crystal
# simple_format("foo\n\nbar\n\nbaz") do |paragraph|
# text paragraph
# hr
# end
# ```
# outputs:
# ```html
# foo<hr>
#
# bar<hr>
#
# baz<hr>
# ```
def simple_format(text : String, &block : String -> _) : Nil
paragraphs = split_paragraphs(text)

paragraphs = [""] if paragraphs.empty?

paragraphs.each do |paragraph|
yield paragraph
raw "\n\n" unless paragraph == paragraphs.last
end
view
end

# Wraps text in paragraphs based on line breaks
#
# ```crystal
# simple_format("foo\n\nbar\n\nbaz")
# ```
# outputs:
# ```html
# <p>foo</p>
#
# <p>bar</p>
#
# <p>baz</p>
# ```
def simple_format(text : String, **html_options) : Nil
simple_format(text) do |formatted_text|
para(html_options) do
raw formatted_text
end
end
end
end
160 changes: 3 additions & 157 deletions src/lucky/page_helpers/text_helpers.cr
Original file line number Diff line number Diff line change
@@ -1,46 +1,7 @@
# These helper methods will return a `String`.
module Lucky::TextHelpers
@@_cycles = Hash(String, Cycle).new

# Shortens text after a length point and inserts content afterward
#
# **Note: This method writes HTML directly to the page. It does not return a
# String.**
#
# This is ideal if you want an action associated with shortened text, like
# "Read more".
#
# * `length` (default: `30`) will control the maximum length of the text,
# including the `omission`.
# * `omission` (default: `...`) will insert itself at the end of the
# truncated text.
# * `separator` (default: nil) is where words are cut off. This is often
# overridden to break on word boundries by setting the separator to a space
# `" "`. Keep in mind this, may cause your text to be truncated before your
# `length` value if the `length` - `omission` is before the `separator`.
# * `escape` (default: false) weather or not to HTML escape the truncated
# string.
# * `blk` (default: nil) A block to run after the text has been truncated.
# Often used to add an action to read more text, like a "Read more" link.
#
# ```crystal
# truncate("Four score and seven years ago", length: 20) do
# link "Read more", to: "#"
# end
# ```
# outputs:
# ```html
# "Four score and se...<a href="#">Read more</a>"
# ```
def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String | Nil = nil, escape : Bool = false, blk : Nil | Proc = nil) : Nil
content = truncate_text(text, length, omission, separator)
raw (escape ? HTML.escape(content) : content)
blk.call if !blk.nil? && text.size > length
end

def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String | Nil = nil, escape : Bool = true, &block : -> _) : Nil
truncate(text, length, omission, separator, escape, blk: block)
end

# Shorten text after a length point.
#
# Unlike `truncate`, this method can be used inside of other tags because it
Expand Down Expand Up @@ -69,71 +30,6 @@ module Lucky::TextHelpers
"#{text[0, stop]}#{omission}"
end

# Wrap phrases to make them stand out
#
# This will wrap all the phrases inside a piece of `text` specified by the
# `phrases` array. The default is to wrap each with the `<mark>` element.
# This can be customized with the `highlighter` argument.
#
# **Note: This method writes HTML directly to the page. It does not return a
# String**
#
# ```crystal
# highlight("Crystal is type-safe and compiled.", phrases: ["type-safe", "compiled"])
# ```
# outputs:
# ```html
# Crystal is <mark>type-safe</mark> and <mark>compiled</mark>.
# ```
#
# **With a custom highlighter**
#
# ```crystal
# highlight(
# "You're such a nice and attractive person.",
# phrases: ["nice", "attractive"],
# highlighter: "<strong>\\1</strong>"
# )
# ```
# outputs:
# ```html
# You're such a <strong>nice</strong> and <strong>attractive</strong> person.
# ```
def highlight(text : String, phrases : Array(String | Regex), highlighter : Proc | String = "<mark>\\1</mark>")
if text.blank? || phrases.all?(&.to_s.blank?)
raw (text || "")
else
match = phrases.map do |p|
p.is_a?(Regex) ? p.to_s : Regex.escape(p.to_s)
end.join("|")

if highlighter.is_a?(Proc)
raw text.gsub(/(#{match})(?![^<]*?>)/i, &highlighter)
else
raw text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
end
end
end

# Highlight a single phrase
#
# Exactly the same as the `highlight` that takes multiple phrases, but with a
# singular `phrase` argument for readability.
# ```
def highlight(text : String, phrases : Array(String | Regex), &block : String -> _)
highlight(text, phrases, highlighter: block)
end

def highlight(text : String, phrase : String | Regex, highlighter : Proc | String = "<mark>\\1</mark>")
phrases = [phrase] of String | Regex
highlight(text, phrases, highlighter: highlighter)
end

def highlight(text : String, phrase : String | Regex, &block : String -> _)
phrases = [phrase] of String | Regex
highlight(text, phrases, highlighter: block)
end

# Grab a window of longer string
#
# You'll need to specify a `phrase` to center on, either a Regex or a String.
Expand Down Expand Up @@ -188,6 +84,8 @@ module Lucky::TextHelpers
[prefix, affix, postfix].join
end

# It pluralizes `singular` unless `count` is 1. You can specify the `plural` option
# to override the chosen plural word.
def pluralize(count : Int32 | String | Nil, singular : String, plural = nil) : String
word = if (count == 1 || count =~ /^1(\.0+)?$/)
singular
Expand All @@ -205,58 +103,6 @@ module Lucky::TextHelpers
text.join(break_sequence)
end

# Wraps text in whatever you'd like based on line breaks
#
# **Note: This method writes HTML directly to the page. It does not return a
# String**
#
# ```crystal
# simple_format("foo\n\nbar\n\nbaz") do |paragraph|
# text paragraph
# hr
# end
# ```
# outputs:
# ```html
# foo<hr>
#
# bar<hr>
#
# baz<hr>
# ```
def simple_format(text : String, &block : String -> _) : Nil
paragraphs = split_paragraphs(text)

paragraphs = [""] if paragraphs.empty?

paragraphs.each do |paragraph|
yield paragraph
raw "\n\n" unless paragraph == paragraphs.last
end
view
end

# Wraps text in paragraphs based on line breaks
#
# ```crystal
# simple_format("foo\n\nbar\n\nbaz")
# ```
# outputs:
# ```html
# <p>foo</p>
#
# <p>bar</p>
#
# <p>baz</p>
# ```
def simple_format(text : String, **html_options) : Nil
simple_format(text) do |formatted_text|
para(html_options) do
raw formatted_text
end
end
end

# Creates a comma-separated sentence from the provided `Enumerable` *list*
# and appends it to the view.
#
Expand Down