コンテンツにスキップ

フォーマット層 format.ts

中性値の解析と各端のフォーマット。

トークン値はすべてプラットフォーム非依存の中性表現です(16 進数 / rgba / 単位付き文字列 / 数値 / ベジェ配列)。format.ts がそれらを構造化データへ解析し、各 target がローカル言語のリテラルへフォーマットします。

interface ParsedColor { r: number; g: number; b: number; a: number } // r/g/b: 0..255、a: 0..1
interface ParsedDimension { value: number; unit: 'px' | '%' }
interface ParsedDuration { ms: number } // ミリ秒に正規化
interface ParsedShadow { x: number; y: number; blur: number; spread?: number; color: ParsedColor }

3 種類の 16 進数をサポートします:

入力 処理
#RGB 各桁を繰り返して展開
#RRGGBB そのままチャンネルを取る
#AARRGGBB 先頭 2 桁が alpha で、255 で割って 0..1 に正規化
その他の長さ 无法解析的十六进制色值(解析できない 16 進数の色値)を投げる

rgba() / rgb() を解析し、alpha の省略時は 1 です。チャンネルは clamp255 で検証します(0..255 を超えると 颜色通道超出范围(色チャンネルが範囲外)を投げる)。

色の統一エントリ:# で始まれば parseHex、rgb で始まれば parseRgba、それ以外は 不支持的颜色格式(仅接受十六进制与 rgba)(対応していない色形式。16 進数と rgba のみ受け付ける)を投げます。

parseDimension(value: string): ParsedDimension

Section titled “parseDimension(value: string): ParsedDimension”

/^(\d+(?:\.\d+)?)(px|%)$/ に一致しなければ 无法解析的尺寸值(解析できない寸法値)を投げます。受け付けるのは px と % のみ——その他の単位は JSON 層でレッドライン 5 により禁止されています。

parseDuration(value: string): ParsedDuration

Section titled “parseDuration(value: string): ParsedDuration”

/^(\d+(?:\.\d+)?)(s|ms)$/ に一致し、s は 1000 を掛けて、ミリ秒に統一して正規化します。

空白で区切ります(少なくとも 4 セグメント):

x y blur [spread] color

4 番目のセグメントが -?\d+(\.\d+)?px に一致すれば拡張量(spread)、そうでなければ色です:

if (rest.length > 1 && /^-?\d+(\.\d+)?px$/.test(rest[0])) {
spread = Number(rest[0].replace('px', ''))
rest.shift()
}

色の部分は parseColor に戻して処理します。

assertTypedValue(type: TokenType, value: TokenValue): void

Section titled “assertTypedValue(type: TokenType, value: TokenValue): void”

schema の外側にある意味検証:型ごとに 1 つずつアサートし、実際に値を解析します。これが型システム 3 層優先順位の最後の関門です(詳しくは 型システム)。

型 アサーション
color 文字列であり、parseColor で解析できること
dimension 文字列であり、parseDimension で解析できること
duration 文字列であり、parseDuration で解析できること
shadow 文字列であり、parseShadow で解析できること
cubicBezier 長さ 4 の数値配列であること
number / string 検証しない

0xAARRGGBB のリテラルで、Kotlin / C 用です。alpha チャンネルは Math.round(a * 255)、各チャンネルは 2 桁の 16 進数(大文字)にします。

#AARRGGBB の文字列で、ArkTS 用です。toArgbHex を基に 0x を # に置き換えたものです。

Android 専用の判定:パスが /fontsize/i に一致すれば sp、それ以外は dp を使います。

target たちの統一エントリ。token.type に従って中性値を kind で判別するユニオンオブジェクトへ変換します:

{ kind: 'color'; color: ParsedColor }
| { kind: 'dimension'; dimension: ParsedDimension }
| { kind: 'duration'; duration: ParsedDuration }
| { kind: 'shadow'; shadow: ParsedShadow }
| { kind: 'cubicBezier'; bezier: number[] }
| { kind: 'number'; number: number }
| { kind: 'string'; string: string }

各 target がさらにこのユニオンで switch し、ローカルのリテラルへフォーマットします。こうして中性値の解析は 1 か所だけに書き、各端は「どう書くか」だけを担います。

Copyright © 2024-2026 FengMo WenXue