# rtext-writer

> Rich Text library

Latest version **0.1.1** (published 2017-08-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install rtext-writer
pnpm add rtext-writer
yarn add rtext-writer
bun add rtext-writer
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.1 |
| Published | 2017-08-03 |
| First published | 2017-07-28 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Boris Kaul |
| Maintainers | localvoid |
| Keywords | rich, text |

## Links

- npm: https://www.npmjs.com/package/rtext-writer
- Repository: https://github.com/localvoid/rtext
- Issues: https://github.com/localvoid/rtext/issues
- npm.io page: https://npm.io/package/rtext-writer

## Alternatives

- [ext-list](https://npm.io/package/ext-list.md) — 6.3M weekly downloads
- [@lexical/selection](https://npm.io/package/@lexical/selection.md) — 3.8M weekly downloads
- [@lexical/text](https://npm.io/package/@lexical/text.md) — 3.6M weekly downloads
- [@lexical/clipboard](https://npm.io/package/@lexical/clipboard.md) — 3.0M weekly downloads
- [@tiptap/extension-mention](https://npm.io/package/@tiptap/extension-mention.md) — 3.0M weekly downloads

## Recent versions

- 0.1.1 (latest) — 2017-08-03
- 0.1.0 — 2017-07-28

## README

# Rich Text Writer

`rtext-writer` package provides an easy-to-use interface for composing rich texts. It is using a
[builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) with a chainable API.

```ts
class RichTextWriter {
  constructor();
  write(...ws: Array<string | RichText | ((w: RichTextWriter) => void)>): this;
  begin(type: string, data?: any): this;
  beginKey(key: string, type: string, data?: any): this;
  end(type: string): this;
  endKey(key: string, type: string): this;
  continue(type: string, data?: any): this;
  continueKey(key: string, type: string, data?: any): this;
  compose(): RichText;
}
```

API is pretty simple, `begin()` and `end()` methods are used to specify annotations, `write()` is used to write text and
`compose()` to get results.

`beginKey()` and `endKey()` are used to create overlapping annotations that have the same `type`. When `endKey()` is
used, it will try to find an annotation with a matching `type` and `key`.

`continue()` methods will reuse the last annotation when it has the same `end` position and all properties are matching.

### Utility functions

```ts
function richText(): RichTextWriter;

function rt(
  literals: TemplateStringsArray,
  ...placeholders: Array<string | RichText | ((w: RichTextWriter) => void)>,
): (w: RichTextWriter) => void;

function annotate(text: string, regexp: RegExp, type: string, data?: any, key?: string): RichText;
```

`richText()` is a simple helper function that will instantiate `RichTextWriter` objects.

`rt()` is a tagged template literal that will create a writer function.

`annotate()` will annotate all text regions matched by `regexp`.

## Example

```ts
function expected(value: any) {
  return function(w: RichTextWriter) {
    w.begin("expected").write(JSON.stringify(value)).end("expected");
  };
}

function received(value: any) {
  return function(w: RichTextWriter) {
    w.begin("received").write(JSON.stringify(value)).end("received");
  };
}

const a = { value: 1 };
const b = { value: 2 };

const errorMessage = richText()
  .begin("errorTitle").write("Error Title\n").end("errorTitle")
  .write("Expected: ", expected(a), "\n")
  .write("Received: ", received(b), "\n")
  .compose();
```

## Example from the iko library

[iko](https://github.com/localvoid/iko) has a high-level API that was built on top of `RichTextWriter`, and it looks
like this:

```ts
export class NumberAssertion extends Assertion<number> {
  toBeApproximatelyEqual(number: number, epsilon = Number.EPSILON): this {
    const a = this.obj;
    const b = number;
    const aAbs = Math.abs(a);
    const bAbs = Math.abs(b);
    const pass = Math.abs(a - b) <= (aAbs < bAbs ? bAbs : aAbs) * epsilon;

    if (!pass) {
      const message = errMsg()
        .matcherHint("toBeApproximatelyEqual", "received", "expected", "epsilon")
        .hint(rt`abs(${rA} - ${eB}) <= (abs(${rA}) < abs(${eB}) ? abs(${eB}) : abs(${rA})) * ${eE}\n\n`)
        .info(rt`Expected number to be approximately equal to ${e(b)}, intstead received ${r(a)}\n`);

      throw new AssertionError(message.compose(), this.toBeApproximatelyEqual);
    }

    return this;
  }
}
```

---
_Source: https://npm.io/package/rtext-writer · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
