npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

wikirefs-spec

v0.0.4-spec

Published

A collection of tests to validate markdown parser output against the wikirefs spec

Downloads

23

Readme

wikirefs-spec

A WikiBonsai Project NPM package

WikiRefs refers to several wiki constructs that all fall under the umbrella "wikiref" and generally include the [[double square bracket]] syntax in some way.

This project expects:

  • The text that appears between square brackets should match a filename from a given collection of markdown files (e.g. [[filename]] -> filename.md).
  • Whitespace is supported in filenames, though it is not preferred.
  • Matching between [[wikirefs]] and filenames is case insensitive.
  • The file's title metadata is what gets rendered to the anchor (a) tag's inner text. If no title exists, the filename is used instead.

This project's implementation does not enforce the following, but downstream projects in the WikiBonsai project do:

  • Filenames in a collection of markdown files are expected to be unique. (This is in part to keep the specification a touch simpler. If full file paths are desired, try using traditional [markdown](links) instead)

Use

Below is an example usage of the test cases provided by wikirefs-spec:

import assert from 'node:assert/strict';
import { wikiAttrCases, wikiLinkCases, wikiEmbedCases } from 'wikirefs-spec';

function run(contextMsg: string, tests: TestCase[]): void {
  context(contextMsg, () => {
    for(const test of tests) {
      it(test.descr, () => {
        const expdHTML: string = test.html;
        const actlHTML: string = md.render(test.mkdn, env);
        assert.strictEqual(actlHTML, expdHTML);
      });
    }
  });
}

describe('render wikirefs; mkdn -> html', () => {

  run('wikiattr test cases', wikiAttrCases);
  run('wikilink test cases', wikiLinkCases);
  run('wikiembed test cases', wikiEmbedCases);

});

WikiAttrs

"Wikiattrs" are block constructs whose content is the only content on a given line. They are identical to typed wikilinks except they expect a newline after the closing square brackets ]]. They may be located anywhere in a markdown file, but are collected and rendered at the top of the file if desired -- much like how footnotes are collected and rendered at the bottom of a markdown file. (Generated HTML is reminiscent of wikipedia-style info boxes and can be turned off in the scenario where only metadata is desired).

Wikiattrs are meant to be compatible with caml metadata attributes.

Wikiattrs do not support labels.

Single

All of the following examples should generate the same html:

:attrtype::[[filename]]

Some more text.
Some more text.

:attrtype::[[filename]]

(Optional colon prefixes)

attrtype::[[filename]]

Some more text.

Resulting HTML:

<aside class="attrbox">
  <span class="attrbox-title">Attributes</span>
    <dl>
      <dt>attrtype</dt>
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-a" data-href="/tests/fixtures/fname-a">title a</a></dd>
    </dl>
</aside>
<p>Some more text.</p>

List

Lists are also supported. All of the following examples should generate the same html:

Comma-separated lists.

:attrtype::[[fname-a]], [[fname-b]], [[fname-c]]

Markdown-style bullet lists.

:attrtype::
- [[fname-a]]
- [[fname-b]]
- [[fname-c]]
:attrtype::
+ [[fname-a]]
+ [[fname-b]]
+ [[fname-c]]
:attrtype::
* [[fname-a]]
* [[fname-b]]
* [[fname-c]]
:attrtype::
- [[fname-a]]
+ [[fname-b]]
* [[fname-c]]

Optional colon prefix.

attrtype::
- [[fname-a]]
- [[fname-b]]
- [[fname-c]]

Flexible whitespace.

: attrtype ::
              - [[fname-a]]
              - [[fname-b]]
              - [[fname-c]]

Resulting HTML:

<aside class="attrbox">
  <span class="attrbox-title">Attributes</span>
    <dl>
      <dt>attrtype</dt>
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-a" data-href="/tests/fixtures/fname-a">title a</a></dd>
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-b" data-href="/tests/fixtures/fname-b">title b</a></dd>
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-c" data-href="/tests/fixtures/fname-c">title c</a></dd>
        <!-- etc. -->
    </dl>
</aside>

