///|
fn collapse_spaces(value : String) -> String {
let output = StringBuilder()
let mut previous_space = false
for char in value {
if char == ' ' || char == '\n' || char == '\r' || char == '\t' {
if !previous_space {
output.write_char(' ')
}
previous_space = true
} else {
output.write_char(char)
previous_space = false
}
}
output.to_string().trim().to_owned()
}
///|
pub fn normalize_narrative(value : String) -> String {
collapse_spaces(value)
}
///|
pub fn narrative_text(value : Json) -> String? {
match query_text(value, "text.div", fallback="") {
"" =>
match query_text(value, "text.status", fallback="") {
"" => None
status => Some(status)
}
div => Some(div)
}
}
///|
pub fn resource_narrative(value : Json) -> String? {
narrative_text(value).map(normalize_narrative)
}
///|
pub fn resource_has_narrative(value : Json) -> Bool {
resource_narrative(value) is Some(_)
}
///|
pub fn narrative_word_count(value : String) -> Int {
normalize_narrative(value)
.split(" ")
.map(fn(part) { part.to_owned() })
.filter(fn(part) { part != "" })
.to_array()
.length()
}
///|
pub fn narrative_character_count(value : String) -> Int {
normalize_narrative(value).length()
}
///|
pub fn narrative_preview(value : String, limit : Int) -> String {
let normalized = normalize_narrative(value)
if limit <= 0 || normalized.length() <= limit {
normalized
} else {
normalized[0:limit].to_owned() + "..."
}
}
///|
pub fn strip_html_tags(value : String) -> String {
let output = StringBuilder()
let mut inside = false
for char in value {
if char == '<' {
inside = true
} else if char == '>' {
inside = false
} else if !inside {
output.write_char(char)
}
}
output.to_string()
}
///|
pub fn narrative_plain_text(value : String) -> String {
normalize_narrative(strip_html_tags(value))
}
///|
pub fn narrative_contains(value : String, query : String) -> Bool {
narrative_plain_text(value).to_lower().contains(query.to_lower())
}
///|
pub fn resources_with_narrative(values : Array[Json]) -> Array[Json] {
values.filter(fn(value) { resource_has_narrative(value) })
}
///|
pub fn narrative_coverage(values : Array[Json]) -> Int {
if values.length() == 0 {
100
} else {
resources_with_narrative(values).length() * 100 / values.length()
}
}