diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d35d445..0ca9d10 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: PUSH_BEFORE: ${{ github.event.before }} run: | # ビルドに関係しないファイル(これ以外が1つでも変わっていればビルドする) - ignore='(\.md$|^LICENSE$|^\.claude/|^\.github/dependabot\.yml$)' + ignore='(\.md$|^LICENSE$|^docs/|^\.claude/|^\.github/dependabot\.yml$)' if [[ "$GITHUB_REF" == refs/tags/v* ]]; then # タグは公開するので常にビルドする echo "code=true" >> "$GITHUB_OUTPUT"; exit 0 diff --git a/CLAUDE.md b/CLAUDE.md index 63ce8fc..db122de 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,7 +19,7 @@ - `Span` を使うのは計測で効果があった箇所のみ(住所照合の正規化、CSV の読み込み)。`Span` を使わなくても両方で速くできる場合は、`#if` を使わず共通のコードにする。 - `ZipConvertCustomerBarCode.Drawing`: System.Drawing.Common による描画(Windows のみ)。 - `ZipConvertCustomerBarCode.SkiaSharp`: SkiaSharp による描画。名前空間は `SkiaSharp` との衝突を避けるため `ZipConvertCustomerBarCode.Skia`。 -- `ZipConvertCustomerBarCode.Demo`: デモサイト(Blazor WebAssembly、net10.0、パッケージにはしない)。コアの `BarCode.Create` と `ToSvg` / `ToPrintSvg` だけを使い、郵便番号データは使わない(12万件あり、ブラウザーで読み込むには重い)。`InvariantGlobalization` で ICU を省いている(コアはカルチャに依存しない)。ソリューションに含めているので、CI の test でビルドされる。 +- `ZipConvertCustomerBarCode.Demo`: デモサイト(Blazor WebAssembly、net10.0、パッケージにはしない)。コアの `BarCode.Create` と `ToSvg` / `ToPrintSvg` だけを使い、郵便番号データは使わない(12万件あり、ブラウザーで読み込むには重い)。`InvariantGlobalization` で ICU を省いている(コアはカルチャに依存しない)。ソリューションに含めているので、CI の test でビルドされる。README の画面のスクリーンショットは `docs/demo.png`(NuGet のパッケージページでも表示されるよう、README からは raw.githubusercontent.com の絶対 URL で参照する)。 - ローカルでは `dotnet run --project ZipConvertCustomerBarCode.Demo` で起動する。Razor では `@code` が予約語なので、変数名に `code` を使わない。 - `netstandard2.0` の既定 C# は 7.3。`#if NET8_0_OR_GREATER` の外では `record` や null 許容参照型など新しい構文は使わない。 - バージョン・著作権表示・パッケージ情報は `Directory.Build.props` にまとめている。パッケージアイコン `icon.png`(128×128)は、このライブラリで作ったバーコードの先頭4シンボル(スタート + 郵便番号3桁)を縦に伸ばし、紺地に白で描いたもの。`dotnet run tools/GenerateIcon.cs -- icon.png` で生成する(色・拡大率・余白もこのスクリプトにある)。デモサイトのファビコン `ZipConvertCustomerBarCode.Demo/wwwroot/icon.png` も同じ画像なので、作り直したらコピーする。 @@ -48,7 +48,7 @@ - パッケージ作成時の検証(`EnablePackageValidation`)で、net8.0 版から netstandard2.0 版の公開 API が欠けているとエラー(CP0002)になる(net8.0 版にだけ API を足すのは検出しない)。 - あわせて、公開済みのバージョン(`Directory.Build.props` の `PackageValidationBaselineVersion`)と比べて公開 API を削除・変更していないかも確認する。破壊的変更をするメジャーバージョンアップでは、この基準を外すか更新する。 - NuGet パッケージの更新も Dependabot が PR にする。`SkiaSharp` とテスト用の `SkiaSharp.NativeAssets.Linux.NoDependencies` はバージョンを揃える必要があるので、グループにまとめて一緒に更新する。 -- `build.yml` は、ドキュメントなどビルドに関係しないファイル(`*.md`・`LICENSE`・`.claude/`・`.github/dependabot.yml`)だけの変更では test と pack をスキップする(`changes` ジョブで判定)。`paths-ignore` を使うと必須チェックが報告されず PR をマージできなくなるので使わない。 +- `build.yml` は、ドキュメントなどビルドに関係しないファイル(`*.md`・`LICENSE`・`docs/`・`.claude/`・`.github/dependabot.yml`)だけの変更では test と pack をスキップする(`changes` ジョブで判定)。`paths-ignore` を使うと必須チェックが報告されず PR をマージできなくなるので使わない。 - master はルールセットで保護している(PR 経由のみ、`build-result`(test・pack の結果をまとめるジョブ)と verify-lockfile の `verify` の成功が必須)。CI のジョブ名を変えるとマージできなくなるので、ルールセットの必須チェックも合わせて変更する。 ## バーコード処理 diff --git a/README.md b/README.md index 2b57614..05980d6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,23 @@ # ZipConvertCustomerBarCode -郵便番号、住所から郵便物用のカスタマバーコードを生成する -**[デモ](https://cssho.github.io/ZipConvertCustomerBarCode/)**: ブラウザーで郵便番号と住所を入力して、バーコードを試せます(WebAssembly で動作し、入力内容はどこにも送信しません)。 +郵便番号、住所から郵便物用のカスタマバーコードを生成する .NET ライブラリです。[デモサイト](#デモ)で試せます。 ## カスタマバーコード > お客さまがあらかじめ郵便物に印字する場合のバーコードがカスタマバーコードです。カスタマバーコードは、原則として差し出しの必要条件ではなく、料金割引を受けようとする場合に印字するもので、あて名印字と同時に印字できるような仕様としています。 [郵便局 - 郵便番号・バーコードマニュアル](http://www.post.japanpost.jp/zipcode/zipmanual/index.html) +## デモ +**https://cssho.github.io/ZipConvertCustomerBarCode/** + +ブラウザーで郵便番号と住所を入力すると、その場でバーコードを作ります。インストールは不要です。 + +[![デモサイトの画面: 郵便番号と住所から作ったバーコード、シンボル列、C# のコード例](https://raw.githubusercontent.com/cssho/ZipConvertCustomerBarCode/master/docs/demo.png)](https://cssho.github.io/ZipConvertCustomerBarCode/) + +- バーコード、シンボル列(郵便番号・住所表示番号などの区切りごと)、抜き出した住所表示番号を表示します。 +- 画像用と印刷用(実寸)の SVG をダウンロードできます。 +- 入力した内容で同じバーコードを作る C# のコード例を表示します。 +- このライブラリを WebAssembly でそのまま動かしているので、入力内容はどこにも送信しません。郵便番号データ(utf_ken_all.csv)は使っていないため、住所の自動分割や住所から郵便番号を探す機能は試せません。 + ## 構成 .NET Standard 2.0 のライブラリです(コアは .NET 8 以降向けのビルドも含み、住所の照合や郵便番号データの読み込みでメモリの割り当てが少なくなります)。描画方法に合わせてパッケージを選んでください。 diff --git a/ZipConvertCustomerBarCode.Demo/App.razor b/ZipConvertCustomerBarCode.Demo/App.razor index 29e3b4b..0212217 100644 --- a/ZipConvertCustomerBarCode.Demo/App.razor +++ b/ZipConvertCustomerBarCode.Demo/App.razor @@ -104,23 +104,24 @@ } バーコードに入るのは先頭13けた分です -
シンボル列
-
-
    - @for (var i = 0; i < barcode.Symbols.Count; i++) - { -
  1. @barcode.Symbols[i]
  2. - } -
