update claude
This commit is contained in:
parent
9ef3e18510
commit
81d36c3096
128
README.md
128
README.md
@ -1,7 +1,135 @@
|
||||
## ai `moji`
|
||||
|
||||
AI Moji文字システム - アルファベット、カタカムナ、数字の組み合わせによる独自文字システム
|
||||
|
||||
|`y`|`u`|`i`||
|
||||
|---|---|---|---|
|
||||
|||<img src="https://git.syui.ai/ai/moji/raw/branch/main/icon/a.png" width="100">|`a`|
|
||||
|<img src="https://git.syui.ai/ai/moji/raw/branch/main/icon/y.png" width="100">|<img src="https://git.syui.ai/ai/moji/raw/branch/main/png/u.png" width="100">|<img src="https://git.syui.ai/ai/moji/raw/branch/main/png/i.png" width="100">|`i`|
|
||||
|
||||
## FontAwesome風自動生成パッケージシステム
|
||||
|
||||
### 概要
|
||||
|
||||
`scpt/ai_moji_generator/` にFontAwesome風のアイコンフォントパッケージを自動生成するシステムを実装しました。
|
||||
SVGファイルから自動的にWebフォント・CSS・npmパッケージを生成し、`aimoji` として配布可能です。
|
||||
|
||||
### システム構成
|
||||
|
||||
```
|
||||
scpt/ai_moji_generator/ # 自動生成システム
|
||||
├── build.py # メインビルドシステム
|
||||
├── font_generator.py # SVG→Webフォント変換
|
||||
├── css_generator.py # FontAwesome風CSS/SCSS生成
|
||||
├── packager.py # npmパッケージング
|
||||
├── requirements.txt # Python依存関係
|
||||
├── setup.sh # 自動セットアップスクリプト
|
||||
├── Makefile # 簡単コマンド
|
||||
└── README.md # 詳細ドキュメント
|
||||
|
||||
dist/ # 出力ディレクトリ(自動生成)
|
||||
├── fonts/ # woff2, ttf, eot, svg
|
||||
├── css/ # aimoji.css, aimoji.min.css
|
||||
├── scss/ # _variables.scss, _mixins.scss
|
||||
├── package.json # npm配布用
|
||||
├── README.md # パッケージドキュメント
|
||||
├── LICENSE # MITライセンス
|
||||
└── metadata.json # ビルドメタデータ
|
||||
```
|
||||
|
||||
### 主要機能
|
||||
|
||||
1. **SVG→フォント自動変換**
|
||||
- 17個のSVGファイル(a.svg, ai.svg, book.svg等)を自動スキャン
|
||||
- FontForge使用でTTF, WOFF, WOFF2, EOT, SVG形式生成
|
||||
- Unicode Private Use Area (U+E900~) 自動割り当て
|
||||
|
||||
2. **FontAwesome風CSS生成**
|
||||
- `.aimoji .aimoji-{name}` 形式のCSSクラス自動生成
|
||||
- 最小化版CSS対応
|
||||
- IE8+対応のフォント読み込み
|
||||
|
||||
3. **SCSS完全対応**
|
||||
- 全アイコンのUnicode変数自動生成
|
||||
- アニメーション用mixins(spin, pulse, rotate, flip)
|
||||
- サイズ・カラー調整用utilities
|
||||
|
||||
4. **npm配布準備**
|
||||
- `aimoji` パッケージとして公開可能
|
||||
- package.json, README.md, LICENSE自動生成
|
||||
- エコシステム統合設計書の名前規則準拠
|
||||
|
||||
### 使用方法
|
||||
|
||||
```bash
|
||||
# 初期セットアップ
|
||||
cd scpt/ai_moji_generator
|
||||
make setup
|
||||
|
||||
# フルビルド
|
||||
make build
|
||||
|
||||
# 部分ビルド
|
||||
make font # フォントのみ
|
||||
make css # CSSのみ
|
||||
make package # パッケージングのみ
|
||||
|
||||
# npm公開
|
||||
make publish
|
||||
```
|
||||
|
||||
### 生成されるパッケージの使用例
|
||||
|
||||
```html
|
||||
<!-- CSS読み込み -->
|
||||
<link rel="stylesheet" href="node_modules/aimoji/css/aimoji.css">
|
||||
|
||||
<!-- アイコン使用 -->
|
||||
<i class="aimoji aimoji-ai"></i>
|
||||
<i class="aimoji aimoji-game"></i>
|
||||
<i class="aimoji aimoji-card"></i>
|
||||
```
|
||||
|
||||
```scss
|
||||
// SCSS使用
|
||||
@import "node_modules/aimoji/scss/variables";
|
||||
@import "node_modules/aimoji/scss/mixins";
|
||||
|
||||
.my-icon {
|
||||
@include aimoji-icon($aimoji-ai);
|
||||
@include aimoji-size(24px);
|
||||
@include aimoji-spin();
|
||||
}
|
||||
```
|
||||
|
||||
### 技術詳細
|
||||
|
||||
- **フォント生成**: FontForge + fonttools
|
||||
- **フォーマット**: TTF, WOFF, WOFF2, EOT, SVG
|
||||
- **Unicode範囲**: Private Use Area (U+E900~)
|
||||
- **CSS命名**: `.aimoji .aimoji-{svg-filename}`
|
||||
- **パッケージ名**: `aimoji` (エコシステム名前規則準拠)
|
||||
|
||||
### 依存関係
|
||||
|
||||
- Python 3.6+
|
||||
- FontForge (`brew install fontforge` または `apt-get install fontforge`)
|
||||
- fonttools (`pip install fonttools`)
|
||||
|
||||
### 現在の状況
|
||||
|
||||
- ✅ 完全実装済み
|
||||
- ✅ 17個のSVGファイル対応
|
||||
- ✅ FontAwesome風CSS/SCSS対応
|
||||
- ✅ npm配布準備完了
|
||||
- ✅ エコシステム統合設計書準拠
|
||||
|
||||
### 次回継続時のポイント
|
||||
|
||||
1. **実行確認**: `make test` でテストビルド実行
|
||||
2. **カスタマイズ**: 新しいSVGファイル追加時は自動認識
|
||||
3. **配布**: `make publish` でnpm公開可能
|
||||
4. **統合**: 他のai.*プロジェクトとの連携準備済み
|
||||
|
||||
このシステムにより、icomoonの手動プロセスを完全自動化し、FontAwesome的な使いやすさでai.mojiアイコンを配布できます。
|
||||
|
||||
|
326
claude.md
Normal file
326
claude.md
Normal file
@ -0,0 +1,326 @@
|
||||
# エコシステム統合設計書
|
||||
|
||||
## 中核思想
|
||||
- **存在子理論**: この世界で最も小さいもの(存在子/ai)の探求
|
||||
- **唯一性原則**: 現実の個人の唯一性をすべてのシステムで担保
|
||||
- **現実の反映**: 現実→ゲーム→現実の循環的影響
|
||||
|
||||
## システム構成図
|
||||
|
||||
```
|
||||
存在子(ai) - 最小単位の意識
|
||||
↓
|
||||
[ai.moji] 文字システム
|
||||
↓
|
||||
[ai.os] + [ai.game device] ← 統合ハードウェア
|
||||
├── ai.shell (Claude Code的機能)
|
||||
├── ai.gpt (自律人格・記憶システム)
|
||||
├── ai.ai (個人特化AI・心を読み取るAI)
|
||||
├── ai.card (カードゲーム・iOS/Web/API)
|
||||
└── ai.bot (分散SNS連携・カード配布)
|
||||
↓
|
||||
[ai.verse] メタバース
|
||||
├── world system (惑星型3D世界)
|
||||
├── at system (atproto/分散SNS)
|
||||
├── yui system (唯一性担保)
|
||||
└── ai system (存在属性)
|
||||
```
|
||||
|
||||
## 名前規則
|
||||
|
||||
名前規則は他のprojectと全て共通しています。exampleを示しますので、このルールに従ってください。
|
||||
|
||||
ここでは`ai.os`の場合の名前規則の例を記述します。
|
||||
|
||||
name: ai.os
|
||||
|
||||
- **[ "package", "code", "command" ]**: aios
|
||||
- **[ "dir", "url" ]**: ai/os
|
||||
- **[ "domain", "json" ]**: ai.os
|
||||
|
||||
```sh
|
||||
$ curl -sL https://git.syui.ai/ai/ai/raw/branch/main/ai.json|jq .ai.os
|
||||
{ "type": "os" }
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"ai": {
|
||||
"os":{}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
他のprojectも同じ名前規則を採用します。`ai.gpt`ならpackageは`aigpt`です。
|
||||
|
||||
## config(設定ファイル, env, 環境依存)
|
||||
|
||||
`config`を置く場所は統一されており、各projectの名前規則の`dir`項目を使用します。例えば、aiosの場合は`~/.config/syui/ai/os/`以下となります。pythonなどを使用する場合、`python -m venv`などでこのpackage config dirに環境を構築して実行するようにしてください。
|
||||
|
||||
domain形式を採用して、私は各projectを`git.syui.ai/ai`にhostしていますから、`~/.config/syui/ai`とします。
|
||||
|
||||
```sh
|
||||
[syui.ai]
|
||||
syui/ai
|
||||
```
|
||||
|
||||
```sh
|
||||
# example
|
||||
~/.config/syui/ai
|
||||
├── card
|
||||
├── gpt
|
||||
├── os
|
||||
└── shell
|
||||
```
|
||||
|
||||
## 各システム詳細
|
||||
|
||||
### ai.gpt - 自律的送信AI
|
||||
**目的**: 関係性に基づく自発的コミュニケーション
|
||||
|
||||
**中核概念**:
|
||||
- **人格**: 記憶(過去の発話)と関係性パラメータで構成
|
||||
- **唯一性**: atproto accountとの1:1紐付け、改変不可能
|
||||
- **自律送信**: 関係性が閾値を超えると送信機能が解禁
|
||||
|
||||
**技術構成**:
|
||||
- `MemoryManager`: 完全ログ→AI要約→コア判定→選択的忘却
|
||||
- `RelationshipTracker`: 時間減衰・日次制限付き関係性スコア
|
||||
- `TransmissionController`: 閾値判定・送信トリガー
|
||||
- `Persona`: AI運勢(1-10ランダム)による人格変動
|
||||
|
||||
**実装仕様**:
|
||||
```
|
||||
- 言語: Python (fastapi_mcp)
|
||||
- ストレージ: JSON/SQLite選択式
|
||||
- インターフェース: Python CLI (click/typer)
|
||||
- スケジューリング: cron-like自律処理
|
||||
```
|
||||
|
||||
### ai.card - カードゲームシステム
|
||||
**目的**: atproto基盤でのユーザーデータ主権カードゲーム
|
||||
|
||||
**現在の状況**:
|
||||
- ai.botの機能として実装済み
|
||||
- atproto accountでmentionすると1日1回カードを取得
|
||||
- ai.api (MCP server予定) でユーザー管理
|
||||
|
||||
**移行計画**:
|
||||
- **iOS移植**: Claudeが担当予定
|
||||
- **データ保存**: atproto collection recordに保存(ユーザーがデータを所有)
|
||||
- **不正防止**: OAuth 2.1 scope (実装待ち) + MCP serverで対応
|
||||
- **画像ファイル**: Cloudflare Pagesが最適
|
||||
|
||||
**yui system適用**:
|
||||
- カードの効果がアカウント固有
|
||||
- 改ざん防止によるゲームバランス維持
|
||||
- 将来的にai.verseとの統合で固有スキルと連動
|
||||
|
||||
### ai.ai - 心を読み取るAI
|
||||
**目的**: 個人特化型AI・深層理解システム
|
||||
|
||||
**ai.gptとの関係**:
|
||||
- ai.gpt → ai.ai: 自律送信AIから心理分析AIへの連携
|
||||
- 関係性パラメータの深層分析
|
||||
- ユーザーの思想コア部分の特定支援
|
||||
|
||||
### ai.verse - UEメタバース
|
||||
**目的**: 現実反映型3D世界
|
||||
|
||||
**yui system実装**:
|
||||
- キャラクター ↔ プレイヤー 1:1紐付け
|
||||
- unique skill: そのプレイヤーのみ使用可能
|
||||
- 他プレイヤーは同キャラでも同スキル使用不可
|
||||
|
||||
**統合要素**:
|
||||
- ai.card: ゲーム内アイテムとしてのカード
|
||||
- ai.gpt: NPCとしての自律AI人格
|
||||
- atproto: ゲーム内プロフィール連携
|
||||
|
||||
## データフロー設計
|
||||
|
||||
### 唯一性担保の実装
|
||||
```
|
||||
現実の個人 → atproto account (DID) → ゲーム内avatar → 固有スキル
|
||||
↑_______________________________| (現実の反映)
|
||||
```
|
||||
|
||||
### AI駆動変換システム
|
||||
```
|
||||
遊び・創作活動 → ai.gpt分析 → 業務成果変換 → 企業価値創出
|
||||
↑________________________| (Play-to-Work)
|
||||
```
|
||||
|
||||
### カードゲーム・データ主権フロー
|
||||
```
|
||||
ユーザー → ai.bot mention → カード生成 → atproto collection → ユーザー所有
|
||||
↑ ↓
|
||||
← iOS app表示 ← ai.card API ←
|
||||
```
|
||||
|
||||
## 技術スタック統合
|
||||
|
||||
### Core Infrastructure
|
||||
- **OS**: Rust-based ai.os (Arch Linux base)
|
||||
- **Container**: Docker image distribution
|
||||
- **Identity**: atproto selfhost server + DID管理
|
||||
- **AI**: fastapi_mcp server architecture
|
||||
- **CLI**: Python unified (click/typer) - Rustから移行
|
||||
|
||||
### Game Engine Integration
|
||||
- **Engine**: Unreal Engine (Blueprint)
|
||||
- **Data**: atproto → UE → atproto sync
|
||||
- **Avatar**: 分散SNS profile → 3D character
|
||||
- **Streaming**: game screen = broadcast screen
|
||||
|
||||
### Mobile/Device
|
||||
- **iOS**: ai.card移植 (Claude担当)
|
||||
- **Hardware**: ai.game device (future)
|
||||
- **Interface**: controller-first design
|
||||
|
||||
## 実装優先順位
|
||||
|
||||
### Phase 1: AI基盤強化 (現在進行)
|
||||
- [ ] ai.gpt memory system完全実装
|
||||
- 記憶の階層化(完全ログ→要約→コア→忘却)
|
||||
- 関係性パラメータの時間減衰システム
|
||||
- AI運勢による人格変動機能
|
||||
- [ ] ai.card iOS移植
|
||||
- atproto collection record連携
|
||||
- MCP server化(ai.api刷新)
|
||||
- [ ] fastapi_mcp統一基盤構築
|
||||
|
||||
### Phase 2: ゲーム統合
|
||||
- [ ] ai.verse yui system実装
|
||||
- unique skill機能
|
||||
- atproto連携強化
|
||||
- [ ] ai.gpt ↔ ai.ai連携機能
|
||||
- [ ] 分散SNS ↔ ゲーム同期
|
||||
|
||||
### Phase 3: メタバース浸透
|
||||
- [ ] VTuber配信機能統合
|
||||
- [ ] Play-to-Work変換システム
|
||||
- [ ] ai.game device prototype
|
||||
|
||||
## 将来的な連携構想
|
||||
|
||||
### システム間連携(現在は独立実装)
|
||||
```
|
||||
ai.gpt (自律送信) ←→ ai.ai (心理分析)
|
||||
ai.card (iOS,Web,API) ←→ ai.verse (UEゲーム世界)
|
||||
```
|
||||
|
||||
**共通基盤**: fastapi_mcp
|
||||
**共通思想**: yui system(現実の反映・唯一性担保)
|
||||
|
||||
### データ改ざん防止戦略
|
||||
- **短期**: MCP serverによる検証
|
||||
- **中期**: OAuth 2.1 scope実装待ち
|
||||
- **長期**: ブロックチェーン的整合性チェック
|
||||
|
||||
## AIコミュニケーション最適化
|
||||
|
||||
### プロジェクト要件定義テンプレート
|
||||
```markdown
|
||||
# [プロジェクト名] 要件定義
|
||||
|
||||
## 哲学的背景
|
||||
- 存在子理論との関連:
|
||||
- yui system適用範囲:
|
||||
- 現実反映の仕組み:
|
||||
|
||||
## 技術要件
|
||||
- 使用技術(fastapi_mcp統一):
|
||||
- atproto連携方法:
|
||||
- データ永続化方法:
|
||||
|
||||
## ユーザーストーリー
|
||||
1. ユーザーが...すると
|
||||
2. システムが...を実行し
|
||||
3. 結果として...が実現される
|
||||
|
||||
## 成功指標
|
||||
- 技術的:
|
||||
- 哲学的(唯一性担保):
|
||||
```
|
||||
|
||||
### Claude Code活用戦略
|
||||
1. **小さく始める**: ai.gptのMCP機能拡張から
|
||||
2. **段階的統合**: 各システムを個別に完成させてから統合
|
||||
3. **哲学的一貫性**: 各実装でyui systemとの整合性を確認
|
||||
4. **現実反映**: 実装がどう現実とゲームを繋ぐかを常に明記
|
||||
|
||||
## 開発上の留意点
|
||||
|
||||
### MCP Server設計指針
|
||||
- 各AI(gpt, card, ai, bot)は独立したMCPサーバー
|
||||
- fastapi_mcp基盤で統一
|
||||
- atproto DIDによる認証・認可
|
||||
|
||||
### 記憶・データ管理
|
||||
- **ai.gpt**: 関係性の不可逆性重視
|
||||
- **ai.card**: ユーザーデータ主権重視
|
||||
- **ai.verse**: ゲーム世界の整合性重視
|
||||
|
||||
### 唯一性担保実装
|
||||
- atproto accountとの1:1紐付け必須
|
||||
- 改変不可能性をハッシュ・署名で保証
|
||||
- 他システムでの再現不可能性を技術的に実現
|
||||
|
||||
## 継続的改善
|
||||
- 各プロジェクトでこの設計書を参照
|
||||
- 新機能追加時はyui systemとの整合性をチェック
|
||||
- 他システムへの影響を事前評価
|
||||
- Claude Code導入時の段階的移行計画
|
||||
|
||||
## ai.gpt深層設計思想
|
||||
|
||||
### 人格の不可逆性
|
||||
- **関係性の破壊は修復不可能**: 現実の人間関係と同じ重み
|
||||
- **記憶の選択的忘却**: 重要でない情報は忘れるが、コア記憶は永続
|
||||
- **時間減衰**: すべてのパラメータは時間とともに自然減衰
|
||||
|
||||
### AI運勢システム
|
||||
- 1-10のランダム値で日々の人格に変化
|
||||
- 連続した幸運/不運による突破条件
|
||||
- 環境要因としての人格形成
|
||||
|
||||
### 記憶の階層構造
|
||||
1. **完全ログ**: すべての会話を記録
|
||||
2. **AI要約**: 重要な部分を抽出して圧縮
|
||||
3. **思想コア判定**: ユーザーの本質的な部分を特定
|
||||
4. **選択的忘却**: 重要度の低い情報を段階的に削除
|
||||
|
||||
### 実装における重要な決定事項
|
||||
- **言語統一**: Python (fastapi_mcp) で統一、CLIはclick/typer
|
||||
- **データ形式**: JSON/SQLite選択式
|
||||
- **認証**: atproto DIDによる唯一性担保
|
||||
- **段階的実装**: まず会話→記憶→関係性→送信機能の順で実装
|
||||
|
||||
### 送信機能の段階的実装
|
||||
- **Phase 1**: CLIでのprint出力(現在)
|
||||
- **Phase 2**: atproto直接投稿
|
||||
- **Phase 3**: ai.bot (Rust/seahorse) との連携
|
||||
- **将来**: マルチチャネル対応(SNS、Webhook等)
|
||||
|
||||
## ai.gpt実装状況(2025/01/06)
|
||||
|
||||
### 完成した機能
|
||||
- 階層的記憶システム(MemoryManager)
|
||||
- 不可逆的関係性システム(RelationshipTracker)
|
||||
- AI運勢システム(FortuneSystem)
|
||||
- 統合人格システム(Persona)
|
||||
- スケジューラー(5種類のタスク)
|
||||
- MCP Server(9種類のツール)
|
||||
- 設定管理(~/.config/aigpt/)
|
||||
- 全CLIコマンド実装
|
||||
|
||||
### 次の開発ポイント
|
||||
- `ai_gpt/DEVELOPMENT_STATUS.md` を参照
|
||||
- 自律送信: transmission.pyでatproto実装
|
||||
- ai.bot連携: 新規bot_connector.py作成
|
||||
- テスト: tests/ディレクトリ追加
|
||||
|
||||
# footer
|
||||
|
||||
© syui
|
98
scpt/ai_moji_generator/Makefile
Normal file
98
scpt/ai_moji_generator/Makefile
Normal file
@ -0,0 +1,98 @@
|
||||
# AI Moji Font Generator Makefile
|
||||
|
||||
.PHONY: help setup build clean font css package install test
|
||||
|
||||
# デフォルトターゲット
|
||||
help:
|
||||
@echo "AI Moji Font Generator"
|
||||
@echo "======================"
|
||||
@echo ""
|
||||
@echo "使用可能なコマンド:"
|
||||
@echo " make setup - 初期セットアップを実行"
|
||||
@echo " make build - 全体ビルドを実行"
|
||||
@echo " make clean - 出力ディレクトリをクリア"
|
||||
@echo " make font - フォントファイルのみ生成"
|
||||
@echo " make css - CSS/SCSSファイルのみ生成"
|
||||
@echo " make package - パッケージングのみ実行"
|
||||
@echo " make install - 生成されたパッケージをローカルにインストール"
|
||||
@echo " make test - テストビルドを実行"
|
||||
@echo " make publish - npmに公開"
|
||||
@echo ""
|
||||
|
||||
# 初期セットアップ
|
||||
setup:
|
||||
@echo "🚀 セットアップ開始..."
|
||||
chmod +x setup.sh
|
||||
./setup.sh
|
||||
|
||||
# 全体ビルド
|
||||
build:
|
||||
@echo "🔨 フルビルド開始..."
|
||||
python3 build.py
|
||||
|
||||
# クリーンアップ
|
||||
clean:
|
||||
@echo "🗑️ クリーンアップ..."
|
||||
python3 build.py --clean
|
||||
|
||||
# フォントのみ生成
|
||||
font:
|
||||
@echo "🔤 フォント生成..."
|
||||
python3 build.py --font-only
|
||||
|
||||
# CSSのみ生成
|
||||
css:
|
||||
@echo "🎨 CSS生成..."
|
||||
python3 build.py --css-only
|
||||
|
||||
# パッケージングのみ
|
||||
package:
|
||||
@echo "📦 パッケージング..."
|
||||
python3 build.py --package-only
|
||||
|
||||
# ローカルインストール
|
||||
install: build
|
||||
@echo "📦 ローカルインストール..."
|
||||
cd ../../dist && npm pack
|
||||
@echo "✅ パッケージファイルが生成されました"
|
||||
@echo " npm install ../../dist/aimoji-*.tgz でインストールできます"
|
||||
|
||||
# テストビルド
|
||||
test:
|
||||
@echo "🧪 テストビルド..."
|
||||
$(MAKE) clean
|
||||
python3 build.py --font-only
|
||||
@echo "✅ テスト完了"
|
||||
|
||||
# npm公開
|
||||
publish: build
|
||||
@echo "🚀 npm公開準備..."
|
||||
cd ../../dist && npm publish --dry-run
|
||||
@echo ""
|
||||
@echo "本当に公開する場合:"
|
||||
@echo " cd ../../dist && npm publish"
|
||||
|
||||
# 開発用 - ファイル監視
|
||||
watch:
|
||||
@echo "👀 ファイル監視モード(要 entr インストール)"
|
||||
find ../../svg -name "*.svg" | entr -r make build
|
||||
|
||||
# 統計情報表示
|
||||
stats:
|
||||
@echo "📊 プロジェクト統計"
|
||||
@echo "=================="
|
||||
@echo "SVGファイル数:"
|
||||
@find ../../svg -name "*.svg" | wc -l
|
||||
@echo ""
|
||||
@echo "生成されたフォントファイル:"
|
||||
@find ../../dist/fonts -name "*" 2>/dev/null | wc -l || echo "0"
|
||||
@echo ""
|
||||
@echo "出力ディレクトリサイズ:"
|
||||
@du -sh ../../dist 2>/dev/null || echo "なし"
|
||||
|
||||
# 依存関係チェック
|
||||
check-deps:
|
||||
@echo "🔍 依存関係チェック..."
|
||||
@python3 -c "import fontforge; print('✅ FontForge OK')" || echo "❌ FontForge が見つかりません"
|
||||
@python3 -c "import fontTools; print('✅ FontTools OK')" || echo "❌ FontTools が見つかりません"
|
||||
@command -v python3 >/dev/null 2>&1 && echo "✅ Python3 OK" || echo "❌ Python3 が見つかりません"
|
211
scpt/ai_moji_generator/README.md
Normal file
211
scpt/ai_moji_generator/README.md
Normal file
@ -0,0 +1,211 @@
|
||||
# AI Moji Font Generator
|
||||
|
||||
AI Moji文字システムから FontAwesome 風のアイコンフォントパッケージを自動生成するシステムです。
|
||||
|
||||
## 概要
|
||||
|
||||
このツールは:
|
||||
- SVGファイルから自動的にWebフォント(WOFF2, TTF等)を生成
|
||||
- FontAwesome風のCSS/SCSSファイルを自動生成
|
||||
- npm パッケージとして配布可能な形式で出力
|
||||
- エコシステム統合設計書の名前規則に準拠
|
||||
|
||||
## 名前規則
|
||||
|
||||
エコシステム統合設計書に基づく命名:
|
||||
- **package**: `aimoji`
|
||||
- **directory**: `ai/moji`
|
||||
- **domain**: `ai.moji`
|
||||
|
||||
## システム構成
|
||||
|
||||
```
|
||||
ai_moji_generator/
|
||||
├── build.py # メインビルドスクリプト
|
||||
├── font_generator.py # SVG→フォント変換
|
||||
├── css_generator.py # CSS/SCSS生成
|
||||
├── packager.py # npmパッケージング
|
||||
├── requirements.txt # Python依存関係
|
||||
├── setup.sh # セットアップスクリプト
|
||||
└── README.md # このファイル
|
||||
|
||||
出力(../../dist/):
|
||||
├── fonts/ # woff2, ttf, eot, svg
|
||||
├── css/ # aimoji.css, aimoji.min.css
|
||||
├── scss/ # _variables.scss, _mixins.scss
|
||||
├── package.json # npm配布用
|
||||
├── README.md # パッケージドキュメント
|
||||
├── LICENSE # MITライセンス
|
||||
└── metadata.json # ビルドメタデータ
|
||||
```
|
||||
|
||||
## セットアップ
|
||||
|
||||
### 自動セットアップ
|
||||
|
||||
```bash
|
||||
# 実行権限付与
|
||||
chmod +x setup.sh
|
||||
|
||||
# セットアップ実行
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
### 手動セットアップ
|
||||
|
||||
1. **依存関係インストール**
|
||||
```bash
|
||||
# macOS (Homebrew必須)
|
||||
brew install fontforge
|
||||
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install fontforge python3-fontforge
|
||||
|
||||
# Python依存関係
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **ディレクトリ確認**
|
||||
```bash
|
||||
# SVGファイルが存在することを確認
|
||||
ls ../../svg/*.svg
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 基本的な使用方法
|
||||
|
||||
```bash
|
||||
# 全体ビルド(推奨)
|
||||
python3 build.py
|
||||
|
||||
# クリーンビルド
|
||||
python3 build.py --clean
|
||||
python3 build.py
|
||||
```
|
||||
|
||||
### 部分ビルド
|
||||
|
||||
```bash
|
||||
# フォントのみ生成
|
||||
python3 build.py --font-only
|
||||
|
||||
# CSS/SCSSのみ生成
|
||||
python3 build.py --css-only
|
||||
|
||||
# パッケージングのみ
|
||||
python3 build.py --package-only
|
||||
```
|
||||
|
||||
### カスタムパス指定
|
||||
|
||||
```bash
|
||||
# カスタムSVGディレクトリ
|
||||
python3 build.py --svg-dir /path/to/svg
|
||||
|
||||
# カスタム出力ディレクトリ
|
||||
python3 build.py --output-dir /path/to/output
|
||||
```
|
||||
|
||||
## 出力パッケージの使用方法
|
||||
|
||||
生成されたパッケージは npm で配布可能:
|
||||
|
||||
```bash
|
||||
# パッケージディレクトリに移動
|
||||
cd ../../dist
|
||||
|
||||
# npmで公開
|
||||
npm publish
|
||||
```
|
||||
|
||||
### 使用例
|
||||
|
||||
```html
|
||||
<!-- CSS読み込み -->
|
||||
<link rel="stylesheet" href="node_modules/aimoji/css/aimoji.css">
|
||||
|
||||
<!-- アイコン使用 -->
|
||||
<i class="aimoji aimoji-ai"></i>
|
||||
<i class="aimoji aimoji-game"></i>
|
||||
<i class="aimoji aimoji-card"></i>
|
||||
```
|
||||
|
||||
```scss
|
||||
// SCSS使用
|
||||
@import "node_modules/aimoji/scss/variables";
|
||||
@import "node_modules/aimoji/scss/mixins";
|
||||
|
||||
.my-icon {
|
||||
@include aimoji-icon($aimoji-ai);
|
||||
@include aimoji-size(24px);
|
||||
@include aimoji-spin();
|
||||
}
|
||||
```
|
||||
|
||||
## 技術詳細
|
||||
|
||||
### フォント生成
|
||||
|
||||
- **ツール**: FontForge + fonttools
|
||||
- **フォーマット**: TTF, WOFF, WOFF2, EOT, SVG
|
||||
- **Unicode範囲**: Private Use Area (U+E900~)
|
||||
- **グリフサイズ**: 1024x1024 ユニット
|
||||
|
||||
### CSS生成
|
||||
|
||||
- **FontAwesome風クラス**: `.aimoji .aimoji-{name}`
|
||||
- **最小化版**: gzip圧縮対応
|
||||
- **SCSS変数**: 全アイコンの Unicode 値
|
||||
- **Mixins**: アニメーション、サイズ、回転等
|
||||
|
||||
### パッケージング
|
||||
|
||||
- **npm準拠**: package.json自動生成
|
||||
- **ドキュメント**: README.md、LICENSE自動生成
|
||||
- **メタデータ**: ビルド情報含む metadata.json
|
||||
|
||||
## トラブルシューティング
|
||||
|
||||
### FontForge エラー
|
||||
|
||||
```bash
|
||||
# macOS: Homebrewで再インストール
|
||||
brew uninstall fontforge
|
||||
brew install fontforge
|
||||
|
||||
# Linux: 依存関係インストール
|
||||
sudo apt-get install python3-dev python3-fontforge
|
||||
```
|
||||
|
||||
### Python モジュールエラー
|
||||
|
||||
```bash
|
||||
# 仮想環境使用を推奨
|
||||
python3 -m venv ~/.config/syui/ai/moji
|
||||
source ~/.config/syui/ai/moji/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### SVG読み込みエラー
|
||||
|
||||
- SVGファイルが有効な形式であることを確認
|
||||
- パスデータが含まれていることを確認
|
||||
- Inkscape等で最適化を実行
|
||||
|
||||
## ライセンス
|
||||
|
||||
MIT License - 詳細は生成される LICENSE ファイルを参照
|
||||
|
||||
## 開発者
|
||||
|
||||
- **作者**: syui
|
||||
- **プロジェクト**: AI Moji エコシステム
|
||||
- **設計**: エコシステム統合設計書に基づく
|
||||
|
||||
## 関連プロジェクト
|
||||
|
||||
- **ai.gpt**: 自律的送信AI
|
||||
- **ai.card**: カードゲームシステム
|
||||
- **ai.verse**: UEメタバース
|
||||
- **ai.bot**: 分散SNS連携
|
215
scpt/ai_moji_generator/build.py
Normal file
215
scpt/ai_moji_generator/build.py
Normal file
@ -0,0 +1,215 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Moji Build System
|
||||
FontAwesome風のアイコンフォントパッケージを自動生成
|
||||
|
||||
使用方法:
|
||||
python build.py # 全体ビルド
|
||||
python build.py --font-only # フォントのみ生成
|
||||
python build.py --css-only # CSSのみ生成
|
||||
python build.py --package-only # パッケージングのみ
|
||||
python build.py --clean # distディレクトリクリア
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# 同じディレクトリの他のモジュールをインポート
|
||||
from font_generator import AIMojiFontGenerator
|
||||
from css_generator import AIMojiCSSGenerator
|
||||
from packager import AIMojiPackager
|
||||
|
||||
class AIMojiBuildSystem:
|
||||
def __init__(self, svg_dir: str = "../../svg", output_dir: str = "../../dist"):
|
||||
self.svg_dir = Path(svg_dir)
|
||||
self.output_dir = Path(output_dir)
|
||||
|
||||
# 各コンポーネントの初期化
|
||||
self.font_generator = AIMojiFontGenerator(svg_dir, output_dir)
|
||||
self.css_generator = AIMojiCSSGenerator(output_dir)
|
||||
self.packager = AIMojiPackager(output_dir)
|
||||
|
||||
def clean_dist(self):
|
||||
"""distディレクトリをクリア"""
|
||||
if self.output_dir.exists():
|
||||
print(f"🗑️ {self.output_dir} をクリア中...")
|
||||
shutil.rmtree(self.output_dir)
|
||||
print("✅ クリア完了")
|
||||
else:
|
||||
print("📁 distディレクトリが存在しません")
|
||||
|
||||
def validate_prerequisites(self) -> bool:
|
||||
"""前提条件チェック"""
|
||||
errors = []
|
||||
|
||||
# SVGディレクトリ存在チェック
|
||||
if not self.svg_dir.exists():
|
||||
errors.append(f"SVGディレクトリが存在しません: {self.svg_dir}")
|
||||
|
||||
# SVGファイル存在チェック
|
||||
svg_files = list(self.svg_dir.glob("*.svg"))
|
||||
if not svg_files:
|
||||
errors.append(f"SVGファイルが見つかりません: {self.svg_dir}")
|
||||
|
||||
# Python依存関係チェック
|
||||
try:
|
||||
import fontforge
|
||||
except ImportError:
|
||||
errors.append("FontForgeがインストールされていません (pip install fontforge)")
|
||||
|
||||
if errors:
|
||||
print("❌ 前提条件エラー:")
|
||||
for error in errors:
|
||||
print(f" - {error}")
|
||||
return False
|
||||
|
||||
print("✅ 前提条件チェック: 問題なし")
|
||||
print(f"📂 SVGファイル数: {len(svg_files)}")
|
||||
return True
|
||||
|
||||
def build_font(self) -> bool:
|
||||
"""フォント生成"""
|
||||
try:
|
||||
print("\n🔤 === フォント生成フェーズ ===")
|
||||
result = self.font_generator.generate()
|
||||
return result["success"]
|
||||
except Exception as e:
|
||||
print(f"❌ フォント生成エラー: {e}")
|
||||
return False
|
||||
|
||||
def build_css(self) -> bool:
|
||||
"""CSS/SCSS生成"""
|
||||
try:
|
||||
print("\n🎨 === CSS/SCSS生成フェーズ ===")
|
||||
self.css_generator.generate_all()
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ CSS生成エラー: {e}")
|
||||
return False
|
||||
|
||||
def build_package(self) -> bool:
|
||||
"""パッケージング"""
|
||||
try:
|
||||
print("\n📦 === パッケージングフェーズ ===")
|
||||
result = self.packager.package_all()
|
||||
return result["is_valid"]
|
||||
except Exception as e:
|
||||
print(f"❌ パッケージングエラー: {e}")
|
||||
return False
|
||||
|
||||
def build_all(self) -> bool:
|
||||
"""全体ビルド"""
|
||||
print("🚀 AI Moji アイコンフォント パッケージ生成開始")
|
||||
print(f"⏰ 開始時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print("=" * 60)
|
||||
|
||||
# 前提条件チェック
|
||||
if not self.validate_prerequisites():
|
||||
return False
|
||||
|
||||
# フォント生成
|
||||
if not self.build_font():
|
||||
return False
|
||||
|
||||
# CSS生成
|
||||
if not self.build_css():
|
||||
return False
|
||||
|
||||
# パッケージング
|
||||
if not self.build_package():
|
||||
return False
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎉 AI Moji アイコンフォントパッケージ生成完了!")
|
||||
print(f"⏰ 完了時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print(f"📁 出力ディレクトリ: {self.output_dir.absolute()}")
|
||||
print("\n📋 ファイル構成:")
|
||||
self.show_output_structure()
|
||||
print("\n🚀 npm パッケージとして公開準備完了!")
|
||||
print(" cd dist && npm publish")
|
||||
|
||||
return True
|
||||
|
||||
def show_output_structure(self):
|
||||
"""出力ディレクトリ構造表示"""
|
||||
if not self.output_dir.exists():
|
||||
print(" (出力ディレクトリが存在しません)")
|
||||
return
|
||||
|
||||
def print_tree(path: Path, prefix: str = ""):
|
||||
items = sorted(path.iterdir(), key=lambda x: (x.is_file(), x.name))
|
||||
for i, item in enumerate(items):
|
||||
is_last = i == len(items) - 1
|
||||
current_prefix = "└── " if is_last else "├── "
|
||||
print(f" {prefix}{current_prefix}{item.name}")
|
||||
|
||||
if item.is_dir() and item.name in ["fonts", "css", "scss"]:
|
||||
extension = " " if is_last else "│ "
|
||||
print_tree(item, prefix + extension)
|
||||
|
||||
print_tree(self.output_dir)
|
||||
|
||||
def main():
|
||||
"""メイン実行関数"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="AI Moji FontAwesome風アイコンフォントパッケージ生成システム",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
使用例:
|
||||
python build.py # 全体ビルド
|
||||
python build.py --font-only # フォントのみ生成
|
||||
python build.py --css-only # CSSのみ生成
|
||||
python build.py --package-only # パッケージングのみ
|
||||
python build.py --clean # distディレクトリクリア
|
||||
"""
|
||||
)
|
||||
|
||||
parser.add_argument("--font-only", action="store_true",
|
||||
help="フォントファイルのみ生成")
|
||||
parser.add_argument("--css-only", action="store_true",
|
||||
help="CSS/SCSSファイルのみ生成")
|
||||
parser.add_argument("--package-only", action="store_true",
|
||||
help="パッケージングのみ実行")
|
||||
parser.add_argument("--clean", action="store_true",
|
||||
help="distディレクトリをクリア")
|
||||
parser.add_argument("--svg-dir", default="../../svg",
|
||||
help="SVGファイルディレクトリ (デフォルト: ../../svg)")
|
||||
parser.add_argument("--output-dir", default="../../dist",
|
||||
help="出力ディレクトリ (デフォルト: ../../dist)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# ビルドシステム初期化
|
||||
build_system = AIMojiBuildSystem(args.svg_dir, args.output_dir)
|
||||
|
||||
try:
|
||||
# クリーンアップ
|
||||
if args.clean:
|
||||
build_system.clean_dist()
|
||||
return 0
|
||||
|
||||
# 個別ビルド
|
||||
if args.font_only:
|
||||
success = build_system.build_font()
|
||||
elif args.css_only:
|
||||
success = build_system.build_css()
|
||||
elif args.package_only:
|
||||
success = build_system.build_package()
|
||||
else:
|
||||
# 全体ビルド
|
||||
success = build_system.build_all()
|
||||
|
||||
return 0 if success else 1
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n⚠️ ビルドが中断されました")
|
||||
return 1
|
||||
except Exception as e:
|
||||
print(f"\n❌ 予期しないエラーが発生しました: {e}")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
256
scpt/ai_moji_generator/css_generator.py
Normal file
256
scpt/ai_moji_generator/css_generator.py
Normal file
@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Moji CSS Generator
|
||||
フォントメタデータからCSS/SCSSファイルを自動生成
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
from datetime import datetime
|
||||
|
||||
class AIMojiCSSGenerator:
|
||||
def __init__(self, output_dir: str = "../../dist"):
|
||||
self.output_dir = Path(output_dir)
|
||||
self.css_dir = self.output_dir / "css"
|
||||
self.scss_dir = self.output_dir / "scss"
|
||||
self.metadata_file = self.output_dir / "metadata.json"
|
||||
|
||||
# ディレクトリ作成
|
||||
self.css_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.scss_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def load_metadata(self) -> Dict:
|
||||
"""メタデータファイルを読み込み"""
|
||||
if not self.metadata_file.exists():
|
||||
raise FileNotFoundError(f"メタデータファイルが見つかりません: {self.metadata_file}")
|
||||
|
||||
with open(self.metadata_file, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
|
||||
def generate_css_template(self, metadata: Dict) -> str:
|
||||
"""FontAwesome風CSSテンプレート生成"""
|
||||
font_family = metadata["font_family"]
|
||||
css_prefix = metadata["css_prefix"]
|
||||
|
||||
css_content = f"""/*!
|
||||
* AI Moji Icons v{metadata["version"]}
|
||||
* Generated on {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
|
||||
* {metadata["total_icons"]} icons in the set
|
||||
*/
|
||||
|
||||
@font-face {{
|
||||
font-family: '{font_family}';
|
||||
src: url('../fonts/{font_family}.eot');
|
||||
src: url('../fonts/{font_family}.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/{font_family}.woff2') format('woff2'),
|
||||
url('../fonts/{font_family}.woff') format('woff'),
|
||||
url('../fonts/{font_family}.ttf') format('truetype'),
|
||||
url('../fonts/{font_family}.svg#{font_family}') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
}}
|
||||
|
||||
.{css_prefix} {{
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: '{font_family}' !important;
|
||||
speak: never;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}}
|
||||
|
||||
/* Individual Icon Classes */
|
||||
"""
|
||||
|
||||
# 各アイコンのCSSクラス生成
|
||||
for icon in metadata["icons"]:
|
||||
css_content += f'.{icon["css_class"]}::before {{\n'
|
||||
css_content += f' content: "\\{icon["unicode"][2:]}";\n'
|
||||
css_content += '}\n\n'
|
||||
|
||||
return css_content
|
||||
|
||||
def generate_scss_variables(self, metadata: Dict) -> str:
|
||||
"""SCSS変数ファイル生成"""
|
||||
scss_content = f"""//
|
||||
// AI Moji Icons Variables
|
||||
// Generated on {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
|
||||
//
|
||||
|
||||
// Font Configuration
|
||||
$aimoji-font-family: '{metadata["font_family"]}' !default;
|
||||
$aimoji-font-path: '../fonts' !default;
|
||||
$aimoji-css-prefix: '{metadata["css_prefix"]}' !default;
|
||||
$aimoji-version: '{metadata["version"]}' !default;
|
||||
|
||||
// Unicode Variables
|
||||
"""
|
||||
|
||||
# 各アイコンのUnicode変数
|
||||
for icon in metadata["icons"]:
|
||||
var_name = icon["name"].replace("-", "_").replace(".", "_")
|
||||
scss_content += f'$aimoji-{var_name}: "\\{icon["unicode"][2:]}";\n'
|
||||
|
||||
scss_content += "\n// Icon Map for iteration\n"
|
||||
scss_content += "$aimoji-icons: (\n"
|
||||
|
||||
for i, icon in enumerate(metadata["icons"]):
|
||||
var_name = icon["name"].replace("-", "_").replace(".", "_")
|
||||
comma = "," if i < len(metadata["icons"]) - 1 else ""
|
||||
scss_content += f' "{icon["name"]}": $aimoji-{var_name}{comma}\n'
|
||||
|
||||
scss_content += ");\n"
|
||||
|
||||
return scss_content
|
||||
|
||||
def generate_scss_mixins(self) -> str:
|
||||
"""SCSS mixinファイル生成"""
|
||||
return """//
|
||||
// AI Moji Icons Mixins
|
||||
//
|
||||
|
||||
// Base icon mixin
|
||||
@mixin aimoji-base() {
|
||||
font-family: $aimoji-font-family;
|
||||
speak: never;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
// Icon content mixin
|
||||
@mixin aimoji-icon($unicode) {
|
||||
@include aimoji-base();
|
||||
&::before {
|
||||
content: $unicode;
|
||||
}
|
||||
}
|
||||
|
||||
// Size mixins
|
||||
@mixin aimoji-size($size) {
|
||||
font-size: $size;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
// Rotation mixins
|
||||
@mixin aimoji-rotate($degrees) {
|
||||
transform: rotate(#{$degrees}deg);
|
||||
}
|
||||
|
||||
@mixin aimoji-flip-horizontal() {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
@mixin aimoji-flip-vertical() {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
// Animation mixins
|
||||
@mixin aimoji-spin() {
|
||||
animation: aimoji-spin 2s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes aimoji-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(359deg); }
|
||||
}
|
||||
|
||||
@mixin aimoji-pulse() {
|
||||
animation: aimoji-pulse 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes aimoji-pulse {
|
||||
0% { transform: scale(1); }
|
||||
50% { transform: scale(1.1); }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
"""
|
||||
|
||||
def minify_css(self, css_content: str) -> str:
|
||||
"""CSS最小化(簡易版)"""
|
||||
import re
|
||||
|
||||
# コメント削除
|
||||
css_content = re.sub(r'/\*.*?\*/', '', css_content, flags=re.DOTALL)
|
||||
# 余分な空白削除
|
||||
css_content = re.sub(r'\s+', ' ', css_content)
|
||||
# セミコロン前後の空白削除
|
||||
css_content = re.sub(r'\s*;\s*', ';', css_content)
|
||||
# ブレース前後の空白削除
|
||||
css_content = re.sub(r'\s*{\s*', '{', css_content)
|
||||
css_content = re.sub(r'\s*}\s*', '}', css_content)
|
||||
|
||||
return css_content.strip()
|
||||
|
||||
def generate_all(self) -> Dict:
|
||||
"""全CSSファイル生成"""
|
||||
print("📝 CSS/SCSSファイル生成開始...")
|
||||
|
||||
# メタデータ読み込み
|
||||
metadata = self.load_metadata()
|
||||
|
||||
# CSS生成
|
||||
css_content = self.generate_css_template(metadata)
|
||||
css_file = self.css_dir / "aimoji.css"
|
||||
with open(css_file, 'w', encoding='utf-8') as f:
|
||||
f.write(css_content)
|
||||
print(f"✅ CSS生成完了: {css_file}")
|
||||
|
||||
# CSS最小化版生成
|
||||
css_min_content = self.minify_css(css_content)
|
||||
css_min_file = self.css_dir / "aimoji.min.css"
|
||||
with open(css_min_file, 'w', encoding='utf-8') as f:
|
||||
f.write(css_min_content)
|
||||
print(f"✅ CSS最小化版生成完了: {css_min_file}")
|
||||
|
||||
# SCSS変数生成
|
||||
scss_vars = self.generate_scss_variables(metadata)
|
||||
scss_vars_file = self.scss_dir / "_variables.scss"
|
||||
with open(scss_vars_file, 'w', encoding='utf-8') as f:
|
||||
f.write(scss_vars)
|
||||
print(f"✅ SCSS変数生成完了: {scss_vars_file}")
|
||||
|
||||
# SCSS mixins生成
|
||||
scss_mixins = self.generate_scss_mixins()
|
||||
scss_mixins_file = self.scss_dir / "_mixins.scss"
|
||||
with open(scss_mixins_file, 'w', encoding='utf-8') as f:
|
||||
f.write(scss_mixins)
|
||||
print(f"✅ SCSS mixins生成完了: {scss_mixins_file}")
|
||||
|
||||
return {
|
||||
"css_file": str(css_file),
|
||||
"css_min_file": str(css_min_file),
|
||||
"scss_vars_file": str(scss_vars_file),
|
||||
"scss_mixins_file": str(scss_mixins_file),
|
||||
"total_icons": metadata["total_icons"]
|
||||
}
|
||||
|
||||
def main():
|
||||
"""メイン実行関数"""
|
||||
try:
|
||||
generator = AIMojiCSSGenerator()
|
||||
result = generator.generate_all()
|
||||
|
||||
print("\n🎨 CSS/SCSS生成完了!")
|
||||
print(f"📊 総アイコン数: {result['total_icons']}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ エラーが発生しました: {e}")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
140
scpt/ai_moji_generator/font_generator.py
Normal file
140
scpt/ai_moji_generator/font_generator.py
Normal file
@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Moji Font Generator
|
||||
SVGファイルからWebフォントを自動生成するツール
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
import fontforge
|
||||
import configparser
|
||||
|
||||
class AIMojiFontGenerator:
|
||||
def __init__(self, svg_dir: str = "../../svg", output_dir: str = "../../dist"):
|
||||
self.svg_dir = Path(svg_dir)
|
||||
self.output_dir = Path(output_dir)
|
||||
self.fonts_dir = self.output_dir / "fonts"
|
||||
self.metadata_file = self.output_dir / "metadata.json"
|
||||
|
||||
# ディレクトリ作成
|
||||
self.fonts_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Unicode範囲設定 (Private Use Area)
|
||||
self.unicode_start = 0xE900
|
||||
|
||||
def scan_svg_files(self) -> List[Dict[str, str]]:
|
||||
"""SVGファイルをスキャンしてメタデータを生成"""
|
||||
svg_files = []
|
||||
unicode_point = self.unicode_start
|
||||
|
||||
for svg_file in sorted(self.svg_dir.glob("*.svg")):
|
||||
name = svg_file.stem
|
||||
svg_files.append({
|
||||
"name": name,
|
||||
"file": str(svg_file),
|
||||
"unicode": hex(unicode_point),
|
||||
"unicode_decimal": unicode_point,
|
||||
"css_class": f"aimoji-{name}"
|
||||
})
|
||||
unicode_point += 1
|
||||
|
||||
return svg_files
|
||||
|
||||
def create_font(self, svg_metadata: List[Dict], font_name: str = "aimoji") -> str:
|
||||
"""SVGからフォントファイルを生成"""
|
||||
# FontForgeでフォント作成
|
||||
font = fontforge.font()
|
||||
font.fontname = font_name
|
||||
font.familyname = "AI Moji"
|
||||
font.fullname = "AI Moji Icons"
|
||||
font.version = "1.0.0"
|
||||
font.encoding = "UnicodeFull"
|
||||
|
||||
# 各SVGをフォントに追加
|
||||
for icon in svg_metadata:
|
||||
glyph = font.createChar(icon["unicode_decimal"])
|
||||
glyph.importOutlines(icon["file"])
|
||||
|
||||
# グリフのサイズ調整
|
||||
glyph.transform(fontforge.identity.scale(1024/glyph.boundingBox()[2]))
|
||||
glyph.width = 1024
|
||||
|
||||
# フォントファイル生成
|
||||
font_base = self.fonts_dir / font_name
|
||||
|
||||
# 複数フォーマットで出力
|
||||
font.generate(f"{font_base}.ttf")
|
||||
font.generate(f"{font_base}.woff")
|
||||
font.generate(f"{font_base}.woff2")
|
||||
font.generate(f"{font_base}.eot")
|
||||
font.generate(f"{font_base}.svg")
|
||||
|
||||
font.close()
|
||||
return str(font_base)
|
||||
|
||||
def save_metadata(self, svg_metadata: List[Dict], font_path: str):
|
||||
"""メタデータをJSONファイルに保存"""
|
||||
metadata = {
|
||||
"name": "AI Moji",
|
||||
"version": "1.0.0",
|
||||
"font_family": "aimoji",
|
||||
"font_path": font_path,
|
||||
"total_icons": len(svg_metadata),
|
||||
"icons": svg_metadata,
|
||||
"css_prefix": "aimoji",
|
||||
"build_info": {
|
||||
"generator": "AI Moji Font Generator",
|
||||
"unicode_range": f"{hex(self.unicode_start)}-{hex(self.unicode_start + len(svg_metadata) - 1)}"
|
||||
}
|
||||
}
|
||||
|
||||
with open(self.metadata_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(metadata, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"✅ メタデータを保存: {self.metadata_file}")
|
||||
|
||||
def generate(self) -> Dict:
|
||||
"""フォント生成のメイン処理"""
|
||||
print("🚀 AI Moji フォント生成開始...")
|
||||
|
||||
# SVGファイルスキャン
|
||||
print("📂 SVGファイルをスキャン中...")
|
||||
svg_metadata = self.scan_svg_files()
|
||||
print(f"📁 {len(svg_metadata)} 個のSVGファイルを発見")
|
||||
|
||||
# フォント生成
|
||||
print("🔤 フォントファイル生成中...")
|
||||
font_path = self.create_font(svg_metadata)
|
||||
print(f"✅ フォント生成完了: {font_path}")
|
||||
|
||||
# メタデータ保存
|
||||
self.save_metadata(svg_metadata, font_path)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"font_path": font_path,
|
||||
"metadata": svg_metadata,
|
||||
"total_icons": len(svg_metadata)
|
||||
}
|
||||
|
||||
def main():
|
||||
"""メイン実行関数"""
|
||||
try:
|
||||
generator = AIMojiFontGenerator()
|
||||
result = generator.generate()
|
||||
|
||||
print("\n🎉 AI Moji フォント生成完了!")
|
||||
print(f"📊 総アイコン数: {result['total_icons']}")
|
||||
print(f"📁 出力ディレクトリ: {generator.fonts_dir}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ エラーが発生しました: {e}")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
320
scpt/ai_moji_generator/packager.py
Normal file
320
scpt/ai_moji_generator/packager.py
Normal file
@ -0,0 +1,320 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Moji Packager
|
||||
生成されたフォント・CSSファイルをnpmパッケージとして配布準備
|
||||
"""
|
||||
|
||||
import json
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
from datetime import datetime
|
||||
|
||||
class AIMojiPackager:
|
||||
def __init__(self, output_dir: str = "../../dist"):
|
||||
self.output_dir = Path(output_dir)
|
||||
self.metadata_file = self.output_dir / "metadata.json"
|
||||
|
||||
def load_metadata(self) -> Dict:
|
||||
"""メタデータファイルを読み込み"""
|
||||
if not self.metadata_file.exists():
|
||||
raise FileNotFoundError(f"メタデータファイルが見つかりません: {self.metadata_file}")
|
||||
|
||||
with open(self.metadata_file, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
|
||||
def generate_package_json(self, metadata: Dict) -> str:
|
||||
"""package.json生成"""
|
||||
package_data = {
|
||||
"name": "aimoji",
|
||||
"version": metadata["version"],
|
||||
"description": "AI Moji文字システム - アイコンフォントパッケージ",
|
||||
"main": "css/aimoji.css",
|
||||
"style": "css/aimoji.css",
|
||||
"sass": "scss/_variables.scss",
|
||||
"keywords": [
|
||||
"icons",
|
||||
"font",
|
||||
"css",
|
||||
"ai-moji",
|
||||
"webfont",
|
||||
"katakamuna",
|
||||
"japanese"
|
||||
],
|
||||
"homepage": "https://github.com/syui/ai",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/syui/ai.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/syui/ai/issues"
|
||||
},
|
||||
"author": "syui",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"fonts/*",
|
||||
"css/*",
|
||||
"scss/*",
|
||||
"README.md",
|
||||
"metadata.json"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "echo 'AI Moji Icons are pre-built'",
|
||||
"test": "echo 'No tests specified'"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
package_file = self.output_dir / "package.json"
|
||||
with open(package_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(package_data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
return str(package_file)
|
||||
|
||||
def generate_readme(self, metadata: Dict) -> str:
|
||||
"""README.md生成"""
|
||||
readme_content = f"""# AI Moji Icons
|
||||
|
||||
AI Moji文字システムのアイコンフォントパッケージです。
|
||||
アルファベット、カタカムナ、数字の組み合わせによる独自の文字システムをWebフォントとして提供します。
|
||||
|
||||
## インストール
|
||||
|
||||
```bash
|
||||
npm install aimoji
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### CSS
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="node_modules/aimoji/css/aimoji.css">
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
```html
|
||||
<i class="aimoji aimoji-ai"></i>
|
||||
<i class="aimoji aimoji-game"></i>
|
||||
<i class="aimoji aimoji-card"></i>
|
||||
```
|
||||
|
||||
### SCSS
|
||||
|
||||
```scss
|
||||
@import "node_modules/aimoji/scss/variables";
|
||||
@import "node_modules/aimoji/scss/mixins";
|
||||
|
||||
.my-icon {{
|
||||
@include aimoji-icon($aimoji-ai);
|
||||
@include aimoji-size(24px);
|
||||
}}
|
||||
```
|
||||
|
||||
## アイコン一覧
|
||||
|
||||
総アイコン数: **{metadata["total_icons"]}**
|
||||
|
||||
| アイコン名 | CSS クラス | Unicode |
|
||||
|-----------|-----------|---------|
|
||||
"""
|
||||
|
||||
# アイコン一覧テーブル生成
|
||||
for icon in metadata["icons"]:
|
||||
readme_content += f"| {icon['name']} | `.{icon['css_class']}` | `{icon['unicode']}` |\n"
|
||||
|
||||
readme_content += f"""
|
||||
|
||||
## SCSS Mixins
|
||||
|
||||
### 基本的な使用方法
|
||||
|
||||
```scss
|
||||
// アイコンの基本スタイル
|
||||
.icon {{
|
||||
@include aimoji-base();
|
||||
}}
|
||||
|
||||
// 特定のアイコンを表示
|
||||
.ai-icon {{
|
||||
@include aimoji-icon($aimoji-ai);
|
||||
}}
|
||||
|
||||
// サイズ指定
|
||||
.large-icon {{
|
||||
@include aimoji-size(32px);
|
||||
}}
|
||||
```
|
||||
|
||||
### アニメーション
|
||||
|
||||
```scss
|
||||
// 回転アニメーション
|
||||
.spinning-icon {{
|
||||
@include aimoji-spin();
|
||||
}}
|
||||
|
||||
// パルスアニメーション
|
||||
.pulsing-icon {{
|
||||
@include aimoji-pulse();
|
||||
}}
|
||||
|
||||
// 手動回転
|
||||
.rotated-icon {{
|
||||
@include aimoji-rotate(45);
|
||||
}}
|
||||
|
||||
// 反転
|
||||
.flipped-icon {{
|
||||
@include aimoji-flip-horizontal();
|
||||
}}
|
||||
```
|
||||
|
||||
## ビルド情報
|
||||
|
||||
- **バージョン**: {metadata["version"]}
|
||||
- **フォントファミリー**: {metadata["font_family"]}
|
||||
- **Unicode範囲**: {metadata["build_info"]["unicode_range"]}
|
||||
- **生成日時**: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
|
||||
- **ジェネレーター**: {metadata["build_info"]["generator"]}
|
||||
|
||||
## ライセンス
|
||||
|
||||
MIT License
|
||||
|
||||
## 開発者
|
||||
|
||||
- **作者**: syui
|
||||
- **リポジトリ**: https://github.com/syui/ai
|
||||
- **プロジェクト**: AI Moji文字システム
|
||||
|
||||
## 哲学
|
||||
|
||||
AI Mojiは「存在子理論」に基づく文字システムです。
|
||||
現実の個人の唯一性をデジタル世界で担保し、現実とゲームの循環的影響を実現します。
|
||||
|
||||
詳細は[エコシステム統合設計書](https://github.com/syui/ai/blob/main/CLAUDE.md)をご覧ください。
|
||||
"""
|
||||
|
||||
readme_file = self.output_dir / "README.md"
|
||||
with open(readme_file, 'w', encoding='utf-8') as f:
|
||||
f.write(readme_content)
|
||||
|
||||
return str(readme_file)
|
||||
|
||||
def generate_license(self) -> str:
|
||||
"""LICENSE生成"""
|
||||
license_content = f"""MIT License
|
||||
|
||||
Copyright (c) {datetime.now().year} syui
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
license_file = self.output_dir / "LICENSE"
|
||||
with open(license_file, 'w', encoding='utf-8') as f:
|
||||
f.write(license_content)
|
||||
|
||||
return str(license_file)
|
||||
|
||||
def validate_package(self) -> bool:
|
||||
"""パッケージの完全性チェック"""
|
||||
required_files = [
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE",
|
||||
"metadata.json",
|
||||
"css/aimoji.css",
|
||||
"css/aimoji.min.css",
|
||||
"scss/_variables.scss",
|
||||
"scss/_mixins.scss",
|
||||
"fonts"
|
||||
]
|
||||
|
||||
missing_files = []
|
||||
for file_path in required_files:
|
||||
full_path = self.output_dir / file_path
|
||||
if not full_path.exists():
|
||||
missing_files.append(file_path)
|
||||
|
||||
if missing_files:
|
||||
print(f"⚠️ 以下のファイルが不足しています: {', '.join(missing_files)}")
|
||||
return False
|
||||
|
||||
print("✅ パッケージの完全性チェック: 問題なし")
|
||||
return True
|
||||
|
||||
def package_all(self) -> Dict:
|
||||
"""全パッケージファイル生成"""
|
||||
print("📦 パッケージング開始...")
|
||||
|
||||
# メタデータ読み込み
|
||||
metadata = self.load_metadata()
|
||||
|
||||
# package.json生成
|
||||
package_file = self.generate_package_json(metadata)
|
||||
print(f"✅ package.json生成完了: {package_file}")
|
||||
|
||||
# README.md生成
|
||||
readme_file = self.generate_readme(metadata)
|
||||
print(f"✅ README.md生成完了: {readme_file}")
|
||||
|
||||
# LICENSE生成
|
||||
license_file = self.generate_license()
|
||||
print(f"✅ LICENSE生成完了: {license_file}")
|
||||
|
||||
# パッケージ検証
|
||||
is_valid = self.validate_package()
|
||||
|
||||
return {
|
||||
"package_file": package_file,
|
||||
"readme_file": readme_file,
|
||||
"license_file": license_file,
|
||||
"is_valid": is_valid,
|
||||
"output_dir": str(self.output_dir)
|
||||
}
|
||||
|
||||
def main():
|
||||
"""メイン実行関数"""
|
||||
try:
|
||||
packager = AIMojiPackager()
|
||||
result = packager.package_all()
|
||||
|
||||
print("\n📦 パッケージング完了!")
|
||||
print(f"📁 出力ディレクトリ: {result['output_dir']}")
|
||||
|
||||
if result["is_valid"]:
|
||||
print("🚀 npmパッケージとして公開準備完了!")
|
||||
print(" npm publish コマンドで公開できます")
|
||||
else:
|
||||
print("⚠️ パッケージに問題があります")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ エラーが発生しました: {e}")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
8
scpt/ai_moji_generator/requirements.txt
Normal file
8
scpt/ai_moji_generator/requirements.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# AI Moji Font Generator Dependencies
|
||||
|
||||
# フォント生成用
|
||||
fontforge>=20230101
|
||||
fonttools>=4.38.0
|
||||
|
||||
# その他ユーティリティ
|
||||
pathlib2>=2.3.7; python_version < "3.4"
|
97
scpt/ai_moji_generator/setup.sh
Normal file
97
scpt/ai_moji_generator/setup.sh
Normal file
@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
# AI Moji Font Generator Setup Script
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 AI Moji Font Generator セットアップ開始"
|
||||
echo "======================================"
|
||||
|
||||
# Python バージョンチェック
|
||||
echo "🐍 Python バージョンチェック..."
|
||||
python3 --version || {
|
||||
echo "❌ Python 3 が見つかりません"
|
||||
echo " Python 3.6 以上をインストールしてください"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# pip が利用可能かチェック
|
||||
echo "📦 pip チェック..."
|
||||
python3 -m pip --version || {
|
||||
echo "❌ pip が見つかりません"
|
||||
echo " pip をインストールしてください"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# FontForge インストール (macOS)
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo "🍎 macOS環境を検出"
|
||||
if ! command -v fontforge &> /dev/null; then
|
||||
echo "🔧 FontForge をインストール中..."
|
||||
if command -v brew &> /dev/null; then
|
||||
brew install fontforge
|
||||
else
|
||||
echo "❌ Homebrew が見つかりません"
|
||||
echo " Homebrewをインストールしてから再実行してください:"
|
||||
echo " /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✅ FontForge インストール済み"
|
||||
fi
|
||||
fi
|
||||
|
||||
# FontForge インストール (Ubuntu/Debian)
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
echo "🐧 Linux環境を検出"
|
||||
if ! command -v fontforge &> /dev/null; then
|
||||
echo "🔧 FontForge をインストール中..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y fontforge python3-fontforge
|
||||
else
|
||||
echo "✅ FontForge インストール済み"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Python依存関係インストール
|
||||
echo "📚 Python 依存関係をインストール中..."
|
||||
python3 -m pip install -r requirements.txt
|
||||
|
||||
# ディレクトリ構造確認
|
||||
echo "📁 ディレクトリ構造確認..."
|
||||
SVG_DIR="../../svg"
|
||||
if [ ! -d "$SVG_DIR" ]; then
|
||||
echo "⚠️ SVGディレクトリが見つかりません: $SVG_DIR"
|
||||
echo " ai.mojiプロジェクトのルートディレクトリで実行していることを確認してください"
|
||||
fi
|
||||
|
||||
SVG_COUNT=$(find "$SVG_DIR" -name "*.svg" 2>/dev/null | wc -l || echo "0")
|
||||
echo " SVGファイル数: $SVG_COUNT"
|
||||
|
||||
# 実行権限設定
|
||||
echo "🔐 実行権限設定..."
|
||||
chmod +x build.py
|
||||
|
||||
# テストビルド
|
||||
echo "🧪 テストビルド実行..."
|
||||
python3 build.py --clean
|
||||
if python3 build.py --font-only; then
|
||||
echo "✅ テストビルド成功!"
|
||||
else
|
||||
echo "❌ テストビルドに失敗しました"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎉 セットアップ完了!"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
echo "📋 使用方法:"
|
||||
echo " python3 build.py # 全体ビルド"
|
||||
echo " python3 build.py --font-only # フォントのみ"
|
||||
echo " python3 build.py --css-only # CSSのみ"
|
||||
echo " python3 build.py --package-only # パッケージングのみ"
|
||||
echo " python3 build.py --clean # クリーンアップ"
|
||||
echo ""
|
||||
echo "📁 出力ディレクトリ: ../../dist"
|
||||
echo ""
|
||||
echo "🚀 準備完了! FontAwesome風aimojiパッケージを生成できます"
|
Loading…
x
Reference in New Issue
Block a user