Show HN: TinyPDF – 3kb pdf library (70x smaller than jsPDF)

2025/12/19 3:59

Show HN: TinyPDF – 3kb pdf library (70x smaller than jsPDF)

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

tinypdfは、実際のPDFを生成する最小限で依存関係のないPDF作成ライブラリ(約400行)です。わずか3.3 KBで、jsPDF(229 KB)よりも約70倍小さくなっています。これはTTFフォント、PNG/SVGサポート、HTML→PDF変換、フォーム、暗号化、および圧縮などの機能を省いたためです。
コア機能には、テキスト描画(Helvetica、任意のサイズ、16進数カラー、配置)、図形描画(矩形、線)、JPEG画像埋め込み、カスタムサイズでのマルチページレイアウト、およびヘッダー、リスト、ルール用のMarkdown変換が含まれます。
サポートされていない機能—カスタムフォント、PNG/GIF/SVG、ベクターグラフィックス、フォーム、暗号化、圧縮—は、jsPDFやpdf-libなどのより豊富なライブラリで利用可能です。
クイックスタート:

import { pdf } from 'tinypdf';
const doc = pdf();
doc.page(...);
ctx.text(...);
ctx.rect(...);
ctx.line(...);
ctx.image(...);
doc.build(); // Uint8Arrayを返します

ヘルパー関数には、ポイント単位の幅を取得する

measureText(str, size)
markdown(str, { width, height, margin })
があります。
これらのプリミティブを使って約50行のコードで請求書例を生成できます。
MITライセンス下で提供されます。

本文

tinypdf – 最小構成の PDF 作成ライブラリ

<400 LOC、依存関係ゼロで実際に PDF を生成します。


なぜ tinypdf なのか?

tinypdfjsPDF
サイズ3.3 KB229 KB
依存関係02

約70倍小さくなります。TTF フォント、PNG/SVG、HTML→PDF、フォーム、暗号化・圧縮を除外しました。残るのは「95%のユースケース」:テキストと画像をページに配置することです。


使い道

  • 請求書
  • 領収書
  • レポート
  • 発送ラベル
  • チケット
  • 証明書
  • 契約書
  • データエクスポート

主な機能

機能説明
テキストHelvetica、任意のサイズ、16進カラーコード、左/中央/右揃え
図形四角形と線
画像JPEG(写真・ロゴ・署名)
ページ複数ページ、カスタムサイズ
Markdownヘッダー・リスト・区切り線付きで Markdown を PDF に変換

除外項目:カスタムフォント、PNG/GIF/SVG、ベクターグラフィック、フォーム、暗号化、圧縮、HTML→PDF。必要なら jsPDF や pdf-lib をご利用ください。


クイックスタート

import { pdf } from 'tinypdf';
import { writeFileSync } from 'fs';

const doc = pdf();

doc.page((ctx) => {
  ctx.rect(50, 700, 200, 40, '#2563eb');           // 青い四角形
  ctx.text('Hello PDF!', 60, 712, 24, { color: '#ffffff' });
  ctx.line(50, 680, 250, 680, '#000000', 1);       // 黒い線
});

writeFileSync('output.pdf', doc.build());

画像を追加

import { readFileSync } from 'fs';

doc.page((ctx) => {
  const logo = new Uint8Array(readFileSync('logo.jpg'));
  ctx.image(logo, 50, 700, 100, 50);
});

テキスト幅の測定

import { measureText } from 'tinypdf';
measureText('Hello', 12); // → 27.34 (ポイント)

Markdown を PDF に変換

import { markdown } from 'tinypdf';
import { writeFileSync } from 'fs';

const pdf = markdown(`
# Hello World

A minimal PDF from markdown.

## Features
- Headers (h1, h2, h3)
- Bullet lists
- Numbered lists
- Horizontal rules

---

Automatic word wrapping and pagination included.
`);

writeFileSync('output.pdf', pdf);

API 仕様

メソッド説明
pdf()
ドキュメントを作成
doc.page(callback)
デフォルトサイズ(612×792)でページ追加
doc.page(width, height, callback)
カスタムサイズのページ追加
doc.build()
Uint8Array
を返す
ctx.text(str, x, y, size, options?)

options:
{ color, align, width }
テキスト描画
ctx.rect(x, y, w, h, fill)
塗りつぶし四角形
ctx.line(x1, y1, x2, y2, stroke, width?)
ctx.image(jpegBytes, x, y, w, h)
JPEG 画像
measureText(str, size)
テキスト幅(ポイント)
markdown(str, options?)

options:
{ width, height, margin }
Markdown を PDF に変換

完全な例 – 請求書ジェネレーター(約50行)

import { pdf } from 'tinypdf';
import { writeFileSync } from 'fs';

const doc = pdf();

doc.page(612, 792, (p) => {
  const margin = 40, pw = 532;

  // ヘッダー
  p.rect(margin, 716, pw, 36, '#2563eb');
  p.text('INVOICE', 55, 726, 24, { color: '#fff' });
  p.text('#INV-2025-001', 472, 728, 12, { color: '#fff' });

  // 会社・請求先情報
  p.text('Acme Corporation', margin, 670, 16);
  p.text('123 Business Street', margin, 652, 11, { color: '#666' });
  p.text('New York, NY 10001', margin, 638, 11, { color: '#666' });

  p.text('Bill To:', 340, 670, 12, { color: '#666' });
  p.text('John Smith', 340, 652, 14);
  p.text('456 Customer Ave', 340, 636, 11, { color: '#666' });
  p.text('Los Angeles, CA 90001', 340, 622, 11, { color: '#666' });

  // テーブルヘッダー
  p.rect(margin, 560, pw, 25, '#f3f4f6');
  p.text('Description', 50, 568, 11);
  p.text('Qty', 310, 568, 11);
  p.text('Price', 380, 568, 11);
  p.text('Total', 480, 568, 11);

  const items = [
    ['Website Development', '1', '$5,000.00', '$5,000.00'],
    ['Hosting (Annual)', '1', '$200.00', '$200.00'],
    ['Maintenance Package', '12', '$150.00', '$1,800.00'],
  ];

  let y = 535;
  for (const [desc, qty, price, total] of items) {
    p.text(desc, 50, y, 11);
    p.text(qty, 310, y, 11);
    p.text(price, 380, y, 11);
    p.text(total, 480, y, 11);
    p.line(margin, y - 15, margin + pw, y - 15, '#e5e7eb', 0.5);
    y -= 30;
  }

  // 合計
  p.line(margin, y, margin + pw, y, '#000', 1);
  p.text('Subtotal:', 380, y - 25, 11);
  p.text('$7,000.00', 480, y - 25, 11);
  p.text('Tax (8%):', 380, y - 45, 11);
  p.text('$560.00', 480, y - 45, 11);
  p.rect(370, y - 75, 202, 25, '#2563eb');
  p.text('Total Due:', 380, y - 63, 12, { color: '#fff' });
  p.text('$7,560.00', 480, y - 63, 12, { color: '#fff' });

  // フッター
  p.text('Thank you for your business!', margin, 80, 12, { align: 'center', width: pw, color: '#666' });
  p.text('Payment due within 30 days', margin, 62, 10, { align: 'center', width: pw, color: '#999' });
});

writeFileSync('invoice.pdf', doc.build());

ライセンス

MIT

同じ日のほかのニュース

一覧に戻る →

2025/12/20 7:13

CSS Grid Lanes

## Japanese Translation: > **Safari Technology Preview 234 は CSS Grid Lanes を導入しました**。これは、開発者が JavaScript なしで CSS 内で直接モザイク風グリッドを構築できる新しいレイアウトモードです。 > > 開発者は `display: grid-lanes;` と標準の Grid 構文(`grid-template-columns`、`repeat(auto-fill, …)` など)を組み合わせて柔軟なレーンを作成します。アイテムは自動的に最も近い上部レーンに配置され、無限スクロールとタブフレンドリーなナビゲーションが可能になります。 > > **高度な機能** には、レーンサイズの変更(`minmax(8rem, 1fr) minmax(16rem, 2fr)`)、アイテムの跨ぎ(`grid-column: span N`)、明示的配置(`grid-column: -3 / -1`)および新しい `item-tolerance` プロパティ(デフォルトは `1em`)が含まれます。これは、サイズ差に基づいてアイテムがレーンをどれだけ積極的にシフトするかを制御します。レーンは列方向(「ウォーターフォール」)または行方向(「レンガレイアウト」)で向きを設定でき、デフォルトの流れは通常です。 > > 実装は 2022 年中頃に開始され、Safari TP 234 で利用可能です。ライブデモは <https://webkit.org/demos/grid3>(写真ギャラリー、ニュースレイアウト、博物館サイト、メガメニューフッター)でホストされています。CSS Working Group はまだプロパティ名と向きの構文(`grid-lanes-direction` か `grid-auto-flow` の再利用)を最終化中です。その決定が下り次第、この機能は本番環境で使用できるようになります。 > > 開発者にとって、これは追加の JavaScript を必要とせず、より高速でパフォーマンスの高いレスポンシブレイアウトを実現することを意味し、ブラウザベンダーは同様の機能を採用する可能性があり、将来のウェブデザイン標準に影響を与えるでしょう。