- -
+

シンボル列

+
+ @foreach (var group in SymbolGroups) + { +
+
@group.Label
+
    + @foreach (var symbol in barcode.Symbols.Skip(group.Start).Take(group.Count)) + { +
  1. @symbol
  2. + } +
+
+ } +
+

C# で同じバーコードを作る

@CodeSample
} @@ -183,13 +184,16 @@ blockAddress = sample.BlockAddress; } - // シンボル列の位置ごとの種類: スタート(0)・郵便番号(1〜7)・住所表示番号(8〜20)・チェックデジット(21)・ストップ(22) - private static string SymbolKind(int index) => index switch + private record SymbolGroup(string Label, string Kind, int Start, int Count); + + // シンボル列(常に23個)の区切り: スタート・郵便番号7けた・住所表示番号13けた・チェックデジット・ストップ + private static readonly SymbolGroup[] SymbolGroups = { - 0 or 22 => "start", - <= 7 => "zip", - <= 20 => "address", - _ => "check", + new("スタート", "start", 0, 1), + new("郵便番号", "zip", 1, 7), + new("住所表示番号(13けた)", "address", 8, 13), + new("チェック\nデジット", "check", 21, 1), + new("ストップ", "start", 22, 1), }; private static string DataUri(string svg) => "data:image/svg+xml;charset=utf-8," + Uri.EscapeDataString(svg); diff --git a/ZipConvertCustomerBarCode.Demo/wwwroot/css/app.css b/ZipConvertCustomerBarCode.Demo/wwwroot/css/app.css index ffdc8cc..39dd640 100644 --- a/ZipConvertCustomerBarCode.Demo/wwwroot/css/app.css +++ b/ZipConvertCustomerBarCode.Demo/wwwroot/css/app.css @@ -286,7 +286,28 @@ code, pre { border-radius: 4px; } -.symbols, .legend { +/* シンボル列は区切り(スタート・郵便番号・住所表示番号・チェックデジット・ストップ)ごとにまとめ、まとまりの単位で折り返す */ +.symbol-groups { + display: flex; + flex-wrap: wrap; + /* 見出しが2行のまとまり(チェックデジット)があっても、記号の行をそろえる */ + align-items: flex-end; + gap: 12px 10px; +} + +.symbol-group { + min-width: 0; +} + +.symbol-group-label { + font-size: 0.75rem; + color: var(--muted); + line-height: 1.3; + margin-bottom: 4px; + white-space: pre; +} + +.symbols { display: flex; flex-wrap: wrap; gap: 4px; @@ -295,11 +316,6 @@ code, pre { margin: 0; } -.legend { - margin-top: 8px; - font-size: 0.8rem; -} - .symbol { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 0.85rem; @@ -309,14 +325,10 @@ code, pre { text-align: center; } -.legend .symbol { - font-family: inherit; -} - -.symbol.start { background: var(--start); } -.symbol.zip { background: var(--zip); } -.symbol.address { background: var(--address); } -.symbol.check { background: var(--check); } +.symbol-group.start .symbol { background: var(--start); } +.symbol-group.zip .symbol { background: var(--zip); } +.symbol-group.address .symbol { background: var(--address); } +.symbol-group.check .symbol { background: var(--check); } .code { background: var(--code-bg); @@ -328,13 +340,14 @@ code, pre { margin: 0; } -.card ul { +/* 「このデモについて」の箇条書き(シンボル列などのリストには当てない) */ +.card > ul { margin: 0; padding-left: 1.25em; } /* 長いパッケージ名などが狭い画面ではみ出さないよう折り返す */ -.card li code, .details code { +.card > ul code, .details code { overflow-wrap: anywhere; } diff --git a/ZipConvertCustomerBarCode.Demo/wwwroot/index.html b/ZipConvertCustomerBarCode.Demo/wwwroot/index.html index e219ddf..7df9a88 100644 --- a/ZipConvertCustomerBarCode.Demo/wwwroot/index.html +++ b/ZipConvertCustomerBarCode.Demo/wwwroot/index.html @@ -6,6 +6,8 @@ カスタマバーコード デモ | ZipConvertCustomerBarCode + + diff --git a/docs/demo.png b/docs/demo.png new file mode 100644 index 0000000..2fd1447 Binary files /dev/null and b/docs/demo.png differ