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

udf-cli

v0.4.3

Published

Convert between HTML/Markdown and UYAP UDF file format

Downloads

8,244

Readme

udf-cli

Convert between HTML and UYAP UDF file format. Designed for AI agents that need to read and write UDF documents programmatically.

What is UDF?

UDF is the document format used by UYAP (Turkey's National Judiciary Informatics System). A UDF file is a ZIP archive containing a single content.xml file with text content, formatting, images, and tables encoded in a custom XML schema.

Install

npm install udf-cli

Or run directly:

npx udf-cli html2udf input.html output.udf

CLI Usage

HTML to UDF

udf-cli html2udf <input> [output]

Input accepts a file path, raw HTML string, or - for stdin. If input contains < it is treated as raw HTML. Output is optional — omit it to write to stdout.

# File to file
udf-cli html2udf input.html output.udf

# Raw HTML string to file
udf-cli html2udf '<p><strong>Merhaba</strong> dünya</p>' output.udf

# Raw HTML string to stdout
udf-cli html2udf '<p>Test</p>' > output.udf

# Stdin to file
cat input.html | udf-cli html2udf - output.udf

# Stdin to stdout (pipe-friendly)
echo '<p>Merhaba</p>' | udf-cli html2udf - > output.udf

UDF to HTML

udf-cli udf2html <input> [output]

Input accepts a file path or - for stdin. Output is optional — omit it to print HTML to stdout.

# File to file
udf-cli udf2html input.udf output.html

# File to stdout (agent-friendly — read UDF content directly)
udf-cli udf2html input.udf

# Stdin to stdout
cat input.udf | udf-cli udf2html -

# Full roundtrip via pipes
echo '<p>Test</p>' | udf-cli html2udf - | udf-cli udf2html -

Markdown to UDF

udf-cli md2udf <input> [output]

Input accepts a file path, raw Markdown string, or - for stdin.

# File to file
udf-cli md2udf input.md output.udf

# Stdin to file
cat input.md | udf-cli md2udf - output.udf

# Raw Markdown via stdin
echo '**Merhaba** dünya' | udf-cli md2udf - output.udf

Supported Markdown syntax for input:

  • **bold** and *italic*, ***bold italic***
  • # Heading 1 through ###### Heading 6
  • 1. Numbered list and - Bulleted list (with nesting via indentation)
  • Markdown tables (| col1 | col2 | with separator row)
  • ![alt](data:image/png;base64,...) images

UDF to Markdown

udf-cli udf2md <input> [output]

Converts UDF to Markdown — ideal for AI agents that work better with Markdown than HTML. Tables become Markdown tables, bold/italic use **/* syntax, lists become 1./- items.

# Read a UDF file as Markdown (agent-friendly)
udf-cli udf2md input.udf

# Save as Markdown file
udf-cli udf2md input.udf output.md

Example output:

**T.C.**
**ANTALYA 3. ASLİYE HUKUK MAHKEMESİ**

**ESAS NO:** 2024/463
**DAVACI:** Mehmet Yılmaz

| **Sıra No** | **Açıklama** | **Toplam (TL)** |
| --- | --- | --- |
| 1 | Arsa değeri | 1.250.000,00 |
| 2 | Bina değeri | 990.000,00 |

1. Taşınmazın konumu
2. Yapının fiziksel durumu

- Dış cephe boyasında dökülme
- Çatı izolasyonunda bozulma

Signing (.udf) with an e-signature card

udf-cli sign adds a detached CAdES-BES signature (sign.sgn) to one or more .udf files using a PKCS#11 smart card. The PIN is requested once and reused for all files in a single card session.

# Driver auto-detected, PIN entered in a native GUI window (nothing on the command line):
udf-cli sign evrak1.udf evrak2.udf
# explicit driver + non-interactive PIN sources:
udf-cli sign *.udf --module /usr/local/lib/libakisp11.dylib --pin 1234
UDF_PIN=1234 UDF_PKCS11_MODULE=/usr/local/lib/libakisp11.dylib udf-cli sign *.udf
# with intermediate CA certs (if the card holds only the leaf):
udf-cli sign evrak.udf --extra-certs türktrust-h7.cer türktrust-root.cer
  • Driver auto-detection: if you omit --module, the CLI looks for your installed vendor driver in known locations (AKİS libakisp11, SafeNet eTPKCS11, Gemalto gtop11dotnet) and loads the first that works on your CPU arch. Override with --module or UDF_PKCS11_MODULE. The driver is shipped by your card vendor and is not bundled or downloaded — install your card software (e.g. AKİS). On Apple Silicon, use a universal/arm64 driver (or run Node under Rosetta with an x86_64-only one).
  • PIN entry, agent-friendly: if you omit --pin/UDF_PIN, a native OS dialog (macOS osascript, Linux zenity/kdialog, Windows WinForms) pops up for the human to type the PIN — outside the terminal, so a tool/agent driving the CLI never handles it. In a headless session (no desktop), it errors clearly and asks for --pin/UDF_PIN instead.
  • --extra-certs embeds intermediate CA certificates (PEM or DER) when the card stores only the signer certificate and UYAP needs the full chain.
  • The PIN is requested once. On a wrong PIN the command aborts immediately and does not retry — cards lock after ~3 failed attempts.
  • Signing pulls in the optional koffi dependency, which downloads a prebuilt native binary on first install (needs network). Format conversion commands do not need it.
  • The signature is plain BES (no timestamp/policy), matching the UYAP editor's output.
  • macOS (Apple Silicon): some vendors ship x86_64-only drivers. If --module fails to load on arm64, run Node under Rosetta: arch -x86_64 node $(which udf-cli) sign ....

Library Usage

import { htmlToUdf, udfToHtml, udfToMarkdown, markdownToUdf } from 'udf-cli';

// HTML string → UDF buffer
const udfBuffer = await htmlToUdf('<p><strong>Mahkeme kararı</strong></p>');
fs.writeFileSync('document.udf', udfBuffer);

// UDF buffer → HTML string
const udf = fs.readFileSync('document.udf');
const html = await udfToHtml(udf);

// UDF buffer → Markdown string
const md = await udfToMarkdown(udf);

// Markdown string → UDF buffer
const udfFromMd = await markdownToUdf('**Başlık**\n\nParagraf metni');

AI Authoring Guide

If you are an AI agent generating UDF documents, use HTML with inline CSS as your input format. Always use pt units. The conversions below are exhaustive — anything not listed is not supported.

System prompt snippet

Paste this into your agent's system prompt:

Generate UDF input as HTML with inline CSS. Use pt for all lengths.

  • Default: when no font-family / font-size is set, text is Times New Roman 12pt, black on white. Omit these attributes unless the user requests a different style.
  • Inline styles: <strong>, <em>, <u>, <span style="font-family:Arial; font-size:12pt; color:#FF0000; background-color:#FFFF00">
  • Paragraphs: <p style="text-align:justify; line-height:1.5; margin-top:12pt; margin-bottom:6pt; margin-left:36pt; text-indent:24pt"> (also text-align:right, hanging indent via negative text-indent)
  • Headings: <h1><h6> produce bold paragraphs at 24/20/16/14/12/10pt
  • Tab stops: <p style="tab-stops:36pt 72pt 108pt">Item<tab/>Value<tab/>Notes</p>
  • Page break: <page-break/>only use when the user explicitly asks for one. The UDF editor renders an inline "sayfa sonudur" marker between pages that readers often mistake for document content. Default to letting the page flow naturally.
  • Tables: standard <table><tr><td>...</td></tr></table>; supports colspan/rowspan; cell styles via inline CSS (background-color, vertical-align, border, border-style:none to hide borders)
  • Lists: <ul>, <ol>, <li> (nesting via nested lists)
  • Images: <img src="data:image/png;base64,..." width="200" height="100"> (width/height in pt)
  • Colors: hex (#RGB, #RRGGBB), rgb(r,g,b), or named CSS colors all work

Always use pt. Do not escape <tab/> or <page-break/>. Do not use <br> to separate paragraphs — start a new <p>.

Cookbook

Coloured bold heading

<p style="text-align:center"><span style="font-family:Arial; font-size:18pt; color:#003366"><strong>BAŞLIK</strong></span></p>

Justified paragraph with first-line indent

<p style="text-align:justify; text-indent:24pt; line-height:1.5">Lorem ipsum dolor sit amet ...</p>

Three-column tab-stop layout (signature block)

<p style="tab-stops:200pt 400pt"><strong>Davacı</strong><tab/><strong>Davalı</strong><tab/><strong>Hâkim</strong></p>
<p style="tab-stops:200pt 400pt">Mehmet Yılmaz<tab/>Ahmet Demir<tab/>Ayşe Kaya</p>

Two sections separated by a page break

<p>İlk sayfa içeriği.</p>
<page-break/>
<p>İkinci sayfa içeriği.</p>

Yellow-highlighted span

<p>Bu cümlede <span style="background-color:#FFFF00">vurgulanmış kısım</span> var.</p>

1.5-line-spaced paragraph with bottom margin

<p style="line-height:1.5; margin-bottom:12pt">İki yana hizalı, 1.5 satır aralıklı paragraf.</p>

Bordered table with bold header row

<table>
  <tr>
    <td style="background-color:#EEEEEE"><strong>Sıra</strong></td>
    <td style="background-color:#EEEEEE"><strong>Açıklama</strong></td>
  </tr>
  <tr>
    <td>1</td>
    <td>Birinci kalem</td>
  </tr>
</table>

Signature block under a table using tab stops

<table>...</table>
<p style="margin-top:24pt; tab-stops:280pt"><strong>Yargıtay</strong><tab/><strong>Mahkeme Mührü</strong></p>

Headings (auto-bold, fixed sizes)

<h1>Karar Özeti</h1>
<h2>Tarafların İddiaları</h2>
<p>Normal gövde metni.</p>

Numbered list with a nested bullet list

<ol>
  <li>Birinci madde</li>
  <li>İkinci madde
    <ul>
      <li>Alt madde a</li>
      <li>Alt madde b</li>
    </ul>
  </li>
  <li>Üçüncü madde</li>
</ol>

Right-aligned paragraph (e.g. date / venue line)

<p style="text-align:right">İstanbul, 7 Mayıs 2026</p>

Hanging indent (negative text-indent)

<p style="margin-left:36pt; text-indent:-36pt">DAVACI<tab/>: Mehmet Yılmaz, T.C. Kimlik No 11111111111, İstanbul</p>

Embedded image (base64 data URI, sized in points)

<p><img src="data:image/png;base64,iVBORw0KGgo..." width="200" height="100"></p>

Table with merged cells (colspan / rowspan)

<table>
  <tr>
    <td rowspan="2" style="vertical-align:middle"><strong>Kalem</strong></td>
    <td colspan="2" style="text-align:center"><strong>Tutar</strong></td>
  </tr>
  <tr>
    <td>Net</td>
    <td>KDV Dahil</td>
  </tr>
  <tr>
    <td>Vekalet ücreti</td>
    <td>1.000 TL</td>
    <td>1.200 TL</td>
  </tr>
</table>

Borderless table (layout grid, no visible lines)

<table>
  <tr>
    <td style="border-style:none">Sol sütun</td>
    <td style="border-style:none">Sağ sütun</td>
  </tr>
</table>

Page break via CSS on <div> (alternative to <page-break/>)

<p>Birinci bölüm.</p>
<div style="page-break-before:always"></div>
<p>İkinci bölüm.</p>

Unit rules

  • Always use pt. Conversion happens automatically for px, em, rem, cm, mm, in, but agents should not rely on this — sticking to pt makes output predictable.
  • Bare numbers (e.g. margin-top:12) are treated as pt.

Common mistakes

| ❌ Wrong | ✅ Right | Why | |---|---|---| | font-size:14px | font-size:14pt | UDF uses points; px works but agents should not guess | | &lt;tab/&gt; | <tab/> | Escaped custom elements become text | | <br><br> for paragraph break | Two separate <p> blocks | UDF is block-based; <br> is intra-paragraph soft break | | <div> for inline text | <p> for paragraph text | <div> is a block group, <p> is a paragraph | | Spaces in CSS like color: red | color:red | Both work but consistent compact form is recommended |

Supported HTML Elements

| HTML | UDF Mapping | |------|-------------| | <p> | Paragraph | | <h1> - <h6> | Paragraph with bold, sizes 24/20/16/14/12/10 pt | | <strong>, <b> | Bold text | | <em>, <i> | Italic text | | <u> | Underlined text | | <span style="..."> | Styled text (font, size, color, background) | | <br> | Paragraph break | | <img src="data:..."> | Embedded image (base64 data URI) | | <table>, <tr>, <td>, <th> | Table with borders (nested tables supported) | | <ul>, <ol>, <li> | Bulleted / numbered lists | | <div> | Block container |

Custom elements

These are non-standard tags handled by udf-cli:

| Element | Meaning | |---------|---------| | <tab/> | Inserts a tab character; aligns with the nearest tab-stops position. Self-closing. | | <page-break/> | Inserts a page break between blocks. Self-closing. Use sparingly — the UDF editor renders a visible "sayfa sonudur" marker between pages, which readers often mistake for actual document text. Only insert when the user explicitly requests a page break. |

Supported CSS Properties

These inline styles are recognized on <p>, <span>, <td>:

  • font-family — mapped to UDF font family. Default: Times New Roman.
  • font-size — supports px (converted to pt) and pt. Default: 12pt.
  • font-weight: bold — bold text
  • font-style: italic — italic text
  • text-decoration: underline — underlined text
  • color — text color. Accepts hex (#RGB, #RRGGBB), rgb(r,g,b), and named CSS colors (red, navy, …).
  • background-color — text/cell background (same color formats as color)
  • text-align — left, center, right, justify
  • vertical-align — top, middle, bottom (table cells)
  • line-height — paragraph line spacing
  • margin-top / margin-bottom / margin-left / margin-right — paragraph spacing & indentation
  • padding-top / padding-bottom / padding-left / padding-right (on <p>) — added to the corresponding margin-* value
  • text-indent — first-line indent (positive or negative for hanging indent)
  • tab-stops — space- or comma-separated list of tab positions (custom property)
  • border (on <td>) — shorthand <width> <style> <color>, e.g. border:1pt solid #000
  • border-style (on <td>) — solid or none (none hides cell borders)
  • page-break-before / page-break-after (on <div>) — value always or page inserts a page break

Writing HTML for UDF Conversion

When generating HTML that will be converted to UDF, follow these guidelines:

Text Formatting

<p>Normal text</p>
<p><strong>Bold text</strong></p>
<p><em>Italic text</em></p>
<p><strong><em>Bold and italic</em></strong></p>
<p><span style="font-family:Arial; font-size:14pt; color:#FF0000">Custom styled text</span></p>

Images

Images must use base64 data URIs. Specify width and height in points:

<img src="data:image/png;base64,iVBORw0KGgo..." width="200" height="100">

Tables

<table>
  <tr>
    <td>Cell 1</td>
    <td>Cell 2</td>
  </tr>
  <tr>
    <td colspan="2">Merged cell</td>
  </tr>
</table>

Nested tables are supported:

<table>
  <tr>
    <td>
      <table>
        <tr><td>Inner cell</td></tr>
      </table>
    </td>
  </tr>
</table>

Lists

<ol>
  <li>First item</li>
  <li>Second item</li>
</ol>

<ul>
  <li>Bullet point</li>
  <li>Another point</li>
</ul>

Centered / Aligned Text

<p style="text-align:center">Centered paragraph</p>
<p style="text-align:right">Right-aligned paragraph</p>
<p style="text-align:justify">Justified paragraph</p>

UDF Format Reference

UDF files have this internal structure:

document.udf (ZIP archive)
└── content.xml

The XML schema:

<?xml version="1.0" encoding="UTF-8" ?>
<template format_id="1.8">
  <content><![CDATA[All document text here]]></content>
  <properties>
    <pageFormat mediaSizeName="1" leftMargin="42.52" rightMargin="28.35"
                topMargin="14.17" bottomMargin="14.17" paperOrientation="1" />
  </properties>
  <elements resolver="hvl-default">
    <paragraph Alignment="0">
      <content startOffset="0" length="5" family="Times New Roman"
               size="12" bold="true" foreground="-16777216" background="-1" />
    </paragraph>
    <table tableName="Sabit" columnCount="2" columnSpans="150,150" border="borderCell">
      <row rowName="row1" rowType="dataRow" border="borderCell">
        <cell colspan="1" align="top" fillColor="16777215"
              border="borderCell" borderSpec="15">
          <paragraph>...</paragraph>
        </cell>
      </row>
    </table>
  </elements>
</template>

Key details:

  • Text offsets are rune-based (Unicode codepoints), not byte-based
  • Colors are signed 32-bit ARGB integers (black = -16777216, white = -1)
  • Alignment: 0 = left, 1 = center, 2 = right, 3 = justify
  • Border spec: bitmask (top=1, right=2, bottom=4, left=8; all sides=15)
  • Images: base64-encoded in imageData attribute, \uFFFC placeholder in text
  • Empty paragraphs: \u200B (zero-width space) placeholder in text

Development

npm install
npm test          # run tests
npm run build     # compile TypeScript