Package squidpony

Class ObText

All Implemented Interfaces:
Serializable, Cloneable, Iterable<ObText.ObTextEntry>, Collection<ObText.ObTextEntry>, List<ObText.ObTextEntry>, RandomAccess

public class ObText
extends ArrayList<ObText.ObTextEntry>
implements Serializable
A simple format parser for String-based configuration or data files where JSON is overkill. Supports only one type, String, but allows each String to have arbitrary nested levels of String children as if in sub-lists. You can interpret the Strings however you want, and quoting each String isn't necessary if they are just one word ("bare words" are allowed). This stores its items in an inner class, ObText.ObTextEntry, which only has a "primary" String and may have a List of "associated" ObTextEntry values, each of which must have their own primary String and which may have their own associated List.
You can use this like any other List, though it will be contain ObTextEntry objects instead of Strings directly. This allows you to control whether you want to iterate through a particular primary String's associated entries, if there are any, or to skip over them and go to the next String in the current List.
This extends ArrayList of ObTextEntry and is modifiable, but it doesn't act quite like what what you might expect from an ArrayList. Chiefly, this only considers the top-level Strings to be part of the List for length and for ArrayList.contains(Object), and will ignore child strings unless you access them via the ObText.ObTextEntry.associated List on an entry that has associated entries.
A common way to use this is with parse(CharSequence) to read a String in the following format.
Format example:
 hello world
 'how are you today?' [just great thanks]
 hooray!

 complexity?
 [it is possible [yes this is a good example]
 'escapes like \[\'\] all work'
 "you can use double or single quotes to allow spaces and brackets in one string"
 ]

 comments are allowed // like this
 comments can have different forms # like this
 // block comments like in c are allowed
 / * but because this example is in javadoc, this example is not actually a comment * /
 // remove the spaces between each slash and asterisk to make the last line a comment.
 /[delimit/or block comments with delimiters/delimit]/

 '''
 raw strings (heredocs) look like this normally.
     they permit characters without escapes, ]][][[ \/\/\ ,
     except for triple quotes.
     they keep newlines and indentation intact,
 except for up to one newline ignored adjacent to each triple quote.
 '''

 [[different[
 if you may need triple quotes
     in the raw string, use a different syntax that allows delimiters.
 here, the delimiter is '''different''', just to be different.]different]]
 

