Skip to content

Commit

Permalink
New: Add typedoc setting
Browse files Browse the repository at this point in the history
  • Loading branch information
Wanasit Tanakitrungruang committed Mar 7, 2021
2 parents b582ae7 + e047e2e commit ac27496
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 30 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"jest": "^26.1.0",
"prettier": "^2.0.5",
"ts-jest": "^26.1.1",
"typedoc": "^0.20.25",
"typescript": "^4.1.3"
},
"husky": {
Expand All @@ -41,6 +42,7 @@
},
"scripts": {
"build": "tsc -p tsconfig.build.json",
"document": "typedoc",
"prepare": "npm run build",
"eslint": "eslint src test",
"prettier": "npm run prettier:src && npm run prettier:test",
Expand Down
53 changes: 42 additions & 11 deletions src/chrono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,26 @@ import { Component, ParsedResult, ParsingOption } from "./index";
import { AsyncDebugBlock, DebugHandler } from "./debugging";
import { createCasualConfiguration } from "./locales/en";

/**
* Chrono configuration.
* It is simply an ordered list of parsers and refiners
*/
export interface Configuration {
parsers: Parser[];
refiners: Refiner[];
}

/**
* A abstraction for Chrono *Parser*.
*
* Each parser should recognize and handle a certain date format.
* Chrono uses multiple parses (and refiners) together for parsing the input.
*
* The parser implementation must provide {@Link pattern | pattern()} for the date format.
*
* The {@Link extract | extract()} method is called with the pattern's *match*.
* The matching and extracting is controlled and adjusted to avoid for overlapping results.
*/
export interface Parser {
pattern(context: ParsingContext): RegExp;
extract(
Expand All @@ -16,10 +31,19 @@ export interface Parser {
): ParsingComponents | ParsingResult | { [c in Component]?: number } | null;
}

/**
* A abstraction for Chrono *Refiner*.
*
* Each refiner takes the list of results (from parsers or other refiners) and returns another list of results.
* Chrono applies each refiner in order and return the output from the last refiner.
*/
export interface Refiner {
refine: (context: ParsingContext, results: ParsingResult[]) => ParsingResult[];
}

/**
* The Chrono object.
*/
export class Chrono {
parsers: Array<Parser>;
refiners: Array<Refiner>;
Expand All @@ -30,13 +54,27 @@ export class Chrono {
this.refiners = [...configuration.refiners];
}

parseDate(text, refDate?, opt?): Date {
const results = this.parse(text, refDate, opt);
/**
* Create a shallow copy of the Chrono object with the same configuration (`parsers` and `refiners`)
*/
clone(): Chrono {
return new Chrono({
parsers: [...this.parsers],
refiners: [...this.refiners],
});
}

/**
* A shortcut for calling {@Link parse | parse() } then transform the result into Javascript's Date object
* @return Date object created from the first parse result
*/
parseDate(text: string, referenceDate?: Date, option?: ParsingOption): Date | null {
const results = this.parse(text, referenceDate, option);
return results.length > 0 ? results[0].start.date() : null;
}

parse(text: string, refDate?: Date, opt?: ParsingOption): ParsedResult[] {
const context = new ParsingContext(text, refDate || new Date(), opt || {});
parse(text: string, referenceDate?: Date, option?: ParsingOption): ParsedResult[] {
const context = new ParsingContext(text, referenceDate || new Date(), option || {});

let results = [];
this.parsers.forEach((parser) => {
Expand All @@ -55,13 +93,6 @@ export class Chrono {
return results;
}

clone(): Chrono {
return new Chrono({
parsers: [...this.parsers],
refiners: [...this.refiners],
});
}

private static executeParser(context: ParsingContext, parser: Parser) {
const results = [];
const pattern = parser.pattern(context);
Expand Down
6 changes: 6 additions & 0 deletions src/common/abstractRefiners.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ParsingContext, Refiner } from "../chrono";
import { ParsingResult } from "../results";

/**
* A special type of {@link Refiner} to filter the results
*/
export abstract class Filter implements Refiner {
abstract isValid(context: ParsingContext, result: ParsingResult): boolean;

Expand All @@ -9,6 +12,9 @@ export abstract class Filter implements Refiner {
}
}

/**
* A special type of {@link Refiner} to merge consecutive results
*/
export abstract class MergingRefiner implements Refiner {
abstract shouldMergeResults(
textBetween: string,
Expand Down
6 changes: 6 additions & 0 deletions src/debugging.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
export type AsyncDebugBlock = () => unknown;
export type DebugConsume = (debugLog: AsyncDebugBlock) => void;

/**
* @internal
*/
export interface DebugHandler {
debug: DebugConsume;
}

/**
* @internal
*/
export class BufferedDebugHandler implements DebugHandler {
private buffer: Array<AsyncDebugBlock>;
constructor() {
Expand Down
87 changes: 70 additions & 17 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
import { DebugHandler, DebugConsume } from "./debugging";
import * as en from "./locales/en";
import { Chrono } from "./chrono";
import { Chrono, Parser, Refiner } from "./chrono";

export { en, Chrono };
export const strict = en.strict;
export const casual = en.casual;

export function parse(text: string, ref?: Date, option?: ParsingOption): ParsedResult[] {
return casual.parse(text, ref, option);
}

export function parseDate(text: string, ref?: Date, option?: ParsingOption): Date {
return casual.parseDate(text, ref, option);
}
export { en, Chrono, Parser, Refiner };

export interface ParsingOption {
/**
* To parse only forward dates (the results should be after the reference date).
* This effects date/time implication (e.g. weekday or time mentioning)
*/
forwardDate?: boolean;
debug?: DebugHandler | DebugConsume;

/**
* Additional timezone keywords for the parsers to recognize
*/
timezones?: { string: number };

/**
* Internal debug event handler.
* @internal
*/
debug?: DebugHandler | DebugConsume;
}

/**
* Parsed result or final output.
* Each result object represents a date/time (or date/time-range) mentioning in the input.
*/
export interface ParsedResult {
readonly refDate: Date;
readonly index: number;
Expand All @@ -28,13 +35,35 @@ export interface ParsedResult {
readonly start: ParsedComponents;
readonly end?: ParsedComponents;

readonly date: () => Date;
/**
* Create a javascript date object (from the result.start).
*/
date(): Date;
}

/**
* A collection of parsed date/time components (e.g. day, hour, minute, ..., etc).
*
* Each parsed component has three different levels of certainty.
* - *Certain* (or *Known*): The component is directly mentioned and parsed.
* - *Implied*: The component is not directly mentioned, but implied by other parsed information.
* - *Unknown*: Completely no mention of the component.
*/
export interface ParsedComponents {
readonly isCertain: (c: Component) => boolean;
readonly get: (c: Component) => number | null;
readonly date: () => Date;
/**
* Check the component certainly if the component is *Certain* (or *Known*)
*/
isCertain(component: Component): boolean;

/**
* Get the component value for either *Certain* or *Implied* value.
*/
get(component: Component): number | null;

/**
* @return a javascript date object.
*/
date(): Date;
}

export type Component =
Expand All @@ -61,3 +90,27 @@ import * as ja from "./locales/ja";
import * as pt from "./locales/pt";
import * as nl from "./locales/nl";
export { de, fr, ja, pt, nl };

/**
* A shortcut for {@link en | chrono.en.strict}
*/
export const strict = en.strict;

/**
* A shortcut for {@link en | chrono.en.casual}
*/
export const casual = en.casual;

/**
* A shortcut for {@link en | chrono.en.casual.parse()}
*/
export function parse(text: string, ref?: Date, option?: ParsingOption): ParsedResult[] {
return casual.parse(text, ref, option);
}

/**
* A shortcut for {@link en | chrono.en.casual.parseDate()}
*/
export function parseDate(text: string, ref?: Date, option?: ParsingOption): Date {
return casual.parseDate(text, ref, option);
}
33 changes: 32 additions & 1 deletion src/locales/en/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* Chrono components for English support (*parsers*, *refiners*, and *configuration*)
*
* @module
*/

import ENTimeUnitWithinFormatParser from "./parsers/ENTimeUnitWithinFormatParser";
import ENMonthNameLittleEndianParser from "./parsers/ENMonthNameLittleEndianParser";
import ENMonthNameMiddleEndianParser from "./parsers/ENMonthNameMiddleEndianParser";
Expand All @@ -21,20 +27,39 @@ import { Chrono, Configuration } from "../../chrono";
import SlashDateFormatParser from "../../common/parsers/SlashDateFormatParser";
import ENTimeUnitCasualRelativeFormatParser from "./parsers/ENTimeUnitCasualRelativeFormatParser";

// Shortcuts
/**
* Chrono object configured for parsing *casual* English
*/
export const casual = new Chrono(createCasualConfiguration(false));

/**
* Chrono object configured for parsing *strict* English
*/
export const strict = new Chrono(createConfiguration(true, false));

/**
* Chrono object configured for parsing *UK-style* English
*/
export const GB = new Chrono(createConfiguration(false, true));

/**
* A shortcut for en.casual.parse()
*/
export function parse(text: string, ref?: Date, option?: ParsingOption): ParsedResult[] {
return casual.parse(text, ref, option);
}

/**
* A shortcut for en.casual.parseDate()
*/
export function parseDate(text: string, ref?: Date, option?: ParsingOption): Date {
return casual.parseDate(text, ref, option);
}

/**
* Create a default *casual* {@Link Configuration} for English chrono.
* It calls {@Link createConfiguration} and includes additional parsers.
*/
export function createCasualConfiguration(littleEndian = false): Configuration {
const option = createConfiguration(false, littleEndian);
option.parsers.unshift(new ENCasualDateParser());
Expand All @@ -45,6 +70,12 @@ export function createCasualConfiguration(littleEndian = false): Configuration {
return option;
}

/**
* Create a default {@Link Configuration} for English chrono
*
* @param strictMode If the timeunit mentioning should be strict, not casual
* @param littleEndian If format should be date-first/littleEndian (e.g. en_UK), not month-first/middleEndian (e.g. en_US)
*/
export function createConfiguration(strictMode = true, littleEndian = false): Configuration {
return includeCommonConfiguration(
{
Expand Down
12 changes: 12 additions & 0 deletions src/locales/fr/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* Chrono components for French support (*parsers*, *refiners*, and *configuration*)
*
* @module
*/

import { includeCommonConfiguration } from "../../configurations";
import { ParsedResult, ParsingOption } from "../../index";
import { Chrono, Configuration } from "../../chrono";
Expand Down Expand Up @@ -26,6 +32,9 @@ export function parseDate(text: string, ref?: Date, option?: ParsingOption): Dat
return casual.parseDate(text, ref, option);
}

/**
* @ignore (to be documented later)
*/
export function createCasualConfiguration(littleEndian = true): Configuration {
const option = createConfiguration(false, littleEndian);
option.parsers.unshift(new FRCasualDateParser());
Expand All @@ -34,6 +43,9 @@ export function createCasualConfiguration(littleEndian = true): Configuration {
return option;
}

/**
* @ignore (to be documented later)
*/
export function createConfiguration(strictMode = true, littleEndian = true): Configuration {
return includeCommonConfiguration(
{
Expand Down
12 changes: 12 additions & 0 deletions src/locales/ja/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* Chrono components for Japanese support (*parsers*, *refiners*, and *configuration*)
*
* @module
*/

import JPStandardParser from "./parsers/JPStandardParser";
import JPMergeDateRangeRefiner from "./refiners/JPMergeDateRangeRefiner";
import JPCasualDateParser from "./parsers/JPCasualDateParser";
Expand All @@ -17,12 +23,18 @@ export function parseDate(text: string, ref?: Date, option?: ParsingOption): Dat
return casual.parseDate(text, ref, option);
}

/**
* @ignore (to be documented later)
*/
export function createCasualConfiguration(): Configuration {
const option = createConfiguration();
option.parsers.unshift(new JPCasualDateParser());
return option;
}

/**
* @ignore (to be documented later)
*/
export function createConfiguration(): Configuration {
return {
parsers: [new JPStandardParser()],
Expand Down
Loading

0 comments on commit ac27496

Please sign in to comment.