Kiwi Document C# API
To parse a document, simply pass the raw text into the constructor.
var doc = new KiwiDocument("the entire text of the document");The document will parse, and populate all its properties.
Section Collections
The primary feature of the document are lists of Section objects, in several collections:
Sections: The raw list of allSectionobjectsFilteredSections: A list ofSectionobjects which are not hidden (the name does not start with an underscore)NarrativeSections: A list ofSectionobjects which are not explicitly closed (see Kiwi Document Format)DefaultSections: A list ofSectionobjects with a name matching the default section name
There are methods for working with sections:
Section GetSection(string name): Returns the first section with the provided namestring GetSectionContent(string name, string defaultValue): Returns the content of the first section with the provided name, or the default value if no such section is foundList<Section> GetSections(params string[] name): Returns a list of all filter (non-hidden) sections with any of the provided names. You can pass in a series of regular names, or a series of names preceded by an minus sign, which means: “without this.” So, passing-historymeans, “give me all the sections except any sections named ‘history’”List<Section> GetAllSections(params string[] name): As above, but operates on all sections (including those hidden)bool HasSection: Returnstrueif the document has at least one section with the provided namevoid Apply(Func<Section, StructuredTextBase, Section> function): Takes a delegate that will be applied to all sections. The delegate will be called once for each section, and be passed (1) that section and (2) the entire document. It can do whatever it likes to the section, then return the transformed version, which will replace the original in the document.void ApplyStructure(string structureSpecification): Takes a string that will re-arrange the document. You can name sections in relation to a*character, which means “everything else.” So,history, economics, *will re-arrange the document with allhistorysections first, then alleconomicssections, then everything else.foo, *, barwould movefoosections to the top, andbarsections to the bottom, and leave everything else in its existing order.
Sections
string Content: This contains the content of the section, meaning whatever is separated from the meta by a blank line.List<string> Lines: This is a list of strings representing each line in the section.TrimmedLinesremoves the blank lines from the beginning and end of the content (but retains any blank lines in the middle).Section GetNearestAbove/Below(string name): This will look at the sections above or below the current section in the document, and find the nearest section with the provided name. Returnsnullif a section with that name is not found.
Metadata Collections
Each section – and the document as a whole – has a MetaCollection object exposed at the Meta property. It exposes the following methods:
string Get(string key): Returns the string representation of the first instance of the provided key. Returnsnullif no such meta is found.T Get<T>(string key): Returns the value of first instance of metadata with the provided key. Returnsdefault(T)if no such meta is found.bool HasMeta(string key): Returnstrueif the collection has any meta with the provided key.List<T> GetAllValues<T>(string key): Will provide a list of all values for the provided key.
Document Meta
The document as a whole – like each of its sections – exposes a Meta property which functions as above. This meta collection is simply the same meta collection of the first section.
However, the document also exposes an AllMeta property which is a consolidated list of all the meta items from all the sections in the document.
Many of the meta-related methods return the first meta value found for the key, which means AllMeta can be used to search down through multiple sections for a specific meta key.
Meta also has a few convenience properties for common meta.
string Title: The value for the meta with the keytitlestring Description: The value for the meta with the keydescriptionordesc(I kept forgetting the key I used, so I just look for both)string Status: The value for the meta with the keystatusDateTime Date: The value for the meta with the keydate, parsed into aDateTime(it will beDateTime.MinValueif it won’t parse)
Example
Consider this document:
title: The Barker Family
established: 1999-06-05
[[ person ]]
first: Deane
last: Barker
The husband
[[ person ]]
first: Annie
last: Barker
The wifeWe can work with it like this:
var doc = new KiwiDocument(documentText);
Console.WriteLine(doc.Title);
Console.WriteLine($"Est. {doc.Get<DateTime>("established"):MMMM, d yyyy}");
foreach(var section in doc.GetSections("person"))
{
var lastName = section.Meta.Get("last");
var firstName = section.Meta.Get("first")
Console.WriteLine($"{last}, {first}: {section.Content}");
}Resulting in:
The Barker Family
Est. June 5, 1999
Barker, Deane: The husband
Barker, Annie: The wifeSectionMap
Each section has a Map property which exposes numerous properties regarding where that section lies in context of the entire document.
bool IsFirst: Returnstrueif this is the first section in the documentbool IsLast: Returnstrueif this is the last section in the documentint Total: Returns the total number of sections in the documentint Index: Returns the 0-based position of this section in the documentint Ordinal: Returns the 1-based position of this section in the documentSection Prev: Returns the prior section in the document, ornullif this is the first sectionSection Next: Returns the next section in the document, ornullif this is the last sectionint TotalOfType: Returns the number of sections with the same name as this section (including this section)int IndexOfType: Returns the 0-based position of this section among sections with the same nameint OrdinalOfType: Returns the 1-based position of this section among sections with the same namebool IsFirstOfType: Returnstrueif this is the first section with its name in the documentbool IsLastOfType: Returnstrueif this is the last section with its name in the documentbool IsNextSameType: Returnstrueif the next section has the same name as this sectionbool IsPrevSameType: Returnstrueif the previous section has the same name as this section