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

poml

v1.0.3

Published

Positional Markup Language - Simple markup for describing the position of components within a string.

Downloads

2

Readme

PoML - Positional Markup Language

This is <0>PoML</0>.
It stands for <0><1>P</1>ositional <1>M</1>arkup <1>L</1>anguage</0>.
Use it to <2>interpolate components or tags</2> into a string and back.

Install

React

For React, just install the poml-react module:

yarn add poml-react

Core

For the core package, just install poml

yarn add poml

Usage

console.log(parsePOML('Hello <0>world!</0>'))
// [
//   { type: 'TextNode', value: 'Hello ' },
//   {
//     type: 'ComponentNode',
//     position: 0,
//     children: [{ type: 'TextNode', value: 'world!' }],
//   },
// ]

React

// prettier-ignore
<Poml
  source="<0>Hello, world!</0> This is<1>cool!</1>"
  Components={[
    ({ children }) => <h1>{children}</h1>,
    ({ children }) => <em>{children}</em>
  ]}
/>

API

This module is split up into the core parser logic and individual implementations like React.

API - Core

API - parsePOML(markup: string): MarkupNode[]

Parses a POML string returning the AST.

Returns: MarkupNode[]

export type TextNode = {
  type: 'TextNode'
  id: string
  value: string
}

export type ComponentNode = {
  type: 'ComponentNode'
  id: string
  position: number
  children: MarkupNode[]
}

export type MarkupNode = TextNode | ComponentNode

For examples, checkout src/poml.test.ts

API - React

API - <Poml>

The <Poml /> component memoizes and parses of source input and applies your components to the AST. You must supply the source PoML string. If your PoML contains Component tags (which it should otherwise its just a regular ol' string), then you should provide an array of components via the Components props. The component at index 0 will interpolate into tag <0> from the string.

Example

<Poml
  source="Hello, <0>world!</0> This <1>is <2>cool!</2></1>"
  Components={[
    ({ children }) => <strong>{children} <i class="icon-world" /></div>,
    ({ children }) => <em>{children}</em>,
    ({ children }) => <><span className="strikethrough">{children}</span> great!</>,
  ]}
/>

{/* Result */}

<>
  Hello, <strong>world! <i class="icon-world" /></strong>
  This <em>is <span className="strikethrough">cool!</span> great!
</>

For more examples, checkout src/poml-react.test.ts

Motivation

String externalization is the process of taking hard-coded strings out of your code and into some other repository (whether that be a CMS or a JSON file). It's typically a pre-requisite of internationalizing a piece of software. A common mistake during this process is known as string concatenation.

Suppose you have some HTML that looks like this:

Clone this <span class="icon-text">repository<i class="icon-repo" /></span>

When externalizing this string, one might be tempted pull this out into two strings:

  • clone_this: 'Clone this'
  • repository: 'repository'

And then recombine them in the template:

{{t "clone_this"}} <span class="icon-text">{{t "repository"}}<i class="icon-repo" /></span>

This is effectively concatenating three strings together! First the clone_this string, then a single space, then the repository string. Anybody looking at the two externalized strings in isolation will not fully understand the context. "Clone this". Clone this what? Clone this sheep? Spider? Depending on the context, the translated content may very flip the ordering of the words around. Or maybe in some regions a phrase like "Clone this repository" has been colloquially known as a single word and there you are adding on a bunch of nonsense in their language.

One way to get around this is to directly embed the HTML into your string and pass that along for translation. But what if you need to change the template? Further, we're mixing concerns. Translated text and functional markup.

A better solution is to interpolate your markup into an externalized string.

Clone this <0>respository</0>

This way, the translator still gets the full context and the actual implemtnation still lives in your source code. Granted, this does create an even larger dependency on the externalized string and the call-site.

Specification

NOTE: This section is not yet complete.