///|
pub(all) struct DocumentStats {
element_count : Int
block_count : Int
text_count : Int
image_slot_count : Int
text_characters : Int
occupied_area : Int
ids : Array[String]
} derive(Debug, Eq)
///|
pub fn DocumentStats::empty() -> DocumentStats {
{
element_count: 0,
block_count: 0,
text_count: 0,
image_slot_count: 0,
text_characters: 0,
occupied_area: 0,
ids: [],
}
}
///|
fn append_id(ids : Array[String], id : String) -> Array[String] {
let result = ids.copy()
result.push(id)
result
}
///|
pub fn analyze_document(document : PosterDocument) -> DocumentStats {
document.elements.fold(init=DocumentStats::empty(), (stats, element) => {
match element {
Block(id~, rect~, fill=_, radius=_) =>
{
..stats,
element_count: stats.element_count + 1,
block_count: stats.block_count + 1,
occupied_area: stats.occupied_area +
Int::max(rect.width, 0) * Int::max(rect.height, 0),
ids: append_id(stats.ids, id),
}
Text(id~, content~, position=_, style=_, max_width=_) =>
{
..stats,
element_count: stats.element_count + 1,
text_count: stats.text_count + 1,
text_characters: stats.text_characters + content.char_length(),
ids: append_id(stats.ids, id),
}
ImageSlot(id~, asset_id=_, rect~, label~, fit=_) =>
{
..stats,
element_count: stats.element_count + 1,
image_slot_count: stats.image_slot_count + 1,
occupied_area: stats.occupied_area +
Int::max(rect.width, 0) * Int::max(rect.height, 0),
text_characters: stats.text_characters + label.char_length(),
ids: append_id(stats.ids, id),
}
}
})
}
///|
pub fn text_character_count(document : PosterDocument) -> Int {
analyze_document(document).text_characters
}
///|
pub fn image_slot_count(document : PosterDocument) -> Int {
analyze_document(document).image_slot_count
}
///|
fn find_element_at(
elements : Array[Element],
index : Int,
id : String,
) -> Element? {
if index >= elements.length() {
None
} else if element_id(elements[index]) == id {
Some(elements[index])
} else {
find_element_at(elements, index + 1, id)
}
}
///|
pub fn find_element(document : PosterDocument, id : String) -> Element? {
find_element_at(document.elements, 0, id)
}
///|
pub fn element_ids_sorted(document : PosterDocument) -> Array[String] {
let ids = element_ids(document)
for i = 0; i < ids.length(); i = i + 1 {
for j = i + 1; j < ids.length(); j = j + 1 {
if String::lexical_compare(ids[i], ids[j]) > 0 {
let value = ids[i]
ids[i] = ids[j]
ids[j] = value
}
}
}
ids
}