Inspired strongly by STOB and its Java port , but no code is shared and the format is slightly different. The main differences are:
  • We use square brackets in place of STOB's curly braces to mark children associated with a string.
  • ObText supports nested block comments using the syntax /[delimiter/contents/delimiter]/ where delimiter may be empty but must match on both sides, and contents is the body of the comment.
  • ObText uses Python-like "heredoc" syntax for raw strings surrounded by triple-apostrophes '''like so''' with optional initial and final newlines in the raw string ignored. An alternate raw string syntax is present that allows delimiters, using the syntax [[delimiter[contents]delimiter]], where again delimiter may be empty and contents is the body of the raw string.
    See Also:
    Serialized Form
    • Field Details

    • Constructor Details

    • Method Details

      • parse

        public ObText parse​(CharSequence text)
        Parses the given text (a String or other CharSequence) and appends it into this ObText.
        Parameters:
        text - a CharSequence (such as a String) using ObText formatting, as described in this class' JavaDocs
        Returns:
        this ObText object after appending the parsed text, for chaining
      • add

        public void add​(int index, String text)
        Inserts the given String element at the specified position in this ObText's top level. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
        Parameters:
        index - index at which the specified element is to be inserted
        text - String element to be inserted, without any associated entries
      • add

        public boolean add​(String text)
        Appends the given String element to the end of this ObText at the top level.
        Parameters:
        text - String element to be inserted, without any associated entries
        Returns:
        true (this always modifies the ObText)
      • hash64

        public long hash64()
      • hashCode

        public int hashCode()
        Specified by:
        hashCode in interface Collection<ObText.ObTextEntry>
        Specified by:
        hashCode in interface List<ObText.ObTextEntry>
        Overrides:
        hashCode in class ArrayList<ObText.ObTextEntry>
      • appendQuoted

        public static void appendQuoted​(StringBuilder sb, String text)
      • appendQuotedObText

        public static void appendQuotedObText​(StringBuilder sb, String text)
      • appendQuoted

        protected static void appendQuoted​(StringBuilder sb, String text, regexodus.Matcher bareFinder)
      • toString

        public String toString()
        Overrides:
        toString in class AbstractCollection<ObText.ObTextEntry>
      • serializeToString

      • deserializeFromString

        public static ObText deserializeFromString​(String data)
        Deserializes an ObText that was serialized by serializeToString() or toString(), and will ignore the prefix and suffix that toString appends for readability (these are "ObText object: [[[[ " and " ]]]]", for reference). This is otherwise the same as calling the constructor ObText(CharSequence).
        Parameters:
        data - a String that is usually produced by serializeToString or toString on an ObText
        Returns:
        a new ObText produced by parsing data (disregarding any prefix or suffix from toString() )
      • keyList

        Gets all Strings from the top level of this ObText, not including any associated values, and puts them in an ArrayList of String. The returned list will retain the same order the Strings were entered in, and unlike keySet() or keyOrderedSet(), duplicate keys will all be preserved. Changes to the returned List won't be reflected in this ObText.
        Returns:
        all top-level Strings (without associated values) as an ArrayList of String
      • keyOrderedSet

        Gets all unique Strings from the top level of this ObText, not including any associated values, and puts them in an OrderedSet of String. The returned set will retain the same order the Strings were entered in, and you can use OrderedSet methods like OrderedSet.getAt(int) to look up keys by index. Changes to the returned Set won't be reflected in this ObText.
        Returns:
        all unique top-level Strings (without associated values) as an OrderedSet of String keys
      • keySet

        public HashSet<String> keySet()
        Gets all unique Strings from the top level of this ObText, not including any associated values, and puts them in a HashSet of String. The returned set won't be insertion-ordered or necessarily retain the same order the Strings were entered in; use keyOrderedSet() if you want this. Changes to the returned Set won't be reflected in this ObText.
        Returns:
        all unique top-level Strings (without associated values) as a HashSet of String keys
      • basicOrderedMap

        Gets all unique Strings from the top level of this ObText as keys in an OrderedMap, with the first String associated with each key as its value (or null if nothing is associated with a key String). The returned map will retain the same order the keys were entered in, and you can use OrderedMap methods like OrderedMap.keyAt(int) to look up keys by index or OrderedMap.getAt(int) to look up value String by index. Changes to the returned Map won't be reflected in this ObText.
        Returns:
        an OrderedMap of unique String keys associated with the first associated String for each key (or null)
      • basicMap

        public HashMap<String,​String> basicMap()
        Gets all unique Strings from the top level of this ObText as keys in a HashMap, with the first String associated with each key as its value (or null if nothing is associated with a key String). The returned map won't be insertion-ordered or necessarily retain the same order the Strings were entered in; use shallowOrderedMap() if you want this. Changes to the returned Map won't be reflected in this ObText.
        Returns:
        a HashMap of unique String keys associated with the first associated String for each key (or null)
      • shallowOrderedMap

        Gets all unique Strings from the top level of this ObText as keys in an OrderedMap, with any Strings associated with those keys as their values (in a possibly-empty ArrayList of String for each value). The returned map will retain the same order the keys were entered in, and you can use OrderedMap methods like OrderedMap.keyAt(int) to look up keys by index or OrderedMap.getAt(int) to look up the ArrayList of value Strings by index. Changes to the returned Map won't be reflected in this ObText.
        Returns:
        an OrderedMap of unique String keys associated with ArrayList values containing associated Strings
      • shallowMap

        Gets all unique Strings from the top level of this ObText as keys in a HashMap, with any Strings associated with those keys as their values (in a possibly-empty ArrayList of String for each value). The returned map won't be insertion-ordered or necessarily retain the same order the Strings were entered in; use basicOrderedMap() if you want this. Changes to the returned Map won't be reflected in this ObText.
        Returns:
        a HashMap of unique String keys associated with ArrayList values containing associated Strings
      • makeMatcher

        Can be used to help reading sequences of Strings with ObText-style quotation marking their boundaries. This returns a ObText.ContentMatcher object that you must call setTarget on before using it. The argument(s) to setTarget should be the text that might contain quotes, heredoc-style quotes, or just bare words. Calling Matcher.find() will try to find the next String, returning false if there's nothing left or returning true and advancing the search if a String was found. The String might be a special term in some cases, like "[" and "]" without quotes being syntax in ObText that don't contain usable Strings. That's why, after a String was found with find(), you should check ObText.ContentMatcher.hasMatch() to verify that a match was successful, and if that's true, then you can call ObText.ContentMatcher.getMatch() to get the un-quoted contents of the next String in the target.
        Returns:
        a ObText.ContentMatcher that must have one of its setTarget() methods called before it can be used
      • makeMatcher

        Can be used to help reading sequences of Strings with ObText-style quotation marking their boundaries. This returns a ObText.ContentMatcher object that is already configured to read from text. The text should contain Strings that may be surrounded by quotes, heredoc-style quotes, or just bare words. Calling Matcher.find() will try to find the next String, returning false if there's nothing left or returning true and advancing the search if a String was found. The String might be a special term in some cases, like "[" and "]" without quotes being syntax in ObText that don't contain usable Strings. That's why, after a String was found with find(), you should check ObText.ContentMatcher.hasMatch() to verify that a match was successful, and if that's true, then you can call ObText.ContentMatcher.getMatch() to get the un-quoted contents of the next String in the target.
        Parameters:
        text - the target String that should probably have at least one sub-string that might be quoted
        Returns:
        a ObText.ContentMatcher that can be used immediately by calling Matcher.find()
      • makeMatcherNoComments

        Can be used to help reading sequences of Strings with ObText-style quotation marking their boundaries, but no comments (which allows some additional characters to be used in bare words, like '#'). This returns a ObText.ContentMatcher object that is already configured to read from text. The text should contain Strings that may be surrounded by quotes, heredoc-style quotes, or just bare words. Calling Matcher.find() will try to find the next String, returning false if there's nothing left or returning true and advancing the search if a String was found. Unlike the ContentMatcher produced by makeMatcher(CharSequence), you can call ObText.ContentMatcher.getMatch() after any successful call to Matcher.find(), which will get the un-quoted contents of the next String in the target.
        Parameters:
        text - the target String that should probably have at least one sub-string that might be quoted
        Returns:
        a ObText.ContentMatcher that can be used immediately by calling Matcher.find()