Current section
Files
Jump to
Current section
Files
lib/nldoc/spec/content.ex
defmodule NLdoc.Spec.Content do
@moduledoc """
This module provides helper functions for interpreting the content of NLdoc Spec objects.
"""
alias NLdoc.Spec.Text
@doc """
Returns true if the given text is discernible, i.e. consists anything else than whitespace or invisible characters.
If the given text is an `NLdoc.Spec` object, this function will recursively check whether any of its children
contain discernible text.
## Examples
iex> alias NLdoc.Spec.{Content, Paragraph, Text}
iex> Content.discernible_text?(
...> %Paragraph{children: [
...> %Text{text: "This is"},
...> %Text{text: " "},
...> %Text{text: "an example."},
...> ]}
...> )
true
iex> Content.discernible_text?("")
false
iex> Content.discernible_text?(%Paragraph{children: [%Text{text: " "}]})
false
"""
@spec discernible_text?(NLdoc.Spec.object() | String.t() | nil) :: boolean()
def discernible_text?(text) when is_binary(text),
# \s matches standard whitespace characters.
# \b matches a backspace character.
# \x{0085} matches Unicode character U+0085 (Next Line).
# See the tests for this module for a complete list of all these Unicode characters and what they are.
# See also https://en.wikipedia.org/wiki/Whitespace_character#Unicode
do:
String.replace(
text,
~r/[\s\b\x{0085}\x{00A0}\x{1680}\x{180E}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}\x{200A}\x{200B}\x{200C}\x{200D}\x{2028}\x{2029}\x{202F}\x{205F}\x{2060}\x{3000}\x{FEFF}]/u,
""
) != ""
def discernible_text?(%{text: text}), do: discernible_text?(text)
def discernible_text?(%{children: children}), do: Enum.any?(children, &discernible_text?/1)
def discernible_text?(_), do: false
@doc """
Returns all the text elements in a series of NLdoc Spec objects, concatenated into a single series of texts.
## Examples
iex> alias NLdoc.Spec.{Content, Paragraph, Text}
iex> Content.text(
...> %Paragraph{children: [
...> %Text{text: "This is"},
...> %Text{text: " "},
...> %Text{text: "an example."},
...> ]}
...> )
[%Text{text: "This is"}, %Text{text: " "}, %Text{text: "an example."}]
iex> Content.text([
...> %Paragraph{children: [
...> %Text{text: "This is"},
...> %Text{text: " "},
...> %Text{text: "an example."},
...> ]},
...> %Paragraph{children: [
...> %Text{text: "And this is"},
...> %Text{text: " "},
...> %Text{text: "another example."},
...> ]}
...> ])
[%Text{text: "This is"}, %Text{text: " "}, %Text{text: "an example."}, %Text{text: "And this is"}, %Text{text: " "}, %Text{text: "another example."}]
iex> Content.text(%Text{text: "Just a single text object."})
[%Text{text: "Just a single text object."}]
"""
@spec text(NLdoc.Spec.object() | [NLdoc.Spec.object()]) :: [Text.t()]
def text(text = %Text{}) do
[text]
end
def text(%{children: children}) do
text(children)
end
def text(resources) when is_list(resources) do
resources |> Enum.flat_map(&text/1)
end
end