CSSプリプロセッサの要件は、こちらの記事のいずれかを読んだ後に作成しました。 これは、 スタイラスfor Node.jsプリプロセッサに関する記事でした。 実際、これらの「プリプロセッサ」について知りました。 このプリプロセッサのシンタックスの単純さに驚かされました。 Googleからの結果を2日間(またはそれ以下)表示した後、自分にとって興味深いものは見つかりませんでした。 まさにその瞬間に、頭がおかしい思いが思い浮かびました。なぜですか?
次の要件がありました。
- 最も単純な構文(もちろん!)
- 開発言語はPHPです(これで、あなたはすでにそう言うことができます)
- ソーススタイルシートをブロックツリーとして表示する機能
実際、おそらくそれだけです。
私は何をしましたか?
開始点から経過したすべての時間、私は自分の製品の開発に費やし、次のものを手に入れました-オープンソースのMySheetライブラリは、パーサーとCSSスタイルのプリプロセッサの両方です。
もちろん、製品のプレゼンテーション用に小さなWebサイトを作成する必要がありました(この目的のためにどのプログラミング言語を選択したかを既に推測しましたか?)。 開発プロセスの興味深い瞬間-ライブラリの作成方法、遭遇した落とし穴、および作成プロセスで学んだことについて-少し後で説明します。 そして今、私のCSSプリプロセッサの機能について。
- 算術式
この機能は、ほぼすべてのCSSプリプロセッサーで使用できます。 彼女はMySheetライブラリをバイパスしませんでした。
$wrapper_height = 50% .wrapper height $wrapper_height + 20px top ($wrapper_height / 2)
それは何のためですか? はい、神は彼を知っています。 冗談。 今、私のライブラリのこの関数は非常に生の形式です。 型boolはありません。したがって、これまでのところ(これまでに!)条件はありません。 しかし、素敵な小さなパンが1つあり、そのアプリケーションは私のサイトのメインページで見つけることができます。
.object color #a50c5b - 50sat /* decrease saturation by 50% */ background-color #a50c5b + 50lt /* make color lighter by 50 percent */
はい! これはまさにあなたが今考えていることです! 色の算術演算を実行できます! ライブラリの公式ウェブサイトでこのチップをお試しください。リストの次の項目に進みます。
- ミックスイン
さて、ここでは、ロシア語でこの言葉を書くことができませんでした。 痛々しいほど多くの人が英語で書いています:
@mixin filter-grayscale(percent) -webkit-filter: grayscale($percent); -ms-filter: grayscale($percent); -o-filter: grayscale($percent); filter: grayscale($percent); img filter-grayscale 100% img:hover filter-grayscale 0%
実際、これはすべてのプリプロセッサのアプリオリの標準機能です。 これを使用するのは非常に簡単です。CSSルールの名前の代わりにミックスインの名前を記述し、このルールの値に引数を渡す必要があります。
変数$ argumentsはmixin宣言でも使用できます。これは、1行で渡されるすべての引数を単純にリストします。
@mixin border-radius(topleft, topright) -webkit-border-radius $topleft $topright 4px 5px border-radius $arguments
プリプロセッサにすでにいくつかのミックスインを組み込んでみました。 これは、まず、パフォーマンスに有益な効果をもたらします。 第二に、開発者とデザイナーは、このプロセスを簡素化する方法ではなく、サイトのスタイルを書くことに集中することができます。 さらに、2番目はしばしば怠lazです。
- 機能
これまでのところ、ライブラリには3つの関数しかありません。 これらはabs、否定、単位なしです。 しかし、それらを記述するための基礎は準備されており、将来、利用可能な関数のリストは拡大します。
関数を呼び出すための構文は、通常のCSS関数の構文とまったく同じです。唯一の違いは、コンパイル済みCSSで登録済みのライブラリ関数を呼び出すと、表示されず、戻り値が表示されることです。
- 旗
私は比較的最近この機会を思いつきました。 その意味は不名誉に簡単であり、その使用例をすぐに示す方が良いと思います:
html height 0 width 50px !prefixWith(ms, moz) !important border-radius 5px !important filter-grayscale 50% transform scale(2)
この場合のフラグは、ルールにプレフィックスを便利に追加するために使用され、次のCSSコードにコンパイルされます。
html { height: 0; -ms-width: 50px !important; -moz-width: 50px !important; width: 50px !important; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; -webkit-filter: grayscale(50%); filter: grayscale(50%); -ms-transform: scale(2); -moz-transform: scale(2); -o-transform: scale(2); -webkit-transform: scale(2); transform: scale(2) }
フラグは、特定のルールに対していくつかのアクションを実行します。 ルールに特定のプロパティをマークして付与するためにもフラグを使用するというアイデアがあります。 たとえば、!NoMixinフラグを実行すると、mixinのコンパイルとCSSコードへの挿入が禁止されます。 これにより、余分な文字やキーワードを使用した構文拡張を回避できます。
- プラグイン
ライブラリを拡張可能にしようとしました。 つまり だから、だれでも(そしてあなたと私、そして一般的にはすべての主婦)は、githubでフォークを作成してソースコード全体をひっくり返すのではなく、プラグインを書くことでライブラリの機能を拡張できます(2番目の操作は禁止しません)。 MySheetライブラリ用の2つのプラグインが作成されました。
-PluginMixin-MSSコードでミックスインを使用する機能を追加します(MySheet Styles)
-PluginSelectorExtensions-次のようなおいしいものを追加します:&記号と擬似セレクターを介した親セレクター(またはセレクターのグループ)へのアクセス:any()。これはCSSCrushプリプロセッサーから削除されました。
- ブロックツリー
これは、実際、リストの3番目の要件であり、記事の冒頭で書いたものです。 ソースを手動で変更するだけでなく、バックエンドからも直接制御できるCSSスタイルが必要でした。 CSSパーサーに固有のコード操作を実行します( tykおよびtyk )。 それは何を与えますか? たとえば、ユーザー設定に基づいてサイトのスタイルを変更できます。 また、好みは大きく異なる場合があります。 フォントをもっと必要とする人もいれば、メインページのタイトルを少し低くしたい人もいます。 この機会はさまざまなサイトジェネレータに追加でき、ソフトウェア製品のユーザーの視聴者に好影響を与えます。
言葉から行為に移り、MySheetライブラリを使用してファイルを解析した後、出力でどの特定のブロックツリーが形成されるかを示したいと思います。 この単純なMSSソースファイルを考えてみましょう。
html { color red; text-align: center; margin: 0 auto; } @mixin rounded-corners (top, right, bottom, left) -webkit-border-radius \$left + \$right \$top + \$bottom -moz-border-radius \$arguments border-radius \$arguments \$left \$right \$left \$right @mixin diagonal-border-radius(left, right) border-radius \$arguments \$right \$left @page padding 5px body rounded-corners 1 2 3 4 .wrapper diagonal-border-radius 6px 10px h1 span color blue
このコードをパーサーに渡します。
<?php try { $result = $mysheet->parseCode($code); $compiledCode = $result->toRealCss(); } catch (\MSSLib\Error\MySheetException $ex) { echo($ex->getTraceAsString()); }
出力では、ほぼ次のツリーが得られます。
MSSブロックツリーオブジェクト(MSSLib \ Structure \ Document)[64] 保護された '_docFilePath' => null 保護された「子供」=> 配列(サイズ= 5) 0 => オブジェクト(MSSLib \ Structure \ Ruleset)[98] プライベート '_selectors' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Selector)[99] private '_mssPath' => string 'html'(長さ= 4) プライベート '_cssPathGroup' => オブジェクト(MSSLib \ Structure \ CssSelectorGroup)[180] プライベート「パス」=> 配列(サイズ= 1) 0 =>文字列 'html'(長さ= 4) プライベート '_ruleset' => &オブジェクト(MSSLib \ Structure \ Ruleset)[98] プライベート '_isFullSelector' => null private '_isParsed' => boolean true プライベート '_handlerMap' => null 保護された '_parentRuleset' => null 保護された「子供」=> 配列(サイズ= 3) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[100] private 'ruleName' => string 'color'(長さ= 5) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[101] プライベート 'params' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ ColorClass)[104] 保護された 'type' => string 'html'(長さ= 4) 保護された「色」=> 配列(サイズ= 1) 0 =>文字列 'red'(長さ= 3) 保護された '_colorLib' => null プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[100] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 1 => オブジェクト(MSSLib \ Structure \ Declaration)[102] private 'ruleName' => string 'text-align'(長さ= 10) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[103] プライベート 'params' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ NonQuotedStringClass)[107] 保護された 'text' => string 'center'(長さ= 6) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[102] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 2 => オブジェクト(MSSLib \ Structure \ Declaration)[105] private 'ruleName' => string 'margin'(長さ= 6) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[106] プライベート 'params' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[110] protected 'metric' => float 0 保護された「ユニット」=> null 1 => オブジェクト(MSSLib \ EmbeddedClasses \ NonQuotedStringClass)[111] 保護された 'text' => string 'auto'(長さ= 4) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[105] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Document)[64] private '_handlerMap'(MSSLib \ Structure \ Block)=> null 1 => オブジェクト(MSSLib \ Plugins \ Mixin \ Mixin)[97] 保護された 'name' => string 'rounded-corners'(長さ= 15) 保護された「ローカル」=> 配列(サイズ= 4) 0 =>文字列 'top'(長さ= 3) 1 =>文字列 'right'(長さ= 5) 2 =>文字列 'bottom'(長さ= 6) 3 =>文字列 'left'(長さ= 4) 保護された「子供」=> 配列(サイズ= 3) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[109] private 'ruleName' => string '-webkit-border-radius'(長さ= 21) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[113] プライベート 'params' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ MathExprClass)[122] 保護された 'expressionTree' => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[116] private 'value'(ツリー\ノード\ノード)=> null private 'parent'(ツリー\ノード\ノード)=> null private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 3) 0 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ParamNode)[117] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[119] private 'varName' => string 'left'(長さ= 4) private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[116] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 1 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ OperatorNode)[118] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ Operators \ PlusOperator)[120] private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[116] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 2 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ParamNode)[121] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[123] private 'varName' => string 'right'(長さ= 5) private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[116] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 1 => オブジェクト(MSSLib \ EmbeddedClasses \ MathExprClass)[130] 保護された 'expressionTree' => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[124] private 'value'(ツリー\ノード\ノード)=> null private 'parent'(ツリー\ノード\ノード)=> null private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 3) 0 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ParamNode)[125] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[127] private 'varName' => string 'top'(長さ= 3) private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[124] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 1 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ OperatorNode)[126] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ Operators \ PlusOperator)[128] private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[124] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 2 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ParamNode)[129] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[131] private 'varName' => string 'bottom'(長さ= 6) private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[124] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[109] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 1 => オブジェクト(MSSLib \ Structure \ Declaration)[114] private 'ruleName' => string '-moz-border-radius'(長さ= 18) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[115] プライベート 'params' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[134] private 'varName' => string 'arguments'(長さ= 9) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[114] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 2 => オブジェクト(MSSLib \ Structure \ Declaration)[132] private 'ruleName' => string 'border-radius'(長さ= 13) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[133] プライベート 'params' => 配列(サイズ= 5) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[137] private 'varName' => string 'arguments'(長さ= 9) 1 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[138] private 'varName' => string 'left'(長さ= 4) 2 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[139] private 'varName' => string 'right'(長さ= 5) 3 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[140] private 'varName' => string 'left'(長さ= 4) 4 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[141] private 'varName' => string 'right'(長さ= 5) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[132] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Document)[64] private '_handlerMap'(MSSLib \ Structure \ Block)=> null 保護された「プラグイン」=> オブジェクト(MSSLib \ Plugins \ Mixin \ PluginMixin)[58] プライベート '_registeredMixins' => 配列(サイズ= 0) 空っぽ プライベート '_systemMixins' => 配列(サイズ= 3) 'border-radius' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Plugins \ Mixin \ EmbeddedMixins \ BasicSet)[61] 1 => string 'border_radius'(長さ= 13) '変換' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Plugins \ Mixin \ EmbeddedMixins \ BasicSet)[61] 1 => string 'transform'(長さ= 9) 'filter-grayscale' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Plugins \ Mixin \ EmbeddedMixins \ BasicSet)[61] 1 => string 'filter_grayscale'(長さ= 16) 保護された '_enabledMixinSetClasses' => 配列(サイズ= 1) 0 =>文字列 'basic'(長さ= 5) 2 => オブジェクト(MSSLib \ Plugins \ Mixin \ Mixin)[112] protected 'name' => string 'diagonal-border-radius'(長さ= 22) 保護された「ローカル」=> 配列(サイズ= 2) 0 => string 'left'(長さ= 4) 1 =>文字列 'right'(長さ= 5) 保護された「子供」=> 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[136] private 'ruleName' => string 'border-radius'(長さ= 13) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[142] プライベート 'params' => 配列(サイズ= 3) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[145] private 'varName' => string 'arguments'(長さ= 9) 1 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[146] private 'varName' => string 'right'(長さ= 5) 2 => オブジェクト(MSSLib \ EmbeddedClasses \ VariableClass)[147] private 'varName' => string 'left'(長さ= 4) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[136] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Document)[64] private '_handlerMap'(MSSLib \ Structure \ Block)=> null 保護された「プラグイン」=> オブジェクト(MSSLib \ Plugins \ Mixin \ PluginMixin)[58] プライベート '_registeredMixins' => 配列(サイズ= 0) 空っぽ プライベート '_systemMixins' => 配列(サイズ= 3) 'border-radius' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Plugins \ Mixin \ EmbeddedMixins \ BasicSet)[61] 1 => string 'border_radius'(長さ= 13) '変換' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Plugins \ Mixin \ EmbeddedMixins \ BasicSet)[61] 1 => string 'transform'(長さ= 9) 'filter-grayscale' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Plugins \ Mixin \ EmbeddedMixins \ BasicSet)[61] 1 => string 'filter_grayscale'(長さ= 16) 保護された '_enabledMixinSetClasses' => 配列(サイズ= 1) 0 =>文字列 'basic'(長さ= 5) 3 => オブジェクト(MSSLib \ Structure \ AtRule)[135] 保護された '_name' =>文字列 'page'(長さ= 4) 保護された '_parameters' =>文字列 ''(長さ= 0) 保護された「子供」=> 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[143] private 'ruleName' => string 'padding'(長さ= 7) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[148] プライベート 'params' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[151] protected 'metric' => float 5 保護された 'unit' => string 'px'(長さ= 2) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[143] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ AtRule)[135] プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Document)[64] private '_handlerMap'(MSSLib \ Structure \ Block)=> null 4 => オブジェクト(MSSLib \ Structure \ Ruleset)[144] プライベート '_selectors' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Selector)[150] private '_mssPath' => string 'body'(長さ= 4) プライベート '_cssPathGroup' => オブジェクト(MSSLib \ Structure \ CssSelectorGroup)[96] プライベート「パス」=> 配列(サイズ= 1) 0 =>文字列 'body'(長さ= 4) プライベート '_ruleset' => &オブジェクト(MSSLib \ Structure \ Ruleset)[144] プライベート '_isFullSelector' => null private '_isParsed' => boolean true プライベート '_handlerMap' => null 保護された '_parentRuleset' => null 保護された「子供」=> 配列(サイズ= 3) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[152] private 'ruleName' => string 'rounded-corners'(長さ= 15) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[153] プライベート 'params' => 配列(サイズ= 4) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[156] 保護された 'metric' => float 1 保護された「ユニット」=> null 1 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[157] 保護された「メトリック」=> float 2 保護された「ユニット」=> null 2 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[158] protected 'metric' => float 3 保護された「ユニット」=> null 3 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[159] protected 'metric' => float 4 保護された「ユニット」=> null プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[152] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 1 => オブジェクト(MSSLib \ Structure \ Declaration)[154] private 'ruleName' => string 'transform'(長さ= 9) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[155] プライベート 'params' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ FunctionClass)[167] 保護された 'name' => string 'rotate'(長さ= 6) 保護された「引数」=> 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ MathExprClass)[174] 保護された 'expressionTree' => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[170] private 'value'(ツリー\ノード\ノード)=> null private 'parent'(ツリー\ノード\ノード)=> null private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ OperatorNode)[171] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ Operators \ UnaryMinusOperator)[172] private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[170] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 1 => オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ParamNode)[173] private 'value'(ツリー\ノード\ノード)=> オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[175] protected 'metric' => float 5 保護された 'unit' =>文字列 'deg'(長さ= 3) private 'parent'(ツリー\ノード\ノード)=> &オブジェクト(MSSLib \ Essentials \ ExpressionTree \ ExpressionNode)[170] private 'children'(ツリー\ノード\ノード)=> 配列(サイズ= 0) 空っぽ 保護された '_functionRenderer' => オブジェクト(MSSLib \ Essentials \ FunctionRenderers \ DefaultFunctionRenderer)[166] プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[154] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 2 => オブジェクト(MSSLib \ Structure \ Ruleset)[149] プライベート '_selectors' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Selector)[161] private '_mssPath' => string '.wrapper'(長さ= 8) プライベート '_cssPathGroup' => オブジェクト(MSSLib \ Structure \ CssSelectorGroup)[176] プライベート「パス」=> 配列(サイズ= 1) 0 => string 'body .wrapper'(長さ= 13) プライベート '_ruleset' => &オブジェクト(MSSLib \ Structure \ Ruleset)[149] プライベート '_isFullSelector' => null private '_isParsed' => boolean true プライベート '_handlerMap' => null 保護された '_parentRuleset' => &オブジェクト(MSSLib \ Structure \ Ruleset)[144] 保護された「子供」=> 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[168] private 'ruleName' => string 'diagonal-border-radius'(長さ= 22) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[169] プライベート 'params' => 配列(サイズ= 2) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[178] protected 'metric' => float 6 保護された 'unit' => string 'px'(長さ= 2) 1 => オブジェクト(MSSLib \ EmbeddedClasses \ MetricClass)[179] 保護された 'metric' => float 10 保護された 'unit' => string 'px'(長さ= 2) プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[168] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null 1 => オブジェクト(MSSLib \ Structure \ Ruleset)[164] プライベート '_selectors' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Selector)[177] private '_mssPath' => string 'h1 span'(長さ= 7) プライベート '_cssPathGroup' => オブジェクト(MSSLib \ Structure \ CssSelectorGroup)[183] プライベート「パス」=> 配列(サイズ= 1) 0 => string 'body .wrapper h1 span'(長さ= 21) プライベート '_ruleset' => &オブジェクト(MSSLib \ Structure \ Ruleset)[164] プライベート '_isFullSelector' => null private '_isParsed' => boolean true プライベート '_handlerMap' => null 保護された '_parentRuleset' => &オブジェクト(MSSLib \ Structure \ Ruleset)[149] 保護された「子供」=> 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ Structure \ Declaration)[181] private 'ruleName' => string 'color'(長さ= 5) プライベート 'ruleValue' => オブジェクト(MSSLib \ Structure \ RuleValue)[182] プライベート 'params' => 配列(サイズ= 1) 0 => オブジェクト(MSSLib \ EmbeddedClasses \ ColorClass)[185] 保護された 'type' => string 'html'(長さ= 4) 保護された「色」=> 配列(サイズ= 1) 0 =>文字列 'blue'(長さ= 4) 保護された '_colorLib' => null プライベート '_parentDeclaration' => &オブジェクト(MSSLib \ Structure \ Declaration)[181] プライベート '_flags' => 配列(サイズ= 0) 空っぽ private 'ruleEnabled' => boolean true private 'parent'(MSSLib \ Structure \ Block)=> null プライベート '_handlerMap' => null private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Ruleset)[149] private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Ruleset)[144] private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> &オブジェクト(MSSLib \ Structure \ Document)[64] private '_handlerMap'(MSSLib \ Structure \ Block)=> null private 'parent'(MSSLib \ Structure \ Block)=> null private '_handlerMap'(MSSLib \ Structure \ Block)=> null
最終的に次のCSSにコンパイルされます。
html { color: #ff0000; text-align: center; margin: 0 auto } @page { padding: 5px } body { -webkit-border-radius: 6 4; -moz-border-radius: 1 2 3 4; border-radius: 1 2 3 4 4 2 4 2; -ms-transform: rotate(-5deg); -moz-transform: rotate(-5deg); -o-transform: rotate(-5deg); -webkit-transform: rotate(-5deg); transform: rotate(-5deg) } body .wrapper { border-radius: 6px 10px 10px 6px } body .wrapper h1 span { color: #0000ff }
- CSS出力形式
出力CSSコード形式は、ライブラリ設定を使用して制御できます。 これを行うには、優先プレフィックスとサフィックスを文字列に設定します。
$mysheet = MySheet::Instance(); $mysheet->setActiveDirectory(realpath('./')); $mysheet->getAutoload()->registerAutoload(); $settings = new MSSettings(); $settings->set('cssRenderer', [ 'prefixRule' => ' ', 'suffixRule' => ' /* this is a real CSS rule */', 'sepSelectors' => ', ', 'sepRules' => '; ', 'prefixOCB' => ' ', 'suffixOCB' => "\n", 'prefixCCB' => "\n", 'suffixCCB' => '' ]); … $mysheet->init($settings);
すべての可能なプレフィックスとサフィックスの表は次のとおりです。
役職 デフォルト値 説明 prefixRule 4つのスペース 各ルールの前に挿入される文字列 suffixRule 空行 各ルールの後に挿入された行 sepSelectors 、 セレクター間のセパレーター sepRules ; \ n ルール間の区切り prefixOCB スペースバー 中括弧を開く前に文字列を挿入(OCB-中括弧を開く) サフィックスOCB \ n 中括弧を開いた後に挿入された文字列 prefixCB \ n 中括弧を閉じる前に挿入される文字列(CCB-中括弧を閉じる) サフィックスCCB \ n 中括弧を閉じた後に挿入された文字列 prefixAtRuleLine 4つのスペース @ルール内の各行の前に挿入された行 suffixAtRuleLine 空行 @ルール内の各行の後に挿入された行
- その他の機能
ライブラリには、単純にリストする他の機能があります。 これらには以下が含まれます。
-ルールのコンパイルの有効化と無効化(ルールの前に追加された〜文字を使用)
-データを使用して、CSSコードに小さな画像を自動的に埋め込みます:URL
-@ importディレクティブを使用して他のMSSおよびCSSファイルをインポートします(この機能については現在も作業中です。特に、インポートオプションを設定する機能を追加する必要があります)
-すべての色を1つの形式に変換する
-コンパイルエラーのテキストでサポートされている2つの言語:英語(en_us)およびロシア語(ru_ru)
-ライブラリパーサー拡張機能の有効化と無効化(関数、変数、色などのサポートを無効にできます)
どうだった...
これまでに達成したことの説明で、私は終わったようです。 そして今、私は開発プロセスをどのように導いたかを伝えたいと思います。仕事、学校、そして最愛の少女の間で、図書館を書きました。

図 1-私の好きな女の子
私がミニプロジェクションを始めた瞬間から、多くの時間が経ちました。 多くの異なる疑わしい状況と質問がありました。 そして、それは驚くことではありません-その前に私はこのようなことをしたことがありませんでした。 コンパイラに関する特別な文献は読みませんでしたが、最初はすべてを独自の裁量で行いました。 私は自慢しませんが、反対に私は無駄ではないと言いました。 おそらく、私は生じた問題のいくつかを避けていただろう。
何らかの理由で、私はすぐにライブラリをオープンソースプロジェクトとして作成することにし、すぐに1つのgithubページでは不十分だと自分に言い聞かせました。ライブラリの一部がすでに作成された後、ウェブサイトの作成を開始しました。それにより、欠陥を見つけてオンラインで修正できるようになりました。また、実際にはエンドユーザーに会えるのがいいとすぐに実感しました。
私は自分のライブラリーの名前を思いつきました。私はこれまでで最も有名なSASSおよびLESSプリプロセッサの例から逸脱しないことに決めました、そして、結局MSSは文字の良い組み合わせだと思いました。そして、その名前を思い出深いものにするために、プロジェクトにMySheetという名前を付けることにしました。そして、略語は(MySheet Styles)に適合し、名前にわずかなハイライトがあります。
名前が発明された、それは船の設計を開始する時間です。私が始めた最初のことは、ソースコードパーサーでした。これは私が初めて誤算した場所です。私は、ソースコードをトークンとキーワードに分解せずにそれを始めました。そして、ライブラリが主に文字列を扱うという事実に導かれました。もちろん、このアプローチの欠点は既に選択の段階で見られましたが、残念ながら、これ以上良いものは思いつきませんでした。その後、大学でコンパイラーのコースを教えたが、予備的な字句解析の段階を導入した方が良いことに気づいた。少なくとも、今はコンパイルされたCSSコードへの後続の出力に対するコメントを認識して記憶する問題に直面しているためです。または、例えば、ここで、予期しない改行とインデント(コードを読みやすくするために追加されることが多い)の存在に対するパーサー拡張機能(追加モジュールとしてライブラリに接続されている)の無反応性を実現したいと思います。近い将来、トークンに侵入する段階をパーサーに含めたいと思います。これは、私の意見では、これらの問題を解決するはずです。
色演算のアイデアは、数式のサポートを実装したときに思い浮かびました。カラーピッカーを開かずに、一致する色を選択できるように、サイトデザインの色を明るくしたり暗くしたりできるといいと思いました。ライブラリは、HSLA、RGBA、HEX、およびHTMLカラー形式で動作するようになりました。これらの形式で指定された各色に、他の色形式のチャンネルのデルタを追加できます。たとえば、#000として記録された色に、255ポイントの青チャネルと40ポイントの緑を追加して、色#0028ffを取得できます。この場合、算術式は#000 + 255b + 40gのようになります。
花を使った作業を実現するために、私は自転車を作り直さず、既存のMrColorライブラリを使用することにしました(ただし、このライブラリは「仕上げ」なしでは実行できませんでした)。
ところで、現時点では、ライブラリの最適化について考えました。コードプロファイラーとして、Webgrindを使用しました。最高のプロファイラーではありませんが、彼は仕事をしていて、私のコードの弱点を見つけるのを大いに助けてくれました。
ひとつおもしろいことがあります。プリプロセッサのパーサーがルールの解析を開始すると、登録されたすべてのモジュールを通過し、大まかに言って、各モジュールで解析メソッドを呼び出します。また、算術式と、たとえば、関数は2つの異なるエンティティであるため、ライブラリは同じものを2回解析する必要がありました。私はそれが本当に好きではなく、ある日私は解決策を思いつきました。算術式のパーサーは、それがまだ式ではなく単純な関数であることを発見すると、falseを返さず、関数のまさにそのオブジェクトを返します。したがって、この欠陥を取り除き、ソースコードを解析するプロセスの生産性を向上させました。
また、私自身の最初のロゴをどのように作成したかについても説明したいと思います。ロゴのアイデアを探して、私は絵の具で描かれた絵に出会い、「千の悪魔!しかし、これは素晴らしいアイデアです!」Photoshopでいくつかの描画のレッスンを見た結果、最終的にそのようなしみができました。

図 2-マイブロット
私の将来の計画
まず、ソースコードの予備的な内訳をトークンに追加します。
次に、スタイルを編集し、バックエンドからMSSコード内のブロックを検索するための機能の開発に取り組みます。たとえば、ソースファイルに直接IEの条件付きコメントのサポートを追加できます(あなたについては知りませんが、IEのパッチを保存し、特に半分のCSSルールの場合はページに個別のファイルとして含める必要があることはいつも悩みました)。
私のプロジェクトを改善するためのアイデアが他にあれば、いつでも喜んで聞いています。
結論の代わりに
おそらく、私のライブラリについての最初の記事で伝えたいことはこれだけでしょう。私は自分の製品を少し宣伝できたと思う。私はまた、いわば、開発のポイントを修正し、すでに行われた作業についてフィードバックを得たいと思っていました。
あらゆるアドバイスや提案に加えて、あらゆる種類のサポートと親切な言葉に感謝します。
あなたが私の記事が好きなら、私は間違いなくもっと書きます。
参照資料
GitHub:https : //github.com/Dobby007/mysheet
公式ウェブサイト:http : //mss.flydigo.com/
ドキュメント:http : //mss.flydigo.com/docs
PS申し訳ありませんが、誰かが気づいたようにコメント-私のホスティングはプレッシャーに耐えられませんでした。これについて考えることさえできませんでした。さて、それについて何かを試してみましょう...
PPS残念ながら、私のホスティングは、サイトに厳しい制限があります(無料のものだけではありません)。そして、彼らは中国のイースターで一度だけリクエストに応答するので、私のサイトのコンテンツに対して他の可能な解決策の方向を見なければなりません。
DNSチェーン全体を更新すると、サイトへのPPPSアクセスが完全に復元されます。これでサイトが利用可能になりました:dobby007_h5a5nu.radius-host.net