WikiAttrs expect unqiue attributes per file and unique filenames per attribute. If there are duplicates, metadata will merge all duplicates into a single hash or dictionary-like structure and render will display merged attrtypes with filenames grouped and duplicates preserved. This overall behavior is to make wikiattrs as hash-like as possible -- with unique keys (attrtypes)

For example, this markdown might generate the following json data and html:

: attrtype :: [[fname-a]]
: attrtype :: [[fname-a]], [[fname-b]]
{
  // no duplicates in metadata
  'attrtype': [ 'fname-a', 'fname-b' ],
}
<aside class="attrbox">
  <span class="attrbox-title">Attributes</span>
    <dl>
      <dt>attrtype</dt>
      <!-- filename duplicates preserved here -->
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-a" data-href="/tests/fixtures/fname-a">title a</a></dd>
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-a" data-href="/tests/fixtures/fname-a">title a</a></dd>
        <dd><a class="attr wiki reftype__attrtype" href="/tests/fixtures/fname-b" data-href="/tests/fixtures/fname-b">title b</a></dd>
    </dl>
</aside>

Lists also support flexible whitespacing: Attrtype text may be prefixed (between first colon : and attrtype text) or suffixed (between attrtype text and double colon ::) by one space. List item prefix whitespace (space before the bullet -*+) can have any number of spaces.

The result allows for pretty-printed wikiattrs:

: type             :: [[fname-a]]
: med-type         :: 
                     - [[fname-b]]
                     - [[fname-c]]
: longer-type-text :: 
                     - [[fname-d]]
                     - [[fname-e]]
                     - [[fname-f]]

WikiLinks

"Wikilinks" are inline constructs similar to regular text or links which appear in and alongside other markdown constructs like bold, lists, or tables. They are rendered in-place and as links to other content, especially content within the local context.

#todo

Note: In a markdown context, when talking about the different kinds of wiki constructs (wikiattr, wikilink, wikiembed) "wikilink" refers to the description herein. However, in an HTML context, a wikilink is any anchor (a) tag that was generated by the wikirefs plugin. Thus, anchors typically will have the wikilink class and other css classes describing how that wikilink came to be:

  • wikiattr -> <a class="attr wiki" ...
  • typed wikilink -> <a class="wiki link typed" ...
  • untyped wikilink -> <a class="wiki link" ...
  • wikiembed -> <a class="wiki embed" ...

Untyped

An untyped wikilink should link to another markdown file from a given collection of markdown files. It should render as an anchor tag, where the anchor tag's href property points to the markdown file's url and the anchor's innertext is probably title text generated from the file's metadata. A data-href mirroring the href will also be added.

If provided, the markdown file's doctype may also be added as a css class to the anchor tag.

Markdown:

[[filename]]

Resulting HTML:

<a class="wiki link" href="url" data-href="url">title</a>

Typed

A typed wikilink is a wikilink with linktype information. It should render similarly to untyped wikilinks, with the addition of a type css class to indicate it is a typed wikilink and a css classname that matches the name of the given linktype prefixed with reftype__.

Markdown:

:linktype::[[filename]].

Resulting HTML:

<a class="wiki link type reftype__linktype" href="url" data-href="url">title</a>.

Labelled

When labelled, labelled text (text which appears after the | and before the ]]) will render for the wikilink's anchor text instead of, likely, the file's title.

Markdown:

[[filename|label]]

Resulting HTML:

<a class="wiki link" href="url" data-href="url">label</a>

Labels also work for typed wikilinks.

Markdown:

:linktype::[[filename|label]]

Resulting HTML:

<a class="wiki link type reftype__linktype" href="url" data-href="url">label</a>

WikiEmbeds

WikiEmbeds are also inline constructs, but render as blocks. They provide links to the linked content, but also embed the file's actual content in the current file when rendered. Markdown files, audio, images, and video are all supported.

Markdown

File with wikiembed:

![[filename]]

File to be embedded:

Here is some content.

Resulting HTML:

