Rename the "Table" type to "List" everywhere (#4133)

* Rename the "Table" type to "List" everywhere

* Fix a few missed ones

* Re-save demo artwork
This commit is contained in:
Keavon Chambers
2026-05-09 01:33:39 -07:00
committed by GitHub
parent 6b3e4757de
commit a28b9437aa
79 changed files with 1571 additions and 1591 deletions

View File

@@ -1,4 +1,4 @@
use core_types::table::{Item, Table};
use core_types::list::{Item, List};
use core_types::{ATTR_TYPE, Ctx};
use serde_json::Value;
@@ -240,10 +240,10 @@ fn query_json_all(
/// Strips the surrounding double quotes from string values, returning the raw text. Other types are never wrapped in quotes.
#[default(true)]
unquote_strings: bool,
) -> Table<String> {
) -> List<String> {
let cleaned = strip_trailing_commas(&json);
let Ok(value): Result<Value, _> = serde_json::from_str(&cleaned) else { return Table::new() };
let Some(segments) = parse_json_path(path.trim()) else { return Table::new() };
let Ok(value): Result<Value, _> = serde_json::from_str(&cleaned) else { return List::new() };
let Some(segments) = parse_json_path(path.trim()) else { return List::new() };
let mut results = Vec::new();
resolve_all(&value, &segments, !unquote_strings, &mut results);

View File

@@ -7,8 +7,8 @@ mod to_path;
use convert_case::{Boundary, Converter, pattern};
use core_types::graphene_hash::CacheHash;
use core_types::list::{Item, List};
use core_types::registry::types::{SignedInteger, TextArea};
use core_types::table::{Item, Table};
use core_types::{CloneVarArgs, Context, Ctx, ExtractAll, ExtractVarArgs, OwnedContextImpl};
use dyn_any::DynAny;
use glam::{DAffine2, DVec2};
@@ -737,7 +737,7 @@ fn string_split(
/// "\n" (newline), "\r" (carriage return), "\t" (tab), "\0" (null), and "\\" (backslash).
#[default(true)]
delimiter_escaping: bool,
) -> Table<String> {
) -> List<String> {
let delimiter = if delimiter_escaping { unescape_string(delimiter) } else { delimiter };
string.split(&delimiter).map(str::to_string).map(Item::new_from_element).collect()
@@ -750,7 +750,7 @@ fn string_split(
fn string_join(
_: impl Ctx,
/// The list of strings to join together.
strings: Table<String>,
strings: List<String>,
/// The text placed between each pair of strings.
#[default(", ")]
separator: String,
@@ -768,12 +768,12 @@ fn string_join(
#[node_macro::node(category("Text"))]
async fn map_string(
ctx: impl Ctx + CloneVarArgs + ExtractAll,
strings: Table<String>,
strings: List<String>,
#[expose]
#[implementations(Context -> String)]
mapped: impl Node<Context<'static>, Output = String>,
) -> Table<String> {
let mut result = Table::new();
) -> List<String> {
let mut result = List::new();
for (i, row) in strings.into_iter().enumerate() {
let string = row.into_element();

View File

@@ -1,4 +1,4 @@
use core_types::table::{Item, Table};
use core_types::list::{Item, List};
use core_types::{ATTR_EDITOR_CLICK_TARGET, ATTR_EDITOR_TEXT_FRAME, ATTR_TRANSFORM};
use glam::{DAffine2, DVec2};
use parley::GlyphRun;
@@ -14,7 +14,7 @@ pub struct PathBuilder {
current_subpath: Subpath<PointId>,
origin: DVec2,
glyph_subpaths: Vec<Subpath<PointId>>,
pub vector_table: Table<Vector>,
pub vector_list: List<Vector>,
/// Per-glyph AABBs collected in single-item mode, published as `ATTR_EDITOR_CLICK_TARGET` in `finalize()`.
merged_click_target_bboxes: Vec<[DVec2; 2]>,
/// Per-glyph baselines, parallel to `merged_click_target_bboxes`. Groups glyphs by line for the widening pass.
@@ -35,7 +35,7 @@ impl PathBuilder {
Self {
current_subpath: Subpath::new(Vec::new(), false),
glyph_subpaths: Vec::new(),
vector_table: if per_glyph_items { Table::new() } else { Table::new_from_element(Vector::default()) },
vector_list: if per_glyph_items { List::new() } else { List::new_from_element(Vector::default()) },
merged_click_target_bboxes: Vec::new(),
merged_click_target_baselines: Vec::new(),
per_glyph_bboxes: Vec::new(),
@@ -87,14 +87,14 @@ impl PathBuilder {
let item = Item::new_from_element(Vector::from_subpaths(core::mem::take(&mut self.glyph_subpaths), false))
.with_attribute(ATTR_TRANSFORM, DAffine2::from_translation(glyph_offset))
.with_attribute(ATTR_EDITOR_TEXT_FRAME, frame_in_item_local);
self.vector_table.push(item);
self.vector_list.push(item);
// Defer click target creation to `finalize()` where adjacent AABBs get widened
self.per_glyph_bboxes.push(glyph_bbox);
} else {
for subpath in self.glyph_subpaths.drain(..) {
// Unwrapping here is ok because `self.vector_table` is initialized with a single `Table<Vector>` item
self.vector_table.element_mut(0).unwrap().append_subpath(subpath, false);
// Unwrapping here is ok because `self.vector_list` is initialized with a single `List<Vector>` item
self.vector_list.element_mut(0).unwrap().append_subpath(subpath, false);
}
if let Some(bbox) = glyph_bbox {
self.merged_click_target_bboxes.push(bbox);
@@ -163,16 +163,16 @@ impl PathBuilder {
}
}
pub fn finalize(mut self) -> Table<Vector> {
// Empty table = all glyphs clipped by height. Create a placeholder with the same item-0
// transform a populated table would have so `local_transforms` stays stable mid-drag.
pub fn finalize(mut self) -> List<Vector> {
// Empty list = all glyphs clipped by height. Create a placeholder with the same item-0
// transform a populated list would have so `local_transforms` stays stable mid-drag.
// TODO: Remove this hack and move the attribute up to the parent return value when <https://github.com/GraphiteEditor/Graphite/issues/3779> is done.
if self.vector_table.is_empty() {
if self.vector_list.is_empty() {
let frame_in_item_local = DAffine2::from_scale_angle_translation(self.text_frame_size, 0., -self.first_glyph_offset);
let item = Item::new_from_element(Vector::default())
.with_attribute(ATTR_TRANSFORM, DAffine2::from_translation(self.first_glyph_offset))
.with_attribute(ATTR_EDITOR_TEXT_FRAME, frame_in_item_local);
self.vector_table.push(item);
self.vector_list.push(item);
}
// Widen per-glyph AABBs to close horizontal gaps, then publish as click targets
@@ -184,7 +184,7 @@ impl PathBuilder {
.enumerate()
.filter_map(|(index, bbox)| {
let bbox = (*bbox)?;
let offset = self.vector_table.attribute_cloned_or_default::<DAffine2>(ATTR_TRANSFORM, index).translation;
let offset = self.vector_list.attribute_cloned_or_default::<DAffine2>(ATTR_TRANSFORM, index).translation;
Some((index, offset, [bbox[0] + offset, bbox[1] + offset]))
})
.collect();
@@ -197,7 +197,7 @@ impl PathBuilder {
for (entry, widened) in entries.iter().zip(layer_bboxes.iter()) {
let glyph_local = [widened[0] - entry.1, widened[1] - entry.1];
let rect = Subpath::new_rectangle(glyph_local[0], glyph_local[1]);
self.vector_table.set_attribute(ATTR_EDITOR_CLICK_TARGET, entry.0, Vector::from_subpaths([rect], false));
self.vector_list.set_attribute(ATTR_EDITOR_CLICK_TARGET, entry.0, Vector::from_subpaths([rect], false));
}
}
@@ -207,18 +207,18 @@ impl PathBuilder {
widen_horizontal_gaps(&mut bboxes, &self.merged_click_target_baselines);
let widened_subpaths: Vec<_> = bboxes.iter().map(|[min, max]| Subpath::new_rectangle(*min, *max)).collect();
self.vector_table.set_attribute(ATTR_EDITOR_CLICK_TARGET, 0, Vector::from_subpaths(widened_subpaths, false));
self.vector_list.set_attribute(ATTR_EDITOR_CLICK_TARGET, 0, Vector::from_subpaths(widened_subpaths, false));
}
// Fill in text frame for items that don't have one yet (single-item mode, where item 0 = identity)
let frame = DAffine2::from_scale(self.text_frame_size);
for index in 0..self.vector_table.len() {
if self.vector_table.attribute::<DAffine2>(ATTR_EDITOR_TEXT_FRAME, index).is_none() {
self.vector_table.set_attribute(ATTR_EDITOR_TEXT_FRAME, index, frame);
for index in 0..self.vector_list.len() {
if self.vector_list.attribute::<DAffine2>(ATTR_EDITOR_TEXT_FRAME, index).is_none() {
self.vector_list.set_attribute(ATTR_EDITOR_TEXT_FRAME, index, frame);
}
}
self.vector_table
self.vector_list
}
}

View File

@@ -1,5 +1,5 @@
use core_types::list::{Item, List};
use core_types::registry::types::SignedInteger;
use core_types::table::{Item, Table};
use core_types::{ATTR_END, ATTR_NAME, ATTR_START, Ctx};
/// Checks whether the string contains a match for the given regular expression pattern. Optionally restricts the match to only the start and/or end of the string.
@@ -96,9 +96,9 @@ fn regex_find(
case_insensitive: bool,
/// Make `^` and `$` match the start and end of each line, not just the whole string.
multiline: bool,
) -> Table<String> {
) -> List<String> {
if pattern.is_empty() {
return Table::new();
return List::new();
}
let flags = match (case_insensitive, multiline) {
@@ -111,7 +111,7 @@ fn regex_find(
let Ok(regex) = fancy_regex::Regex::new(&full_pattern) else {
log::error!("Invalid regex pattern: {pattern}");
return Table::new();
return List::new();
};
// Capture group names indexed positionally; index 0 (the whole match) is always None.
@@ -124,7 +124,7 @@ fn regex_find(
let resolved_index = if match_index < 0 {
let from_end = (-match_index) as usize;
if from_end > matches.len() {
return Table::new();
return List::new();
}
matches.len() - from_end
} else {
@@ -132,7 +132,7 @@ fn regex_find(
};
let Some(captures) = matches.get(resolved_index) else {
return Table::new();
return List::new();
};
// Index 0 is the whole match, 1+ are capture groups
@@ -165,9 +165,9 @@ fn regex_find_all(
case_insensitive: bool,
/// Make `^` and `$` match the start and end of each line, not just the whole string.
multiline: bool,
) -> Table<String> {
) -> List<String> {
if pattern.is_empty() {
return Table::new();
return List::new();
}
let flags = match (case_insensitive, multiline) {
@@ -180,7 +180,7 @@ fn regex_find_all(
let Ok(regex) = fancy_regex::Regex::new(&full_pattern) else {
log::error!("Invalid regex pattern: {pattern}");
return Table::new();
return List::new();
};
regex
@@ -208,9 +208,9 @@ fn regex_split(
case_insensitive: bool,
/// Make `^` and `$` match the start and end of each line, not just the whole string.
multiline: bool,
) -> Table<String> {
) -> List<String> {
if pattern.is_empty() {
return Table::new_from_element(string);
return List::new_from_element(string);
}
let flags = match (case_insensitive, multiline) {
@@ -223,7 +223,7 @@ fn regex_split(
let Ok(regex) = fancy_regex::Regex::new(&full_pattern) else {
log::error!("Invalid regex pattern: {pattern}");
return Table::new_from_element(string);
return List::new_from_element(string);
};
regex.split(&string).filter_map(|s| s.ok()).map(|s| s.to_string()).map(Item::new_from_element).collect()

View File

@@ -1,6 +1,6 @@
use super::{Font, FontCache, TypesettingConfig};
use core::cell::RefCell;
use core_types::table::Table;
use core_types::list::List;
use glam::DVec2;
use parley::fontique::{Blob, FamilyId, FontInfo};
use parley::{AlignmentOptions, FontContext, Layout, LayoutContext, LineHeight, PositionedLayoutItem, StyleProperty};
@@ -87,9 +87,9 @@ impl TextContext {
}
/// Convert text to vector paths using the specified font and typesetting configuration
pub fn to_path(&mut self, text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig, per_glyph_items: bool) -> Table<Vector> {
pub fn to_path(&mut self, text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig, per_glyph_items: bool) -> List<Vector> {
let Some(layout) = self.layout_text(text, font, font_cache, typesetting) else {
return Table::new_from_element(Vector::default());
return List::new_from_element(Vector::default());
};
let text_frame_size = DVec2::new(

View File

@@ -1,12 +1,12 @@
use super::text_context::TextContext;
use super::{Font, FontCache, TypesettingConfig};
use core_types::table::Table;
use core_types::list::List;
use glam::DVec2;
use parley::fontique::Blob;
use std::sync::Arc;
use vector_types::Vector;
pub fn to_path(text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig, per_glyph_items: bool) -> Table<Vector> {
pub fn to_path(text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig, per_glyph_items: bool) -> List<Vector> {
TextContext::with_thread_local(|ctx| ctx.to_path(text, font, font_cache, typesetting, per_glyph_items))
}