I find myself requiring an object to store a text string, with ways to throw markup or presentation attributes around it, but in such a way that they're easy to edit and change separately from the string data. I.e. the usual embedded HTML / ANSI escapes / etc... are not really suitable.
With this in mind, I have come up with String::Tagged. I'd appreciate any thoughts or comments people might have on the API and design before I upload it. ----- String::Tagged(3pm) User Contributed Perl Documentation String::Tagged(3pm) NAME "String::Tagged" - string buffers with value tags on ranges SYNOPSIS use String::Tagged; my $st = String::Tagged->new( "An important message" ); $st->apply_tag( 3, 9, bold => 1 ); $st->iter_substr_nooverlap( sub { my ( $substring, %tags ) = @_; print $tags{bold} ? "<b>$substring</b>" : $substring; } ); DESCRIPTION This module implements an object class, instances of which store a (mutable) string buffer that supports tags. A tag is a name/value pair that applies to some non-empty range of the underlying string. Tags may be arbitrarily overlapped. Any given offset within the string has in effect, a set of uniquely named tags. Tags of different names are independent. For tags of the same name, only the the latest, shortest tag takes effect. For example, consider a string with two tags represented here: Here is my string with tags |-------------------------| foo => 1 |-------| foo => 2 |---| bar => 3 Every character in this string has a tag named "foo". The value of this tag is 2 for the words "my" and "string" and the space inbetween, and 1 elsewhere. Additionally, the words "is" and "my" and the space between them also have the tag "bar" with a value 3. CONSTRUCTOR $st = String::Tagged->new( $str ) Returns a new instance of a "String::Tagged" object. It will contain no tags. If the optional $str argument is supplied, the string buffer will be initialised from this value. METHODS $str = $st->str Returns the plain string contained within the object. $str = $st->substr( $start, $len ) Returns a substring of the plain string contained within the object. $st->apply_tag( $start, $len, $name, $value ) Apply the named tag value to the given range. $st->unapply_tag( $start, $len, $name ) Unapply the named tag value from the given range. If the tag extends beyond this range, then any partial fragment of the tag will be left in the string. $st->delete_tag( $start, $len, $name ) Delete the named tag within the given range. Entire tags are removed, even if they extend beyond this range. $st->iter_tags( $callback ) Iterate the tags stored in the string. For each tag, the CODE reference in $callback is invoked once. $callback->( $start, $length, $tagname, $tagvalue ) $st->iter_tags_nooverlap( $callback ) Iterate non-overlapping ranges of tags stored in the string. The CODE reference in $callback is invoked for each range in the string where no tags change. The entire set of tags active in that range is given to the callback. $callback->( $start, $length, %tags ) The callback will be invoked over the entire length of the string, including any ranges with no tags applied. $st->iter_substr_nooverlap( $callback ) Iterate ranges of the substring in the same way as "iter_tags_nooverlap()", but passing the substring of data instead of the start position and length. $callback->( $substr, %tags ) @names = $st->tagnames Returns the set of tag names used in the string, in no particular order. $tags = $st->get_tags_at( $pos ) Returns a HASH reference of all the tag values active at the given position. $value = $st->get_tag_at( $pos, $name ) Returns the value of the named tag at the given position, or "undef" if the tag is not applied there. $st->set_substr( $start, $len, $newstr ) Modifies a range of the underlying plain string to that given. NOTE: - Because of the way that this method modifies the underlying string, its use would disturb the tags applied in its range, or after if the length changes. There is no clear behaviour for what should be done to tags applied in the affected range, or after it. Therefore, this method will throw an exception if any tags apply after the $start index. This is unlikely to be useful in a general application; I am well aware of this fact. I welcome suggestions on what the behaviour(s) ought to be. $st->insert( $start, $newstr ) Insert the given string at the given position. A shortcut around "set_substr()". $st->append( $newstr ) Append to the underlying plain string. Because no tags will yet apply here, this method is not subject to note given in "set_substr()". $st->append_tagged( $newstr, %tags ) Append to the underlying plain string, and apply the given tags. TODO ยท Implement (possibly multiple) ways to modify substrings, while keeping some level of sanity on the tags. Likely sensible behaviour would probably be: Tags entirely before the replaced region would remain unchanged. Tags entirely within the replaced region would be deleted. Tags entirely after the replaced region would get shifted up/down the appropriate amount to ensure they still apply to the right characters. Tags that start before and end after the range would remain, and have their lengths suitably adjusted. Tags that span just the start or end of the range, but not both, would be truncated shorter, so as to remove the part of the tag applied on the modified section but preserving that applied outside. There are likely variations on these rules that could equally apply to some uses of tagged strings. Consider whether the behaviour of modification is chosen per-method, per-tag, or per-string. AUTHOR Paul Evans <leon...@leonerd.org.uk> perl v5.10.0 2009-01-30 String::Tagged(3pm) ----- -- Paul "LeoNerd" Evans leon...@leonerd.org.uk ICQ# 4135350 | Registered Linux# 179460 http://www.leonerd.org.uk/
signature.asc
Description: Digital signature