update claude
This commit is contained in:
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パッケージを生成できます"
|
Reference in New Issue
Block a user