### Markwhen Timeline Structure Example Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md An example of a Markwhen document defining a project timeline with grouped phases, overridden timezones, and dependencies between events. ```markwhen --- title: Project Timeline timezone: America/New_York dateFormat: M/d/y --- group Phase 1 timezone: America/Chicago # Override 2024-01-15: Kickoff !phase1 priority: high location: Conference A 2024-01-22 to 2024-02-01: Development every 3 days # Recurring 2024-02-15: Review !phase1-review attendees: - Manager - Team Lead group Phase 2 after !phase1-review plus 1 week: Planning 2024-03-01: Execution depends_on: !phase1-review ``` ```text root EventGroup ├── Phase 1 (EventGroup) │ ├── Kickoff (Event) │ ├── Development (Event, recurring) │ └── Review (Event) └── Phase 2 (EventGroup) ├── Planning (Event, relative) └── Execution (Event) ``` -------------------------------- ### Configuration via Header Example Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Parses a Markwhen string with YAML header configuration and accesses the header properties. ```javascript import { parse } from "@markwhen/parser"; const markwhen = "\ ---\ title: Q1 Planning\ timezone: America/Los_Angeles\ dateFormat: d/M/y\ ---\ 2024-01-15: Kickoff meeting #project-alpha\ "; const result = parse(markwhen); // Access configuration console.log(result.header.title); // "Q1 Planning" console.log(result.header.timezone); // "America/Los_Angeles" console.log(result.header.dateFormat); // "d/M/y" ``` -------------------------------- ### ID Lookup Example Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Demonstrates how to parse Markwhen text, extract event IDs, and then use those IDs to look up the corresponding event objects from the parse result. Requires the `get` utility function. ```javascript import { parse } from "@markwhen/parser"; const result = parse(` 2024-01-01: Event A !eventA after !eventB plus 5 days 2024-01-10: Event B !eventB `); // Lookup by ID from the parse result const path = result.ids["eventA"]; const event = get(result.events, path); console.log(event.firstLine.restTrimmed); // "Event A" ``` -------------------------------- ### Timezone Parsing Example Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Demonstrates how header timezone and event-specific timezones affect parsing. ```markwhen --- timezone: UTC --- 2024-01-15 10:00:00: Event in UTC timezone: America/New_York # This event is in EST group US-based timezone: America/Chicago 2024-01-15 10:00:00: Event in CST ``` -------------------------------- ### Markwhen Configuration: Academic calendar with dates Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Example of a Markwhen timeline representing an academic year, with distinct periods for semesters and breaks, each assigned a color. ```markwhen --- title: 2024 Academic Year timezone: America/Chicago dateFormat: d/M/y --- 2024-01-15 to 2024-05-10: Spring Semester color: "#3B82F6" 2024-05-15 to 2024-08-15: Summer Break color: "#10B981" 2024-09-01 to 2024-12-15: Fall Semester color: "#F59E0B" ``` -------------------------------- ### Markwhen Configuration: US-based timeline with multiple timezones Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Example of a Markwhen timeline configured for US timezones, specifying different timezones for different groups within the same file. ```markwhen --- title: Office Operations timezone: America/New_York dateFormat: M/d/y --- group East Coast HQ timezone: America/New_York 2024-01-15: Monday standup 2024-01-16: Team lunch group West Coast Office timezone: America/Los_Angeles 2024-01-15: Monday sync 2024-01-18: All-hands meeting ``` -------------------------------- ### Get Prior Event Start Time Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Retrieves the start time of the last event processed. ```typescript priorEventFromDateTime(): DateTime | undefined ``` -------------------------------- ### events.md - Event and Group Classes Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md Details on the `Event`, `EventGroup`, and `EventDescription` classes, along with tree navigation methods like `iter()`, `flat()`, `get()`, `push()`, and `ranges()`. ```APIDOC ## Event and Group Classes This section describes the core classes for representing events and groups, and methods for navigating the event tree. ### Classes - **`Event`**: Represents a single event in the timeline. - **`EventGroup`**: Represents a group of related events. - **`EventDescription`**: Represents the description content of an event. ### Tree Navigation - **`iter()`**: Returns an iterator for traversing the event tree. - **`flat()`**: Returns a flat array of all events and groups. - **`get(id: string)`**: Retrieves an event or group by its ID. - **`push(item: Event | EventGroup)`**: Adds an event or group to the tree. - **`ranges()`**: Returns all date ranges present in the tree. ``` -------------------------------- ### priorEventFromDateTime() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Retrieves the start time of the last event processed within the parsing context. ```APIDOC ## priorEventFromDateTime() ### Description Returns the start time of the last event. ### Method ```typescript priorEventFromDateTime(): DateTime | undefined ``` ``` -------------------------------- ### Example of Invalid Date Syntax Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Illustrates an invalid date format that triggers a parse error. Use valid EDTF, Casual, or Slash formats. ```markwhen 2024-13-45: Invalid month/day ``` -------------------------------- ### Quick Start: Parse Timeline String Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Demonstrates basic usage of the parse function to convert a Markwhen timeline string into a structured object. Shows how to access the title and event count from the parsed result. ```javascript import { parse } from "@markwhen/parser"; const result = parse(` title: Q1 Planning timezone: America/New_York 2024-01-15: Kickoff 2024-02-01: Phase 1 Review 2024-03-01: Final Review `); console.log(result.header.title); // "Q1 Planning" console.log(result.events.children.length); // 3 events ``` -------------------------------- ### get() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/events.md Retrieves a node (event) from the event tree by its path. The path is an array of indices representing the traversal through the nested event structure. ```APIDOC ## get() ### Description Retrieves a node by path. ### Signature ```typescript function get(root: Eventy, path: Path): Eventy | undefined ``` ### Usage Example ```javascript const event = get(result.events, [0, 1, 0]); // Gets root.children[0].children[1].children[0] ``` ``` -------------------------------- ### Example of Event ID Redefinition Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Shows two events with the same ID, where the last definition wins. Use unique IDs or rely on path-based references to avoid issues. ```markwhen 2024-01-01: Event !myid 2024-01-15: Another !myid # Duplicate ID ``` -------------------------------- ### Example of Ambiguous Date Format Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Shows a date range that is ambiguous in certain casual formats but unambiguous in ISO 8601. Set 'dateFormat' header or use EDTF for clarity. ```markwhen 2024-01-05 to 2024-01-06: Event ``` -------------------------------- ### Get or Create Cache for Timezone Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/cache.md Retrieves an existing cache instance for a given Luxon Zone object or creates a new one if it doesn't exist. Subsequent calls with the same timezone will return the identical cache instance. ```javascript import { Caches } from "@markwhen/parser"; import { DateTime } from "luxon"; const caches = new Caches(); // Get timezone zone const ny = DateTime.now().setZone("America/New_York").zone; const nycache = caches.zone(ny); // Same zone returns same cache instance const nycache2 = caches.zone(ny); console.log(nycache === nycache2); // true ``` -------------------------------- ### parseDateRange() Examples Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parse.md Demonstrates parsing various date formats using `parseDateRange`, including EDTF, casual, and slash formats. Shows that invalid formats return undefined. ```javascript import { parseDateRange } from "@markwhen/parser"; // EDTF format const range1 = parseDateRange("2024-01-15/2024-01-20"); console.log(range1?.fromDateTime.year); // 2024 // Casual format const range2 = parseDateRange("Jan 15, 2024 to Jan 20, 2024"); // Slash format const range3 = parseDateRange("1/15/2024 - 1/20/2024"); // Invalid format returns undefined const range4 = parseDateRange("not a date"); console.log(range4); // undefined ``` -------------------------------- ### Example of Invalid Recurrence Syntax Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Demonstrates an invalid 'every' clause with an unrecognized duration unit. Use valid units like days, weeks, months, or years. ```markwhen 2024-01-01: Event every 3 weekz # "weekz" is not recognized ``` -------------------------------- ### Example of Circular Relative Dates Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Illustrates a circular dependency between two events referencing each other. Ensure relative references form an acyclic graph to avoid unexpected results. ```markwhen 2024-01-01: Event A !a after !b plus 5 days 2024-01-10: Event B !b after !a plus 5 days ``` -------------------------------- ### Basic Timeline Configuration Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Configure timeline title, timezone, and date format using YAML front matter. ```markwhen --- title: My Timeline timezone: America/New_York dateFormat: d/M/y --- 2024: Events go here ``` -------------------------------- ### Common Workflows Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Illustrates practical usage patterns for the Markwhen parser library, including parsing and displaying events, handling errors, and exporting to iCalendar. ```APIDOC ## Parse and Display Events ### Description This workflow demonstrates how to parse a Markwhen string, flatten the resulting event tree, and then iterate through the events to display their details. ### Code Example ```javascript import { parse, flat } from "@markwhen/parser"; const markwhenText = ` title: My Timeline 2024-01-01: Event 1 2024-01-05: Event 2 `; const result = parse(markwhenText); // Get all events (flattened) const events = flat(result.events); events.forEach(event => { const { fromDateTime, toDateTime } = event.dateRangeIso; console.log(`${event.firstLine.restTrimmed} (${fromDateTime})`); }); ``` ## Handle Parse Errors ### Description This workflow shows how to check for and process any errors or warnings generated during the parsing of a Markwhen string. ### Code Example ```javascript import { parse } from "@markwhen/parser"; const userInput = ` Invalid Date: Event `; const result = parse(userInput); if (result.parseMessages.length > 0) { const errors = result.parseMessages.filter(m => m.type === "error"); console.error(`${errors.length} parse error(s) found.`); errors.forEach(err => { console.error(` Message: ${err.message}, Position: ${err.pos[0]}`); }); } ``` ## Export to iCalendar ### Description This workflow demonstrates how to parse a Markwhen timeline and then export the events into the standard iCalendar (.ics) format. ### Code Example ```javascript import { parse, toICal } from "@markwhen/parser"; import { writeFileSync } from "fs"; const markwhenText = ` title: My Events 2024-01-15: Meeting `; const result = parse(markwhenText); const ics = toICal(result, { name: "My Timeline Events" }); // Assuming you have writeFileSync available (e.g., in Node.js) // writeFileSync("timeline.ics", ics); console.log("iCalendar data generated:", ics); ``` ``` -------------------------------- ### Create a Basic Parsing Context Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Instantiates a new ParsingContext with default settings. ```javascript import { ParsingContext } from "@markwhen/parser"; import { DateTime } from "luxon"; // Basic context const context = new ParsingContext(); ``` -------------------------------- ### Get Prior Event End Time Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Retrieves the end time of the last event processed. ```typescript priorEventToDateTime(): DateTime | undefined ``` -------------------------------- ### CSS Usage of Predefined Colors Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/colors.md Demonstrates how to use the predefined COLORS array to construct CSS color strings for background and text. ```javascript import { COLORS } from "@markwhen/parser"; // Usage in CSS const bgColor = `rgba(${COLORS[0]}, 0.1)`; // green with 10% opacity const textColor = `rgb(${COLORS[1]})`; // blue solid ``` -------------------------------- ### Get Event by ID Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Looks up an event or event group by its unique ID. Returns undefined if no match is found. ```typescript getById(id: string): Eventy | undefined ``` -------------------------------- ### Get Zoned Reference Time from ParsingContext Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Returns the reference time ('now') adjusted to the current effective timezone. ```typescript get zonedNow(): DateTime ``` -------------------------------- ### Basic parse() Usage Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parse.md Demonstrates basic usage of the `parse` function with simple Markwhen markup. Shows how to access the timeline title and the number of events. ```javascript import { parse } from "@markwhen/parser"; const result = parse(` title: Company History 2010: Founded 2015: Series A Funding 2020: IPO `); console.log(result.header.title); // "Company History" console.log(result.events.children.length); // 3 events ``` -------------------------------- ### Get Parent Zone from ParsingContext Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Finds the timezone from the nearest parent group or header. This is used internally for timezone inheritance. ```typescript parentZone(): Zone ``` -------------------------------- ### parse() with Caching Enabled Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parse.md Illustrates enabling caching with the `parse` function for performance optimization during repeated parsing. Pass `true` to automatically create a new cache. ```javascript const cache = true; // Auto-create cache const result1 = parse(text1, cache); const result2 = parse(text2, cache); // Reuses zone/date caches ``` -------------------------------- ### Get Last Event in Tree Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/events.md Finds the last event in the tree according to the traversal order. Returns the node and its corresponding path. ```typescript function getLast(node: Eventy): { node: Eventy, path: Path } ``` ```javascript const { node, path } = getLast(result.events); ``` -------------------------------- ### CodeMirror 6 Integration for Parsing Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Shows how to integrate Markwhen parsing with CodeMirror 6 editor instances. It demonstrates re-parsing the document on every change and using the parse results (e.g., error ranges) for syntax highlighting. ```javascript import { parse } from "@markwhen/parser"; import { EditorView } from "@codemirror/view"; import { EditorState } from "@codemirror/state"; const view = new EditorView({ extensions: [ // ... other extensions ], dispatch: (tr) => { const newState = view.state.update(tr); // Re-parse on every change const result = parse(newState.doc.toString()); // Use ranges for syntax highlighting const highlights = result.ranges .filter(r => r.type === "error") .map(r => ({ from: r.from, to: r.to, class: "error" })); } }); ``` -------------------------------- ### Foldable Interface Source: https://github.com/mark-when/parser/blob/main/_autodocs/types.md Defines a region in the text that can be folded in an editor, including start and end indices and type. Used for editor fold markers. ```typescript interface Foldable { endIndex: number; type: "comment" | "section" | "header" | "event"; startLine: number; startIndex?: number; foldStartIndex?: number; } ``` -------------------------------- ### Profile Large Document Parsing Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Demonstrates how to profile the parsing of large Markwhen documents using `profileParse` to measure performance and identify bottlenecks. ```javascript const { parseResult, timings } = profileParse(largeText); console.log(`Parsed in ${timings.total}ms`); ``` -------------------------------- ### Get Prior Event from ParsingContext Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Returns the last event added to the context (tail), which is used as a reference point for parsing relative dates. ```typescript priorEvent(): Event | undefined ``` -------------------------------- ### Manage Colors and Tags Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Parses Markwhen text containing color-tagged items and demonstrates how to extract and use these color definitions for rendering. ```javascript import { parse, COLORS, HUMAN_COLORS, hexToRgb } from "@markwhen/parser"; const result = parse(` #project1: blue #project2: #FF69B4 2024-01-15: Task #project1 2024-01-20: Task #project2 `); // Get colors for rendering const tags = result.header.tags || {}; Object.entries(tags).forEach(([tagName, colorDef]) => { const rgb = hexToRgb(colorDef); const style = `background: rgb(${rgb})`; console.log(`#${tagName}: ${style}`); }); ``` -------------------------------- ### GroupRange Type Source: https://github.com/mark-when/parser/blob/main/_autodocs/types.md Extends DateRange to include maxFrom, representing the latest start time of any child event. Used for calculating event group ranges. ```typescript type GroupRange = DateRange & { maxFrom: DateTime }; ``` -------------------------------- ### Efficient ParsingContext Usage with Caching Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Demonstrates two approaches to using ParsingContext: a less efficient method creating a new context for each document and a more efficient method utilizing a shared cache. Use the cached approach for better performance when parsing multiple documents. ```javascript // Less efficient: new context per parse for (const doc of documents) { const ctx = new ParsingContext(); // ... parse doc } // More efficient: shared cache const cache = new Caches(); for (const doc of documents) { const ctx = new ParsingContext(undefined, cache); // ... parse doc } ``` -------------------------------- ### Apply Color to Tags in Markwhen Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/colors.md Demonstrates how to define and apply colors to tags within a Markwhen timeline. The parser records color definitions, which can then be processed by applications. ```markwhen #project1: #FF0080 #project2: blue 2024: Task for project1 #project1 2024: Task for project2 #project2 ``` -------------------------------- ### cache.md - Caching Mechanisms Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md Documentation for the `Cache` and `Caches` classes used for performance optimization. ```APIDOC ## Caching Mechanisms This section covers the caching classes designed to enhance parsing performance. ### `Cache` A class representing a single cache instance. ### `Caches` A class for managing multiple cache instances. ``` -------------------------------- ### Range Interface Source: https://github.com/mark-when/parser/blob/main/_autodocs/types.md Represents a text span with start and end character positions, a type, and optional associated data. Used for syntax highlighting and code folding. ```typescript interface Range { from: number; // Character position (inclusive) to: number; // Character position (exclusive) type: RangeType; content?: any; // Optional associated data } ``` -------------------------------- ### dateRangeToString() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/dates.md Converts a date range, defined by start and end DateTime objects, into a human-readable string. It automatically detects the appropriate granularity for formatting, from seconds to centuries. ```APIDOC ## dateRangeToString() ### Description Converts a date range to human-readable format with automatic granularity detection. ### Method `function dateRangeToString({ fromDateTime, toDateTime }: { fromDateTime: DateTime, toDateTime: DateTime }, formap?: DateFormap): string` ### Parameters #### Path Parameters * `fromDateTime` (DateTime) - Required - Start date. * `toDateTime` (DateTime) - Required - End date. * `formap` (DateFormap) - Optional - Format mapping (see Formatters below). Defaults to `ISOMap`. ### Returns **string** — Date range formatted based on granularity (e.g., "2024/01/15 - 2024/01/20" or "Jan 15 2024 - Jan 20 2024"). ### Automatic Granularity Selects format based on the coarser granularity of both dates: | Granularity | |-------------| | SECOND | | QUARTER_MINUTE | | MINUTE | | QUARTER_HOUR | | HOUR | | DAY | | MONTH | | YEAR | | DECADE | | CENT | ### Formatters (See Formatters section in source for details on `DateFormap`) ``` -------------------------------- ### colors.md - Color Utilities Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md Information on `COLORS` and `HUMAN_COLORS` constants, and utility functions `hexToRgb()` and `rgbStringToHex()`. ```APIDOC ## Color Utilities This section provides constants and functions for working with colors. ### Constants - **`COLORS`**: An object containing predefined color values. - **`HUMAN_COLORS`**: An object mapping human-readable color names to values. ### Functions - **`hexToRgb(hex: string): RgbColor`**: Converts a HEX color string to an RGB object. - **`rgbStringToHex(rgb: RgbColor): string`**: Converts an RGB object to a HEX color string. ``` -------------------------------- ### Example of Invalid Relative Date Syntax Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Highlights an invalid relative date where a non-numeric value is used for a duration. Use numbers for relative date calculations. ```markwhen tomorrow: Event after !event xyz days # "xyz" is not a valid number ``` -------------------------------- ### Date Range Notation in Markwhen Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Demonstrates different ways to specify date ranges in Markwhen, including using 'to', dashes, slashes, and relative date notations. ```markwhen Single date: 2024-01-15: Event name Range with "to": 2024-01-15 to 2024-01-20: Event name Range with dash: 2024-01-15 - 2024-01-20: Event name Range with slash: 2024-01-15 / 2024-01-20: Event name With time: Jan 15 2024 10:00am to 5:00pm: Meeting Relative: after !kickoff plus 5 days: Followup ``` -------------------------------- ### Get Timezone from ParsingContext Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Retrieves the effective timezone for the current parsing location. It searches parent groups, header properties, and falls back to the system timezone. ```typescript get timezone(): Zone ``` -------------------------------- ### Enable Caching for Repeated Parsing Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/cache.md Demonstrates how to enable caching by passing a Caches instance to the parse function, allowing for performance gains through reused timezone and YAML parsing across multiple documents. ```javascript import { parse, Caches } from "@markwhen/parser"; const cache = new Caches(); // Parse multiple documents reusing timezone caches const result1 = parse(text1, cache); const result2 = parse(text2, cache); // Timezone parsing and YAML parsing are reused across documents ``` -------------------------------- ### Cache Reuse for Performance Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Demonstrates how to reuse `Caches` between `ParsingContext` instances to improve performance. The second parse operation can benefit from cached zones and YAML data if the context is similar. ```javascript import { Caches, ParsingContext } from "@markwhen/parser"; const cache = new Caches(); // Parse 1: Creates and populates cache const ctx1 = new ParsingContext(undefined, cache); // ... parsing operations // Parse 2: Reuses cached zones and YAML const ctx2 = new ParsingContext(undefined, cache); // Faster if same timezone and similar structure ``` -------------------------------- ### Date and Time Utilities Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md A collection of utilities for working with dates, date ranges, and relative time expressions. ```APIDOC ## Date and Time Utilities ### Description Provides tools for date range manipulation, relative date parsing, and expansion of recurring events. ### Functions - `RelativeDate.diffFromString(raw)` → DurationLikeObject - `RelativeDate.from(raw, priorDate, plusOrMinus?)` → DateTime - `RelativeDate.fromPlus(raw, priorDate)` → DateTime - `RelativeDate.fromMinus(raw, priorDate)` → DateTime - `dateRangeToString({fromDateTime, toDateTime}, formap?)` → string - `expand(dateRange, recurrence, limit)` → DateRange[] - `expandEvent(event, limit)` → Event[] ``` -------------------------------- ### Mention/Reference Parsing Regex Source: https://github.com/mark-when/parser/blob/main/_autodocs/types.md Regular expression to match @mentions or @path/references. ```typescript const AT_REGEX = /@(\w\d\/]+)/g; ``` -------------------------------- ### Configure Timeline with Frontmatter Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Use frontmatter to set global timeline properties like title, timezone, and tag colors. This configuration applies to the entire timeline. ```markwhen --- title: My Life Timeline timezone: UTC tags: milestone: green education: blue work: orange --- group Education 2010 to 2014: College degree: Bachelor's in Computer Science school: MIT #education 2014 to 2016: Graduate School degree: Master's school: Stanford #education group Work History 2016 to 2019: Company A role: Software Engineer team_size: 5 #work 2019 to present: Company B role: Senior Engineer team_size: 12 #work #milestone ``` -------------------------------- ### Format Date Range with Automatic Granularity Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/dates.md Converts a date range (start and end DateTime objects) into a human-readable string. The function automatically detects the appropriate granularity for formatting. ```typescript function dateRangeToString( { fromDateTime, toDateTime }: { fromDateTime: DateTime, toDateTime: DateTime }, formap?: DateFormap ): string ``` -------------------------------- ### Event Properties Configuration Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Define properties for individual events, such as timezone, priority, and attendees. ```markwhen 2024-01-15: Team Meeting timezone: America/Chicago # Override parent timezone priority: high location: Conference Room A attendees: - Alice - Bob duration: "1 hour" id: project-kickoff # Event identifier startExpanded: true # Suggestion for UI ``` -------------------------------- ### parse.md - Core Parsing Functions Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md Documentation for the primary parsing functions including `parse()`, `parseDateRange()`, `parseHeader()`, `parseICal()`, `incrementalParse()`, and `profileParse()`. ```APIDOC ## Core Parsing Functions This section details the primary functions available for parsing Markwhen content. ### `parse(text: string, options?: ParseOptions): ParseResult` Parses a full Markwhen document string into a structured timeline. ### `parseDateRange(text: string, options?: ParseOptions): DateRange | null` Parses a string to extract a date range. ### `parseHeader(text: string, options?: ParseOptions): TimelineHeader` Parses only the header section of a Markwhen document. ### `parseICal(text: string, options?: ParseOptions): ParseResult` Parses an iCalendar formatted string into a Markwhen timeline. ### `incrementalParse(text: string, context: ParsingContext, options?: ParseOptions): ParseResult` Performs incremental parsing of Markwhen content based on a provided parsing context. ### `profileParse(text: string, options?: ParseOptions): ProfileParseResult` Parses Markwhen content and provides profiling information about the parsing process. ``` -------------------------------- ### Get Event Node by Path Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/events.md Retrieves a specific event node from the Eventy tree using a given path. The path is an array of indices representing the traversal through child nodes. ```typescript function get(root: Eventy, path: Path): Eventy | undefined ``` ```javascript const event = get(result.events, [0, 1, 0]); // Gets root.children[0].children[1].children[0] ``` -------------------------------- ### ParsingContext Constructor Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Initializes a new ParsingContext. It can be configured with a reference date/time, a cache for performance, and a callback to retrieve a prior event for relative date parsing. ```APIDOC ## new ParsingContext(now?, cache?, getPriorEvent?) ### Description Initializes a new ParsingContext instance. ### Parameters #### Path Parameters - **now** (DateTime | string) - Optional - Reference time for relative dates. Defaults to DateTime.now(). - **cache** (Caches) - Optional - Cache instance for performance. Defaults to undefined. - **getPriorEvent** (Function) - Optional - Callback to get prior event for relative parsing. Defaults to undefined. ### Examples ```javascript import { ParsingContext } from "@markwhen/parser"; import { DateTime } from "luxon"; // Basic context const context = new ParsingContext(); // With custom reference date const context = new ParsingContext("2024-06-15T10:00:00Z"); // With cache for performance import { Caches } from "@markwhen/parser"; const cache = new Caches(); const context = new ParsingContext(undefined, cache); // With custom prior event callback const context = new ParsingContext( undefined, undefined, (ctx) => ctx.events.children[0] ); ``` ``` -------------------------------- ### Supported Date Formats in Markwhen Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Illustrates various date and time formats supported by Markwhen, including EDTF, casual, slash, time, combinations, relative dates, and recurrence rules. ```markwhen EDTF (ISO 8601): 2024-01-15 2024-01-15T10:30:00Z 2024-01-15T10:30:00-05:00 2024-W03 (week notation) 2024-01-15/2024-01-20 (range) Casual: Jan 15, 2024 January 15 2024 15 January 2024 15 Jan 2024 2024 (year only) Slash Format (configurable): 1/15/2024 (US: month/day/year) 15/1/2024 (EU: day/month/year) Time: 10:30am, 10:30 PM, 22:30 (24-hour) Combinations: Jan 15 2024 10:30am 2024-01-15T10:30:00Z Relative (from prior event): tomorrow next week after !eventId plus 5 days before 2024-01-20 Recurrence: every day until 2024-12-31 every week for 10 times every month x 12 ``` -------------------------------- ### push() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/events.md Inserts a new event or event group into the event tree at a specified path. Optionally, a tail event can be provided. ```APIDOC ## push() ### Description Inserts a node into the tree at the given path. ### Signature ```typescript function push( node: Event | EventGroup, onto: EventGroup, path?: Path, tail?: Event ): { path: number[], tail?: Event } ``` ``` -------------------------------- ### Extract Header Metadata with parseHeader Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parse.md Use `parseHeader` to extract title, timezone, and date format from a timeline's header. It also returns the line index where the header ends, indicating the start of events. ```javascript import { parseHeader } from "@markwhen/parser"; const { header, headerEndLineIndex } = parseHeader(` title: My Timeline timezone: America/New_York dateFormat: d/M/y 2024: First event `); console.log(header.title); // "My Timeline" console.log(header.timezone); // "America/New_York" console.log(headerEndLineIndex); // 4 (events start at line 5) ``` -------------------------------- ### Get Parsed Result or Fallback Source: https://github.com/mark-when/parser/blob/main/_autodocs/errors.md Attempts to parse Markwhen text, returning the parsed result or a predefined `emptyTimeline` fallback if the result is invalid or lacks events. Ensures a valid structure is always returned. ```javascript function getParsed(text) { const result = parse(text); // Verify we have at least some content if (!result || !result.events) { return emptyTimeline; } return result; } ``` -------------------------------- ### Tree Navigation Utilities Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md These functions allow for efficient traversal and manipulation of the parsed event tree structure. ```APIDOC ## Tree Navigation Utilities ### Description Functions for traversing and manipulating the hierarchical event tree. ### Functions - `iter(eventy, path?)` — Depth-first traversal generator - `iterateTreeFromPath(root, path)` — Traversal from specific path - `flat(node)` — Flatten to events only - `flatMap(node, mapper)` — Traverse with function - `get(root, path)` → Eventy | undefined - `getLast(node)` → {node, path} - `push(node, onto, path?, tail?)` → {path, tail} - `ranges(root?)` → GroupRange | undefined - `eventRange(event)` → GroupRange ``` -------------------------------- ### Create Parsing Context with Custom Reference Date Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Instantiates a new ParsingContext using a specific date and time as the reference point. ```javascript import { ParsingContext } from "@markwhen/parser"; import { DateTime } from "luxon"; // With custom reference date const context = new ParsingContext("2024-06-15T10:00:00Z"); ``` -------------------------------- ### Parse Event Metadata Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/events.md Parses a Markwhen event string to extract tags, completion percentage, and supplemental markdown content like lists and images. The `parse` function is used to get the event object, from which these properties can be accessed. ```javascript import { parse } from "@markwhen/parser"; const result = parse(` 2024-01-15: Quarterly Review #hr #important Location: [Conference Room 5](location) Progress: 75% - Review Q4 results - Plan Q1 initiatives ![graph.png](https://example.com/graph.png) `); const event = result.events.children[0]; console.log(event.tags); // ["hr", "important"] console.log(event.percent); // 75 console.log(event.supplemental.length); // 2 (list, image) ``` -------------------------------- ### Custom Parsing with ParsingContext Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Demonstrates how to create a custom parsing function using `ParsingContext` for integrations like language servers or editor plugins. It parses only the body of the text, skipping the header. ```javascript import { ParsingContext, parsePastHeader } from "@markwhen/parser"; import { DateTime } from "luxon"; function parseWithContext(text, startLine = 0) { const lines = text.split("\n"); const lengthAtIndex = []; let pos = 0; for (const line of lines) { lengthAtIndex.push(pos); pos += line.length + 1; // +1 for newline } const context = new ParsingContext(DateTime.now()); // Parse body only (skip header) parsePastHeader(startLine, context, lines, lengthAtIndex); return context.toTimeline(); } ``` -------------------------------- ### RelativeDate.diffFromString() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/dates.md Parses duration amounts from a string into a Luxon-compatible object. It recognizes various units like milliseconds, seconds, minutes, hours, days, weeks, months, and years, and can combine multiple amounts. ```APIDOC ## RelativeDate.diffFromString() ### Description Parses duration amounts from a string into a Luxon-compatible object. Supports various units and combinations. ### Method `static diffFromString(raw: string): DurationLikeObject` ### Parameters #### Path Parameters * `raw` (string) - Required - Duration string (e.g., "2d 3h", "1 week 2 days") ### Returns Object mapping unit names to values: `{ days: 2, hours: 3, milliseconds: 0, ...}` ### Request Example ```javascript import { RelativeDate } from "@markwhen/parser"; const diff = RelativeDate.diffFromString("2 days 3 hours"); // { days: 2, hours: 3 } ``` ``` -------------------------------- ### Convert ICS to Markwhen Format with parseICal Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parse.md The `parseICal` function converts iCalendar (ICS) data into Markwhen format or a parsed JSON object. It extracts key event details like summary, description, start, and end times, preserving timezone information. ```typescript import { parseICal } from "@markwhen/parser"; const ics = `BEGIN:VCALENDAR VERSION:2.0 PRODID:-//My App//EN BEGIN:VEVENT UID:event1@example.com DTSTART:20240115T100000Z DTEND:20240115T110000Z SUMMARY:Team Meeting DESCRIPTION:Weekly sync END:VEVENT END:VCALENDAR`; const markwhen = parseICal(ics); console.log(markwhen); // Output: "2024-01-15T10:00:00Z / 2024-01-15T11:00:00Z: Team Meeting\n..." // Parse directly to JSON const parsed = parseICal(ics, { output: "json" }); console.log(parsed.events.children[0].firstLine.rest); // "Team Meeting" ``` -------------------------------- ### Image Parsing Regex Source: https://github.com/mark-when/parser/blob/main/_autodocs/types.md Regular expression to match markdown image syntax with alt text and URL. ```typescript const IMAGE_REGEX = /!\^\[([^\]\<\>]*)\]\(((https?:\/\/)?\w\d.\/\&\?=\-\#:,_]+)\)/; ``` -------------------------------- ### profileParse() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parse.md Parses a timeline while measuring performance timing for each phase. It returns the standard ParseResult along with detailed timings for parsing different sections. ```APIDOC ## profileParse() ### Description Parses a timeline while measuring performance timing for each phase. ### Method ```typescript profileParse( timelineString?: string | string[] | Text, cache?: Caches | true, now?: DateTime | string ): { parseResult: ParseResult, timings: ParseTimings } ``` ### Parameters #### Path Parameters - **timelineString** (string | string[] | Text) - Optional - Markwhen markup (same as `parse()`). - **cache** (Caches | true) - Optional - Cache instance (same as `parse()`). - **now** (DateTime | string) - Optional - Reference date (same as `parse()`). Default: DateTime.now(). ### Returns Object with: - `parseResult`: Standard ParseResult - `timings.total`: Total parse time in milliseconds - `timings.lines`: Time to split text into lines - `timings.header`: Time to parse YAML front matter - `timings.body`: Time to parse events ``` -------------------------------- ### Constants Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Provides predefined constants for colors, date formats, and regular expressions used in parsing and formatting. ```APIDOC ## COLORS ### Description A 11-color RGB palette used for default event coloring. ## HUMAN_COLORS ### Description An array of human-readable color names (e.g., "green", "blue"). ## AMERICAN_DATE_FORMAT, EUROPEAN_DATE_FORMAT, DATE_TIME_FORMAT_MONTH_YEAR, DATE_TIME_FORMAT_YEAR ### Description Predefined string formats for parsing and displaying dates and datetimes. ## Regex patterns (EVENT_ID_REGEX, TAG_REGEX, etc.) ### Description Regular expression constants used internally for pattern matching during parsing. ``` -------------------------------- ### utilities.md - Document Modification and Export Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md Utility functions for document modification and export, including `headerSet()`, `entrySet()`, `toArray()`, `mapUrls()`, and `toICal()`. ```APIDOC ## Document Utilities This section details utility functions for modifying and exporting Markwhen documents. ### Functions - **`headerSet(header: TimelineHeader, key: string, value: any): TimelineHeader`**: Sets a property in the timeline header. - **`entrySet(obj: object, path: string, value: any): object`**: Sets a nested property in an object. - **`toArray(data: any): any[]`**: Converts input data to an array. - **`mapUrls(text: string, callback: (url: string) => string): string`**: Maps URLs within a text string using a callback function. - **`toICal(timeline: Timeline, options?: ICalOptions): string`**: Exports a Markwhen timeline to iCalendar format. ``` -------------------------------- ### Timezone Inheritance Testing Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Illustrates how timezones are inherited and managed within `ParsingContext`, including setting a header timezone and testing timezone resolution at different paths, even within nested contexts. ```javascript import { ParsingContext } from "@markwhen/parser"; const context = new ParsingContext(); context.header.timezone = "America/New_York"; // Check effective timezone at various paths console.log(context.timezone.name); // "America/New_York" // Add a group with different timezone const subContext = new ParsingContext( undefined, undefined, (c) => c.tail ); subContext.header = context.header; // Inherit header subContext.events = context.events; // Share tree subContext.currentPath = [0, 1]; // Set position in tree console.log(subContext.timezone.name); // Searches from path [0, 1] ``` -------------------------------- ### Create Parsing Context with Cache Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/parsing-context.md Instantiates a new ParsingContext, providing a Caches instance for performance optimization. ```javascript import { ParsingContext } from "@markwhen/parser"; import { Caches } from "@markwhen/parser"; import { DateTime } from "luxon"; // With cache for performance const cache = new Caches(); const context = new ParsingContext(undefined, cache); ``` -------------------------------- ### Format Date Range with ISO Map Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/dates.md Formats a date range using the ISO 8601 standard. Requires importing ISOMap. ```javascript import { dateRangeToString, ISOMap } from "@markwhen/parser"; import { DateTime } from "luxon"; const from = DateTime.fromISO("2024-01-15"); const to = DateTime.fromISO("2024-01-20"); const result = dateRangeToString({ fromDateTime: from, toDateTime: to }); console.log(result); // "2024-01-15 / 2024-01-20" ``` -------------------------------- ### Traverse Event Hierarchy Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/events.md Demonstrates how to traverse the event hierarchy manually using recursion. It distinguishes between event groups and individual events, printing their titles or first lines. ```javascript import { parse, isEvent, flat } from "@markwhen/parser"; const result = parse(markwhenText); const root = result.events; // Get all flat events (ignoring hierarchy) const allEvents = flat(root); console.log(`Total events: ${allEvents.length}`); // Traverse tree manually function printTree(group, indent = 0) { const pad = " ".repeat(indent); console.log(`${pad}Group: ${group.title || "(root)"}`); for (const child of group.children) { if (isEvent(child)) { console.log(`${pad} Event: ${child.firstLine.restTrimmed}`); } else { printTree(child, indent + 1); } } } printTree(root); ``` -------------------------------- ### Use Incremental Parsing for Editors Source: https://github.com/mark-when/parser/blob/main/_autodocs/README.md Shows the usage of `incrementalParse` for efficient updates in editor environments, requiring the previous parse result, new text, and changes. ```javascript result = incrementalParse(prev, newText, changes); ``` -------------------------------- ### Customizing Date Formatting Source: https://github.com/mark-when/parser/blob/main/_autodocs/configuration.md Customize the output format for date ranges using `dateRangeToString`. Define custom formats and separators for different date weights like days and months. ```javascript import { dateRangeToString, Weight } from "@markwhen/parser"; const customMap = { [Weight.DAY]: { format: "dd MMMM yyyy", separator: " through " }, [Weight.MONTH]: { format: "MMMM yyyy", separator: " - " }, // ... other weights }; const formatted = dateRangeToString( { fromDateTime, toDateTime }, customMap ); ``` -------------------------------- ### parsing-context.md - Advanced Parsing Context Source: https://github.com/mark-when/parser/blob/main/_autodocs/INDEX.md Information on the `ParsingContext` class for advanced custom parsing scenarios. ```APIDOC ## Advanced Parsing Context This section describes the `ParsingContext` class for advanced customization of the parsing process. ### `ParsingContext` Class Provides context and state for advanced, custom parsing scenarios. Allows for fine-grained control over how Markwhen content is processed. ``` -------------------------------- ### Reset Caches Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/cache.md Explains that caches are not directly exposed for manual clearing. To reset all caches, a new instance of Caches must be created. ```javascript // Caches are not exposed for manual clearing currently // Create a new Caches() instance to reset all caches const newCache = new Caches(); ``` -------------------------------- ### headerSet() Source: https://github.com/mark-when/parser/blob/main/_autodocs/api-reference/utilities.md Updates the YAML front matter of a Markwhen timeline. It can either merge new values with existing ones or replace the entire header. ```APIDOC ## headerSet() ### Description Updates the YAML front matter of a timeline. ### Method ```typescript function headerSet( mw: string, value: Record, merge?: boolean ): { from: number, to?: number, insert: string } ``` ### Parameters #### Path Parameters - **mw** (`string`) - Required - The full Markwhen timeline text. - **value** (`Record`) - Required - Fields to set in the header. - **merge** (`boolean`) - Optional - If true, merges with existing header. If false, replaces entire header. Defaults to false. ### Returns An edit operation with: - `from`: Character position to start replacement - `to`: Character position to end replacement (optional) - `insert`: New YAML text to insert ### Examples ```javascript import { headerSet } from "@markwhen/parser"; const markwhen = ` --- title: Old Title timezone: UTC --- 2024: Event `; const change = headerSet(markwhen, { title: "New Title", author: "John Doe" }); // Apply to document const updated = markwhen.slice(0, change.from) + change.insert + (change.to ? markwhen.slice(change.to) : ""); ``` ```