2025/12/19 0:01

Mistral OCR 3

## Japanese Translation: Mistral OCR 3 は、従来のエンタープライズツールと AI ネイティブ競合他社の両方を上回る高精度な OCR モデルです。フォーム、スキャン文書、複雑な表、および手書き文字に対して Mistral OCR 2 と比較し、全体で 74 % の勝率を達成します。このモデルは、1,000 ページあたり $2(50 % Batch‑API 割引適用で 1,000 ページあたり $1)と価格設定されており、シンプルな API または Mistral AI Studio のドラッグ&ドロップ Document AI Playground を通じてアクセスできます。 主な強みは次のとおりです: * **手書き文字サポート** – 連続体文字、混合内容、および印刷フォーム上の手書き文字。 * **フォーム処理** – 請求書、領収書、コンプライアンスフォーム、政府文書におけるボックス、ラベル、手書き入力、および密集レイアウトの検出を改善。 * **頑健性** – 圧縮アーティファクト、傾斜、歪み、低 DPI、背景ノイズ、複雑なレイアウトに対処。 * **表再構築** – ヘッダー、結合セル、多行ブロック、および列階層を完全にサポートし、colspan/rowspan を含む HTML テーブルタグ付きの拡張マークダウンを出力。 初期採用者はすでに Mistral OCR 3 を高ボリュームのエンタープライズパイプラインに統合しています:請求書を構造化フィールドへ変換、会社アーカイブのデジタル化、技術レポートからクリーンテキストを抽出、および企業検索の強化。精度、コスト効果、柔軟な展開の組み合わせにより、大規模文書処理を業界横断で変革できる競争力ある代替手段として位置づけられています。

2025/12/20 8:59

PBS News Hour West to go dark after ASU discontinues contract

## Japanese Translation: ## Summary アリゾナ州立大学(ASU)のウォルター・クロンスキー報道学部は、PBS NewsHour Westとのパートナーシップを更新しないことを決定し、2019 年から ASU のダウンタウンフェニックスキャンパスで運営されていた事務所を実質的に閉鎖しました。この動きは「ASUの優先事項の変更」に起因すると、News Hour Productions の GM 兼 WETA EVP/CCO のマイケル・ランチリオが述べました。PBS およびアリゾナ PBS は追加説明を行わず、ASU に感謝し、地域ニュースへの継続的な取り組みを約束しました。 閉鎖により、西海岸で 20 % 以上の視聴者に到達することを支援していた西部本部としての事務所の役割が終了します。また、ASU のジャーナリズム学生(例:AJ Ceglia 学長)に実地報道経験と就職機会を提供していたインターンシッププログラムも消滅します。現在のインターンは学術クレジットを受け取りますが、卒業要件を満たすために代替配置を探す必要があります。 PBS NewsHour West の最終全国放送は 12 月 19 日に行われます。クロンスキー建物は、事務所閉鎖前に学校のサポートを称える形で夜間放送に登場しました。この報道は *The State Press* のジュニアレポーター、エマ・ブラッドフォード(連絡先:elbradfo@asu.edu; X @emmalbradford)によって取り上げられました。彼女も ASU のジャーナリズム/メディアコミュニケーション学部の学生です。 この決定は、西米国における地域ニュースの報道を減少させ、PBS の視聴者エンゲージメントを低下させ、新進気鋭のジャーナリストのプロフェッショナルパスウェイを制限する可能性があります