<p>
  <div class="embed-wrapper">
    <div class="embed-title">
      <a class="wiki embed" href="/tests/fixtures/embed-doc" data-href="/tests/fixtures/embed-doc">
        embedded document
      </a>
    </div>
    <div class="embed-link">
      <a class="embed-link-icon" href="/tests/fixtures/embed-doc" data-href="/tests/fixtures/embed-doc">
        <i class="link-icon"></i>
      </a>
    </div>
    <div class="embed-content">
      <p>Here is some content.</p>
    </div>
  </div>
</p>

Audio

![[audio.mp3]]

Resulting HTML:

<p>
  <span class="embed-media" src="audio.mp3" alt="audio.mp3">
    <audio class="embed-audio" controls src="/tests/fixtures/audio.mp3"></audio>
  </span>
</p>

Supported audio formats: .mp3, .webm, .wav, .m4a, .ogg, .3gp, flac. (See const.ts)

Image

![[image.png]]

Resulting HTML:

<p>
  <span class="embed-media" src="image.png" alt="image.png">
    <img class="embed-image" src="/tests/fixtures/image.png">
  </span>
</p>

Supported image formats: .png, .jpg, .jpeg, .gif, .psd, .svg, .tif, .tiff, .apng, .avif, .jfif, .pjepg, .pjp, .webp, .bmp, .ico, .cur. (See const.ts)

Video

![[video.mp4]]

Resulting HTML:

<p>
  <span class="embed-media" src="video.mp4" alt="video.mp4">
    <video class="embed-video" controls src="/tests/fixtures/video.mp4"></video>
  </span>
</p>

Supported video formats: .mp4, .mov, .wmv, .flv, .avi, .mkv, .ogv. (See const.ts)

doctype

If a document type (doctype) for the referenced markdown file is given, its slugified form will be added as a css class -- for a markdown file with a doctype called doctype:

WikiAttr

<aside class="attrbox">
  <span class="attrbox-title">Attributes</span>
    <dl>
      <dt>attrtype</dt>
        <dd><a class="attr wiki reftype__attrtype doctype__doctype" href="/tests/fixtures/fname-a" data-href="/tests/fixtures/fname-a">title a</a></dd>
        <!-- etc. -->
    </dl>
</aside>

WikiLink

Typed
<a class="wiki link reftype__linktype doctype__doctype" href="url" data-href="url">title</a>
Untyped
<a class="wiki link doctype__doctype" href="url" data-href="url">title</a>

WikiEmbed

<p>
  <div class="embed-wrapper">
    <div class="embed-title">
      <a class="wiki embed doctype__doctype" href="/tests/fixtures/embed-doc" data-href="/tests/fixtures/embed-doc">
        embedded document
      </a>
    </div>
    <div class="embed-link">
      <a class="embed-link-icon" href="/tests/fixtures/embed-doc" data-href="/tests/fixtures/embed-doc">
        <i class="link-icon"></i>
      </a>
    </div>
    <div class="embed-content">
      <p>Here is some content.</p>
    </div>
  </div>
</p>

Tests

For more on syntax, see the test cases.

Test Case Structure

graph TD;
  wikiref  --> wikiattr;
  wikiref  --> wikilink;
  wikiref  --> wikiembed;
  wikiattr --> prefixed;
  wikiattr --> unprefixed;
  wikilink --> untyped;
  wikilink --> typed;
  wikiembed --> markdown;
  wikiembed --> audio;
  wikiembed --> image;
  wikiembed --> video;

Customization

Sometimes certain aspects of a spec test do not match target expectations. They can be altered in a test suite in the following manner -- this example is taken from markdown-it-wikirefs:

import { wikiRefCases } from 'wikirefs-spec';

describe('markdown-it-wikirefs', () => {

  before(() => {
    // markdown-it implements...
    wikiRefCases.forEach((testcase: WikiRefTestCase) => {
      // ...gfm strikethroughs differently by...
      if (testcase.descr.includes('gfm')
      && testcase.descr.includes('strikethrough')) {
        // ...using '<s>' instead of '<del>'
        testcase.html = testcase.html.replace(/del>/g, 's>');
      }
    });
  });

  // run tests...

});

Before running (inside the before), all test cases are looped through and changed by filtering tests by the descr and then applying the desired change to the test case's html -- or mkdn if so desired.