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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@diglot/comark

v0.2.2

Published

comark adapter for diglot

Readme

@diglot/comark

comark adapter for diglot: extracts segments from comark documents and applies translations to them.

pnpm add @diglot/comark @diglot/core

Usage

import { apply, extract, parse, render } from '@diglot/comark'

const doc = await parse(markdown)
const { segments } = await extract(doc, { file: 'docs/intro.md' })

const translations = new Map([[segments[0].hash, 'Introduction']])
const { doc: translated, report } = await apply(doc, translations)
// report: { applied, missing, rejected }

const output = await render(translated)
  • parse(source) parses with the options the adapter expects and keeps the source and top-level line ranges, so protected spans (inline code, links, components, inline HTML) are taken verbatim from the source. Documents parsed elsewhere work too; their protected spans are re-rendered.

  • extract(doc, { file, policy }) returns segments for headings, paragraphs, list items, table cells, blockquotes, component slots, image alts, allowlisted props, prose frontmatter, code labels and code comments.

  • extract(doc, { spanSources: false }) skips slicing and re-rendering protected spans. Links, inline code, images, components and inline HTML get empty markdown in their placeholders, which changes each segment's text and sourceHash; hash, skeleton, placeholder types and words are the same. Use it when only identities are needed, as for a manifest.

  • apply(doc, translations, { policy }) returns a translated copy. Each translation is validated against the current source segment; placeholders are filled with the current source nodes, so links, code and components always come from the source. Rejected and missing segments keep their source text. Heading ids are kept. Code comments are substituted in the code text, including code already split into highlighted spans.

  • apply(doc, translations, { onSegment }) calls onSegment with an ApplySegmentEvent for each segment. target.setAttribute(name, value) sets a prop on the text block holding the segment (h1 to h6, p, li, blockquote, th, td). Text directly inside a component is wrapped in a span that carries the attributes; it is left unwrapped when no attribute is set. Frontmatter, props, image alts, code labels and code comments have a null target. Span sources are resolved for onSegment only; pass spanSources: false when the callback does not read them (hash, words and skeleton are unaffected).

    const events: ApplySegmentEvent[] = []
    const { doc: translated } = await apply(doc, segment => records.get(segment.hash), {
      onSegment(event) {
        events.push(event)
        if (event.outcome === 'missing' || event.outcome === 'rejected')
          event.target?.setAttribute('lang', 'en')
      },
    })
    const coverage = wordsByStatus(events)
  • apply(doc, translations, { copy: false }) translates doc in place instead of a copy. Use it when nothing else holds on to doc, such as a document parsed for this request.

  • render(doc) writes comark markdown, with hard breaks as :br and bound HTML attributes such as :zoom="false" intact.

  • extractNavigation(source) and applyNavigation(source, translations) handle .navigation.yml files.

  • labelSegment(value, { kind, file, detail, policy }) builds the segment of one label, hashed as extractNavigation hashes a .navigation.yml value (%s is a placeholder) or, with kind: 'frontmatter', as extract hashes a frontmatter value. translateLabel(value, translations, options) returns its translation, or value without a valid one. Use them to translate navigation trees and titleTemplates at runtime; pass the same file, detail and policy as extraction when the policy has a salt.