Skip to content

Commit

Permalink
docs(harper.js): added more detailed and beginner-friendly documentat…
Browse files Browse the repository at this point in the history
…ion on linting
  • Loading branch information
elijah-potter committed Dec 30, 2024
1 parent ace693c commit ef4d503
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 8 deletions.
2 changes: 1 addition & 1 deletion packages/harper.js/examples/raw-web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// We can import `harper.js` using native ECMAScript syntax.
import { WorkerLinter } from 'https://unpkg.com/[email protected]/dist/harper.js';

// Since we are working the browser, we can use either `WorkerLinter`, which doesn't block the event loop, or `LocalLinter`, which does.
// Since we are working in the browser, we can use either `WorkerLinter`, which doesn't block the event loop, or `LocalLinter`, which does.
let linter = new WorkerLinter();

// Every time the `<textarea/>` received an input, we process it and update our list.
Expand Down
6 changes: 5 additions & 1 deletion packages/harper.js/src/Linter.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import type { Lint, Span, Suggestion } from 'wasm';
import { LintConfig } from './main';

/** A interface for an object that can perform linting actions. */
/** An interface for an object that can perform linting actions. */
export default interface Linter {
/** Complete any setup that is necessary before linting. This may include downloading and compiling the WebAssembly binary.
* This setup will complete when needed regardless of whether you call this function.
* This function exists to allow you to do this work when it is of least impact to the user experiences (i.e. while you're loading something else). */
setup(): Promise<void>;

/** Lint the provided text. */
lint(text: string): Promise<Lint[]>;

/** Apply a suggestion to the given text, returning the transformed result. */
applySuggestion(text: string, suggestion: Suggestion, span: Span): Promise<string>;

/** Determine if the provided text is likely to be intended to be English.
* The algorithm can be described as "proof of concept" and as such does not work terribly well.*/
isLikelyEnglish(text: string): Promise<boolean>;

/** Determine which parts of a given string are intended to be English, returning those bits.
* The algorithm can be described as "proof of concept" and as such does not work terribly well.*/
isolateEnglish(text: string): Promise<string>;
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/routes/docs/about/+page.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: What Is Harper?
---

Harper is a grammar checker designed to run anywhere there is text (so really, anywhere).
Most Harper users are catching their mistakes in Neovim, [Obsidian](/obsidian), or Visual Studio Code.
Most Harper users are catching their mistakes in Neovim, [Obsidian](./integrations/obsidian), or Visual Studio Code.

<script>
import Editor from "$lib/Editor.svelte"
Expand Down
17 changes: 12 additions & 5 deletions packages/web/src/routes/docs/harperjs/introduction/+page.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ title: Introduction to harper.js
If you're a developer, odds are that you are using JavaScript or TypeScript on a daily basis.
Your project probably has a least a little bit of either.

Furthermore, a plurality of focused authorship happens inside a web browser or [Electron-based app](https://www.electronjs.org/).
Given this, we want to create an environment where it is as easy as possible to integrate fantastic grammar checking into web applications.
Furthermore, a plurality of focused authorship happens inside either a web browser or an [Electron-based app](https://www.electronjs.org/).
Given this, we wanted to create an environment where trivial to integrate fantastic grammar checking into web applications.
That's why we created `harper.js`.

## What is `harper.js`?
Today, it serves as the foundation for our [Obsidian plugin](/docs/integrations/obsidian) and our [website](/).

`harper.js` is an ECMAScript module designed to easy to import into any project.
On the inside, it uses a copy of Harper compiled to [WebAssembly](https://webassembly.org/).
## Installation

`harper.js` is an ECMAScript module designed to be easy to import into any project.
On the inside, it uses a copy of Harper's core algorithm compiled to [WebAssembly](https://webassembly.org/).

It can be imported [natively in a browser](./CDN) or through [npm](https://www.npmjs.com/package/harper.js).

@install-pkg(harper.js)
25 changes: 25 additions & 0 deletions packages/web/src/routes/docs/harperjs/linting/+page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Linting With harper.js
---

[Linting](<https://en.wikipedia.org/wiki/Lint_(software)>) is the process of consuming, analyzing, and finding faults in text.
This is the principle task Harper tries to do.
When possible, Harper also tries to automatically generate fixes for any issues it finds.

In `harper.js`, there's just one interface you need to worry about: the `Linter`.

## Linters

The `Linter` type is relatively straightforward and has two implementations: the `LocalLinter` and the `WorkerLinter`.
Notice how every method returns a `Promise<...>`.

@code(../../../../../../harper.js/src/Linter.ts)

The `LocalLinter` will instantiate and prepare Harper's WebAssembly module asynchronously, but notably **in the same event loop**.
This can result in high [LCP](https://developer.mozilla.org/en-US/docs/Glossary/Largest_contentful_paint), so this implementation is only recommended in situtations where the event loop will not be doing other latency-sensitive things.
In other words: the `LocalLinter` is not for the web.

The `WorkerLinter`, on the other hand, will instantiate and prepare Harper's WebAssembly module inside a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API), which means it will **not** block the event loop.
This is recommended for interactive web applications.

[Visit our page about CDNs](./CDN) to see an example of the `WorkerLinter` in action.
4 changes: 4 additions & 0 deletions packages/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ export default defineConfig({
title: 'Introduction',
to: '/docs/harperjs/introduction'
},
{
title: 'Linting',
to: '/docs/harperjs/linting'
},
{
title: 'CDN',
to: '/docs/harperjs/CDN'
Expand Down

0 comments on commit ef4d503

Please sign in to comment.