37
lib/service/formatter/text.ex
Normal file
37
lib/service/formatter/text.ex
Normal file
@@ -0,0 +1,37 @@
|
||||
defmodule Mobilizon.Service.Formatter.Text do
|
||||
@moduledoc """
|
||||
Helps to format text blocks
|
||||
|
||||
Inspired from https://elixirforum.com/t/is-there-are-text-wrapping-library-for-elixir/21733/4
|
||||
Using the Knuth-Plass Line Wrapping Algorithm https://www.students.cs.ubc.ca/~cs-490/2015W2/lectures/Knuth.pdf
|
||||
"""
|
||||
|
||||
def quote_paragraph(string, max_line_length) do
|
||||
paragraph(string, max_line_length, "> ")
|
||||
end
|
||||
|
||||
def paragraph(string, max_line_length, prefix \\ "") do
|
||||
string
|
||||
|> String.split("\n\n", trim: true)
|
||||
|> Enum.map(&subparagraph(&1, max_line_length, prefix))
|
||||
|> Enum.join("\n#{prefix}\n")
|
||||
end
|
||||
|
||||
defp subparagraph(string, max_line_length, prefix) do
|
||||
[word | rest] = String.split(string, ~r/\s+/, trim: true)
|
||||
|
||||
lines_assemble(rest, max_line_length - String.length(prefix), String.length(word), word, [])
|
||||
|> Enum.map(&"#{prefix}#{&1}")
|
||||
|> Enum.join("\n")
|
||||
end
|
||||
|
||||
defp lines_assemble([], _, _, line, acc), do: [line | acc] |> Enum.reverse()
|
||||
|
||||
defp lines_assemble([word | rest], max, line_length, line, acc) do
|
||||
if line_length + 1 + String.length(word) > max do
|
||||
lines_assemble(rest, max, String.length(word), word, [line | acc])
|
||||
else
|
||||
lines_assemble(rest, max, line_length + 1 + String.length(word), line <> " " <> word, acc)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user