neco-wrap 0.1.0

Word wrap engine with pluggable line-breaking and character-width policies
Documentation
  • Coverage
  • 3.03%
    1 out of 33 items documented0 out of 29 items with examples
  • Size
  • Source code size: 27.16 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.76 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 34s Average build duration of successful builds.
  • all releases: 36s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • barineco/neco-editor
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • barineco

neco-wrap

日本語

Word wrap engine for splitting logical lines into visual lines, with pluggable line-breaking and character-width policies.

How it works

neco-wrap splits a logical line into visual lines according to a WrapPolicy. A policy bundles two function pointers: one that returns the visual width of a character, and one that decides whether a break is allowed, forbidden, or mandatory at a given byte offset.

wrap_line processes one logical line and returns a list of WrapPoint values, each marking the byte offset and cumulative visual width where a visual line ends. WrapMap applies this over a whole document, tracks the results per logical line, and provides coordinate translation between logical (line, byte_offset) and visual line numbers.

Two built-in policies are provided. WrapPolicy::code breaks after ASCII whitespace and common operators. WrapPolicy::japanese_basic applies kinsoku shaping rules for Japanese text.

Usage

Wrapping a single line

use neco_wrap::{WrapPolicy, wrap_line};

let policy = WrapPolicy::code();
let wraps = wrap_line("ab cd ef", 4, &policy);

// Two wrap points: after "ab " and after "cd "
assert_eq!(wraps.len(), 2);
assert_eq!(wraps[0].byte_offset(), 3);
assert_eq!(wraps[1].byte_offset(), 6);

Managing a whole document with WrapMap

use neco_wrap::{WrapPolicy, WrapMap};

let lines = ["hello world", "foo bar baz"];
let policy = WrapPolicy::code();
let mut map = WrapMap::new(lines.iter().copied(), 6, &policy);

// Total visual lines across all logical lines
let total = map.total_visual_lines();

// Translate logical (line, byte_offset_in_line) to a visual line number
let vline = map.to_visual_line(0, 6);

// After an edit, rewrap just the changed line
map.rewrap_line(0, "hi", &policy);

API

Item Description
BreakOpportunity Allowed, Forbidden, or Mandatory break classification at a byte offset
WrapPolicy Bundles char_width and break_opportunity function pointers
WrapPolicy::new(char_width, break_opportunity) Constructor from two function pointers
WrapPolicy::char_width() Returns the stored character-width function
WrapPolicy::break_opportunity() Returns the stored break-opportunity function
WrapPolicy::code() Built-in policy: breaks after ASCII whitespace and common code operators
WrapPolicy::japanese_basic() Built-in policy: breaks between CJK characters with kinsoku rules
WrapPoint Byte offset and cumulative visual width at a visual line boundary
WrapPoint::byte_offset() Byte offset in the logical line where the visual line ends
WrapPoint::visual_width() Cumulative visual column count up to this wrap point
VisualLine [start, end) byte range of one visual line within a logical line
VisualLine::start() Start byte offset
VisualLine::end() End byte offset
VisualLine::len() Byte length of the visual line
VisualLine::is_empty() True when start equals end
WrapMap Per-document wrap state: stores wrap points for every logical line
WrapMap::new(lines, max_width, policy) Build from a line iterator
WrapMap::max_width() The column limit used for wrapping
WrapMap::line_count() Number of logical lines
WrapMap::visual_line_count(line) Number of visual lines for a logical line
WrapMap::total_visual_lines() Total visual line count across the document
WrapMap::wrap_points(line) Slice of WrapPoint for a logical line
WrapMap::visual_lines(line, line_len) VisualLine segments for a logical line
WrapMap::to_visual_line(line, byte_offset_in_line) Logical position to absolute visual line number
WrapMap::from_visual_line(visual_line) Absolute visual line number to (logical_line, start_byte_offset)
WrapMap::rewrap_line(line, line_text, policy) Recompute wrap points for one logical line after an edit
WrapMap::set_max_width(max_width, lines, policy) Change the column limit and recompute all lines
WrapMap::splice_lines(start_line, removed_count, new_lines, policy) Replace a range of logical lines, matching a document splice
wrap_line(line_text, max_width, policy) Low-level function: wrap one line and return Vec<WrapPoint>

License

MIT