Display Python version, executable path, and script path when run with uv
Project description
anchorfix
HTML アンカーを連番 ID に変換し、内部リンクを自動更新するツール
インストール
uv を使用する場合:
uv add anchorfix
pip を使用する場合:
pip install anchorfix
使用方法
anchorfix <htmlfile> [--prefix PREFIX]
基本的な使用例
デフォルトのプレフィックス 'a' を使用:
anchorfix input.html
カスタムプレフィックスを指定:
anchorfix input.html --prefix sec
出力をファイルにリダイレクト:
anchorfix input.html > output.html
コマンドラインオプション
ヘルプ表示:
anchorfix --help
出力例:
usage: anchorfix [-h] [--prefix PREFIX] [--version] htmlfile
HTMLアンカーを連番IDに変換
positional arguments:
htmlfile 入力HTMLファイルパス
options:
-h, --help show this help message and exit
--prefix PREFIX アンカーIDのプレフィックス (デフォルト: a)
-V, --version バージョン情報を表示
バージョン表示:
anchorfix --version
または:
anchorfix -V
仕様
目的
HTML で編集できる CMS において、ヘッダテキストに基づいたアンカー ID は内部リンクが正しく動作しないことがあります。anchorfix は、これらのアンカーを #a0001 のような連番形式に変換することで、内部リンクを確実に機能させます。
要は Markdown を HTML に変換した後に使うフィルターです。
入出力
- 入力: 単一の HTML ファイルパス(コマンドライン引数)
- 出力: 変換された HTML を標準出力(stdout)に出力
処理対象
以下の HTML 要素を処理します:
<h1>-<h6>タグのid属性<a>タグのname属性
変換ルール
- 連番形式:
{prefix}0001,{prefix}0002, ... (4 桁の連番、0001 から開始) - 既存アンカーの上書き: 既存の
id/name属性値は全て上書き - 内部リンク更新: 同一ファイル内の
<a href="#...">を自動更新 - 外部リンク保持:
<a href="other.html#anchor">のような外部参照は変更しない
CMS 互換性 - アンカー正規化
CMS が生成する HTML では、href属性とid属性のアンカーテキストに不一致が生じることがあります。anchorfix は、内部リンクのマッチングを行う際に以下の正規化処理を適用します:
- URL デコード:
%XX形式のパーセントエンコーディングをデコード - 特殊文字の除去: 以下の文字を削除
- 括弧:
()() - コロン:
: - 引用符:
""\'\''(ASCII/Unicode の両方) - スラッシュ:
/ - 疑問符:
?
- 括弧:
- 空白の正規化: 連続する空白文字を 1 つの半角スペースにまとめる
例:
<!-- 変換前: hrefとidの不一致 -->
<a href="#sigstore">Sigstore(シグストア) とは何か</a>
<h2 id="sigstore%28%E3%82%B7%E3%82%B0%E3%82%B9%E3%83%88%E3%82%A2%29-%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B">
<!-- 変換後: 両方とも同じアンカーIDに -->
<a href="#a0001">Sigstore(シグストア) とは何か</a>
<h2 id="a0001"></h2>
</h2>
この正規化により、以下のような一般的な CMS の不一致パターンに対応できます:
補足-vs補足:-(コロンの有無)cosignvs"cosign"(引用符の有無)pypitestpypivspypi/testpypi(スラッシュの有無)なぜvsなぜ?(疑問符の有無)
エラー処理
- ファイル読み込みエラー: 例外をスロー
- 重複 ID 検出: 同じ
id値が複数存在する場合、行番号と具体的な ID 値を含む例外をスロー - 不完全な HTML:
<body>の中身のみのような不完全な HTML も許容
サンプル
詳細なサンプルは examples/ ディレクトリを参照してください:
examples/basic_input.html/examples/basic_expected.html- 基本的な変換例examples/incomplete_input.html/examples/incomplete_expected.html- 不完全な HTMLexamples/mixed_links_input.html/examples/mixed_links_expected.html- 外部リンク混在examples/duplicate_id_input.html- 重複 ID エラーケース
技術仕様
- HTML パーサー: BeautifulSoup4
- CLI ライブラリ: argparse (標準ライブラリ)
- 入力エンコーディング: UTF-8 を想定し自動判定
- 出力エンコーディング: UTF-8 固定
- HTML フォーマット: 元のインデント・改行は保持しない
開発者向け
セットアップ
uv sync
タスク実行
# テスト実行
# テストは `examples/` ディレクトリのサンプルファイルを直接参照します
poe test
# リント・型チェック
poe check
poe mypy
# フォーマット
poe format
# 全チェック実行&ビルド&スモークテスト
poe build
Property-Based Testing
このプロジェクトでは、Hypothesis を使用した基本的な Property-Based Testing(PBT)を採用しています。
テスト対象プロパティ
- 一意性: 生成されたアンカー ID はすべて一意
- 形式正確性: すべてのアンカー ID が
{prefix}\d{4}形式に一致 - 内部リンク整合性:
<a href="#...">が変換後のアンカー ID と正しく対応
Hypothesis コード例
from hypothesis import given, strategies as st
from anchorfix import process_html
@given(st.text(min_size=1, max_size=10))
def test_anchor_uniqueness(prefix):
"""生成されたアンカーIDが一意であることを検証"""
html = "<h2 id='a'>A</h2><h2 id='b'>B</h2>"
result = process_html(html, prefix=prefix)
# アンカーIDを抽出して一意性を確認
# ...
@given(st.text(min_size=1, max_size=10))
def test_anchor_format(prefix):
"""アンカーIDが正しい形式であることを検証"""
html = "<h2 id='test'>Test</h2>"
result = process_html(html, prefix=prefix)
# 正規表現で形式を確認: {prefix}\d{4}
# ...
ライセンス
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anchorfix-0.0.6.tar.gz.
File metadata
- Download URL: anchorfix-0.0.6.tar.gz
- Upload date:
- Size: 7.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea2817804fdab33b2543526c01a3171ab1ed8e23e7abac666f308b5f607e2b51
|
|
| MD5 |
9164ee6f056b03bb111384075b94d666
|
|
| BLAKE2b-256 |
39578d4215493d9b14196b51657b5ad34727129dfe0a0ecf3c15e978d2c29442
|
Provenance
The following attestation bundles were made for anchorfix-0.0.6.tar.gz:
Publisher:
publish-pypi.yml on heiwa4126/anchorfix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anchorfix-0.0.6.tar.gz -
Subject digest:
ea2817804fdab33b2543526c01a3171ab1ed8e23e7abac666f308b5f607e2b51 - Sigstore transparency entry: 708516413
- Sigstore integration time:
-
Permalink:
heiwa4126/anchorfix@1499d1c978dc11259015743b684fab495bf3a424 -
Branch / Tag:
refs/tags/v0.0.6 - Owner: https://github.com/heiwa4126
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@1499d1c978dc11259015743b684fab495bf3a424 -
Trigger Event:
push
-
Statement type:
File details
Details for the file anchorfix-0.0.6-py3-none-any.whl.
File metadata
- Download URL: anchorfix-0.0.6-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26b90a7d16b163cd229cd6090ad12a5fd4f19c3ed867b1f7a94b6ea67f5019d2
|
|
| MD5 |
f80439dc811bd537f333d9f863274e27
|
|
| BLAKE2b-256 |
3f5f22cd837c9ea75e92c71f09cf389e99a8fd79b9e18097ec144e3c7eb21f85
|
Provenance
The following attestation bundles were made for anchorfix-0.0.6-py3-none-any.whl:
Publisher:
publish-pypi.yml on heiwa4126/anchorfix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anchorfix-0.0.6-py3-none-any.whl -
Subject digest:
26b90a7d16b163cd229cd6090ad12a5fd4f19c3ed867b1f7a94b6ea67f5019d2 - Sigstore transparency entry: 708516416
- Sigstore integration time:
-
Permalink:
heiwa4126/anchorfix@1499d1c978dc11259015743b684fab495bf3a424 -
Branch / Tag:
refs/tags/v0.0.6 - Owner: https://github.com/heiwa4126
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@1499d1c978dc11259015743b684fab495bf3a424 -
Trigger Event:
push
-
Statement type: