StyledStrings
StyledStrings と AnnotatedStrings の API は実験的と見なされており、Julia のバージョン間で変更される可能性があります。
Styling
文字列を扱う際、フォーマットやスタイルはしばしば二次的な関心事として現れます。
例えば、ターミナルに印刷する際には、出力に ANSI escape sequences を散りばめたい場合があります。HTMLスタイリング構造(<span style="...">
など)を出力することも同様の目的を果たします。このように、コンテンツ自体の隣に生のスタイリング構造を単純に挿入することは可能ですが、これは最も基本的なユースケースにしか適していないことがすぐに明らかになります。すべてのターミナルが同じANSIコードをサポートしているわけではなく、スタイリング構造は、すでにスタイルが適用されたコンテンツの幅を計算する際に手間をかけて取り除く必要があります。そして、複数の出力形式を扱う前に、これが必要になります。
Instead of leaving this headache to be widely experienced downstream, it is tackled head-on by the introduction of a special string type (AnnotatedString
). This string type wraps any other AbstractString
type and allows for formatting information to be applied to regions (e.g. characters 1 through to 7 are bold and red).
文字列の領域は、Face
(「フォント」と考えてください)を適用することでスタイルが設定されます。これはスタイリング情報を保持する構造です。便利なことに、グローバルフォント辞書内のフォント(例:shadow
)は、4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
を直接指定する代わりに名前を付けることができます。
これらの機能に加えて、AnnotatedString
を構築するための便利な方法も提供しています。詳細はStyled String Literalsに記載されています。
julia> using StyledStrings
julia> styled"{yellow:hello} {blue:there}"
"hello there"
Annotated Strings
文字列の領域に関連するメタデータを保持することができると、時には便利です。AnnotatedString
は別の文字列をラップし、その一部にラベル付きの値(:label => value
)で注釈を付けることを可能にします。すべての一般的な文字列操作は、基になる文字列に適用されます。ただし、可能な場合はスタイリング情報が保持されます。これは、4d61726b646f776e2e436f64652822222c2022416e6e6f7461746564537472696e672229_4072656620426173652e416e6e6f7461746564537472696e67
を操作することができることを意味します—部分文字列を取り出したり、パディングを施したり、他の文字列と連結したりしても、メタデータの注釈は「一緒に付いてくる」のです。
この文字列タイプは、スタイリング情報を保持するために :face
ラベル付きの注釈を使用する StyledStrings stdlib にとって基本的です。
When concatenating a AnnotatedString
, take care to use annotatedstring
instead of string
if you want to keep the string annotations.
julia> str = AnnotatedString("hello there", [(1:5, :word, :greeting), (7:11, :label, 1)])
"hello there"
julia> length(str)
11
julia> lpad(str, 14)
" hello there"
julia> typeof(lpad(str, 7))
AnnotatedString{String}
julia> str2 = AnnotatedString(" julia", [(2:6, :face, :magenta)])
" julia"
julia> annotatedstring(str, str2)
"hello there julia"
julia> str * str2 == annotatedstring(str, str2) # *-concatenation works
true
AnnotatedString
のアノテーションは、annotations
および annotate!
関数を介してアクセスおよび変更できます。
Styling via AnnotatedString
s
Faces
The Face
type
Face
は、テキストを設定できるフォントの詳細を指定します。これは、さまざまなフォーマットにわたって一般化される基本的な属性のセットをカバーしています。具体的には:
フォント
高さ
体重
スラント
前景
背景
下線
打ち消し線
逆
継承
特定の属性がどのような形を取るかの詳細については、Face
ドキュメントストリングを参照してくださいが、特に興味深いのは inherit
です。これは他の 4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
から属性を 継承 することを可能にします。
The global faces dictionary
特定のスタイルを参照するために便利にするために、グローバルな Dict{Symbol, Face}
があり、これにより Face
を単に名前で参照することができます。パッケージは addface!
関数を介してこの辞書にフェイスを追加でき、ロードされたフェイスは簡単に customized できます。
新しいフェイスを登録するパッケージは、パッケージ名でプレフィックスを付ける必要があります。つまり、mypackage_myface
という形式に従う必要があります。これは予測可能性のため、また名前の衝突を防ぐために重要です。
さらに、パッケージは直接的な色やスタイル(例えば cyan
)の代わりに、セマンティック フェイス(例えば code
)を使用(および導入)するように注意すべきです。これは、使用意図をより明確にし、コンポーザビリティを助け、ユーザーのカスタマイズをより直感的にするなど、いくつかの点で役立ちます。
パッケージプレフィックスルールには2つの免除があります:
- デフォルト値のフェイス辞書に含まれる基本的なフェイスのセット
- Juliaの標準ライブラリである
JuliaSyntaxHighlighting
によって導入された顔。
Basic faces
基本的な顔は、広く適用可能な一般的なアイデアを表すことを意図しています。
特定の属性を持つテキストを設定するために、bold
、light
、italic
、underline
、strikethrough
、および inverse
フェイスがあります。
16の端末色には、次のような名前付きの色があります:black
、red
、green
、yellow
、blue
、magenta
、cyan
、white
、bright_black
/grey
/gray
、bright_red
、bright_green
、bright_blue
、bright_magenta
、bright_cyan
、およびbright_white
。
影のあるテキスト(つまり、薄暗いが存在するもの)には shadow
フェイスがあります。選択された領域を示すためには region
フェイスがあります。同様に、強調やハイライトのために emphasis
と highlight
フェイスが定義されています。また、コードのようなテキストには code
があります。
メッセージの重大性を視覚的に示すために、error
、warning
、success
、info
、note
、および tip
のフェイスが定義されています。
Customisation of faces (Faces.toml
)
グローバルフェイス辞書の名前の顔がカスタマイズ可能であることは良いことです。テーマや美学は素晴らしく、アクセシビリティの理由からも重要です。TOMLファイルは、フェイス辞書の既存のエントリとマージされるFace
仕様のリストに解析できます。
A Face
は、次のようにTOMLで表現されます:
[facename]
attribute = "value"
...
[package.facename]
attribute = "value"
例えば、shadow
フェイスが読みづらい場合は、次のように明るくすることができます:
[shadow]
foreground = "white"
初期化時に、最初のJuliaデポ(通常は~/.julia
)の下にあるconfig/faces.toml
ファイルが読み込まれます。
Applying faces to a AnnotatedString
慣例として、AnnotatedString
の:face
属性は、現在適用されているFace
に関する情報を保持します。これは、グローバルフェイス辞書内の4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
を名前付ける単一のSymbol
、4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
自体、またはそのいずれかのベクトルの形で提供できます。
show(::IO, ::MIME"text/plain", ::AnnotatedString)
および show(::IO, ::MIME"text/html", ::AnnotatedString)
メソッドはどちらも :face
属性を確認し、全体のスタイリングを決定する際にそれらをすべて統合します。
AnnotatedString
の構築時に:face
属性を供給することができ、その後プロパティリストに追加するか、便利なStyled String literalsを使用します。
julia> str1 = AnnotatedString("blue text", [(1:9, :face, :blue)])
"blue text"
julia> str2 = styled"{blue:blue text}"
"blue text"
julia> str1 == str2
true
julia> sprint(print, str1, context = :color => true)
"\e[34mblue text\e[39m"
julia> sprint(show, MIME("text/html"), str1, context = :color => true)
"<span style=\"color: #195eb3\">blue text</span>"
Styled String Literals
AnnotatedString
の構築を容易にするために、Face
が適用され、styled"..."
スタイルの文字列リテラルは、コンテンツと属性をカスタム文法を介して簡単に表現できるようにします。
styled"..."
リテラル内では、波括弧は特別な文字と見なされ、通常の使用ではエスケープする必要があります(\{
、\}
)。これにより、(ネスト可能な){annotations...:text}
構文を使用して注釈を表現することができます。
annotations...
コンポーネントは、3種類のアノテーションのカンマ区切りリストです。
- 顔の名前
- インライン
Face
表現(key=val,...)
key=value
ペア
補間はインラインフェイスキーを除いて、どこでも可能です。
詳細な文法については、styled"..."
ドキュメントの拡張ヘルプを参照してください。
上記で言及された組み込みの顔のリストを次のように示すことができます:
julia> println(styled"
The basic font-style attributes are {bold:bold}, {light:light}, {italic:italic},
{underline:underline}, and {strikethrough:strikethrough}.
In terms of color, we have named faces for the 16 standard terminal colors:
{black:■} {red:■} {green:■} {yellow:■} {blue:■} {magenta:■} {cyan:■} {white:■}
{bright_black:■} {bright_red:■} {bright_green:■} {bright_yellow:■} {bright_blue:■} {bright_magenta:■} {bright_cyan:■} {bright_white:■}
Since {code:bright_black} is effectively grey, we define two aliases for it:
{code:grey} and {code:gray} to allow for regional spelling differences.
To flip the foreground and background colors of some text, you can use the
{code:inverse} face, for example: {magenta:some {inverse:inverse} text}.
The intent-based basic faces are {shadow:shadow} (for dim but visible text),
{region:region} for selections, {emphasis:emphasis}, and {highlight:highlight}.
As above, {code:code} is used for code-like text.
Lastly, we have the 'message severity' faces: {error:error}, {warning:warning},
{success:success}, {info:info}, {note:note}, and {tip:tip}.
Remember that all these faces (and any user or package-defined ones) can
arbitrarily nest and overlap, {region,tip:like {bold,italic:so}}.")
The basic font-style attributes are bold, light, italic, underline, and strikethrough. In terms of color, we have named faces for the 16 standard terminal colors: ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ Since bright_black is effectively grey, we define two aliases for it: grey and gray to allow for regional spelling differences. To flip the foreground and background colors of some text, you can use the inverse face, for example: some inverse text. The intent-based basic faces are shadow (for dim but visible text), region for selections, emphasis, and highlight. As above, code is used for code-like text. Lastly, we have the 'message severity' faces: error, warning, success, info, note, and tip. Remember that all these faces (and any user or package-defined ones) can arbitrarily nest and overlap, like so.
API reference
Styling and Faces
StyledStrings.StyledMarkup.@styled_str
— Macro@styled_str -> AnnotatedString
スタイル付き文字列を構築します。文字列内の {<specs>:<content>}
構造は、カンマ区切りの仕様 <specs>
のリストに従って <content>
にフォーマットを適用します。各仕様は、フェイス名、インラインフェイス仕様、または key=value
ペアの形式を取ることができます。値には、{...}
でラップされている必要があります。これには ,=:{}
のいずれかの文字が含まれている場合です。
$
を使った文字列補間は、通常の文字列と同じように機能しますが、引用符はエスケープする必要があります。フェイス、キー、および値も $
で補間できます。
例
styled"The {bold:{italic:quick} {(foreground=#cd853f):brown} fox} jumped over the {link={https://en.wikipedia.org/wiki/Laziness}:lazy} dog"
拡張ヘルプ
このマクロは、次の EBNF 文法で説明できます。
styledstring = { styled | interpolated | escaped | plain } ;
specialchar = '{' | '}' | '$' | '\"' ;
anychar = [\u0-\u1fffff] ;
plain = { anychar - specialchar } ;
escaped = '\\', specialchar ;
interpolated = '$', ? expr ? | '$(', ? expr ?, ')' ;
styled = '{', ws, annotations, ':', content, '}' ;
content = { interpolated | plain | escaped | styled } ;
annotations = annotation | annotations, ws, ',', ws, annotation ;
annotation = face | inlineface | keyvalue ;
ws = { ' ' | '\t' | '\n' } ; (* whitespace *)
face = facename | interpolated ;
facename = [A-Za-z0-9_]+ ;
inlineface = '(', ws, [ faceprop ], { ws, ',', faceprop }, ws, ')' ;
faceprop = [a-z]+, ws, '=', ws, ( [^,)]+ | interpolated) ;
keyvalue = key, ws, '=', ws, value ;
key = ( [^\0${}=,:], [^\0=,:]* ) | interpolated ;
value = simplevalue | curlybraced | interpolated ;
curlybraced = '{' { escaped | plain } '}' ;
simplevalue = [^${},:], [^,:]* ;
上記の文法にエンコードされていない追加の規定は、plain
が unescape_string
に対して有効な入力であるべきであり、specialchar
は保持されるべきであるということです。
inlineface
の上記の文法は簡略化されており、実際の実装はもう少し洗練されています。完全な動作は以下に示されています。
faceprop = ( 'face', ws, '=', ws, ( ? string ? | interpolated ) ) |
( 'height', ws, '=', ws, ( ? number ? | interpolated ) ) |
( 'weight', ws, '=', ws, ( symbol | interpolated ) ) |
( 'slant', ws, '=', ws, ( symbol | interpolated ) ) |
( ( 'foreground' | 'fg' | 'background' | 'bg' ),
ws, '=', ws, ( simplecolor | interpolated ) ) |
( 'underline', ws, '=', ws, ( underline | interpolated ) ) |
( 'strikethrough', ws, '=', ws, ( bool | interpolated ) ) |
( 'inverse', ws, '=', ws, ( bool | interpolated ) ) |
( 'inherit', ws, '=', ws, ( inherit | interpolated ) ) ;
nothing = 'nothing' ;
bool = 'true' | 'false' ;
symbol = [^ ,)]+ ;
hexcolor = ('#' | '0x'), [0-9a-f]{6} ;
simplecolor = hexcolor | symbol | nothing ;
underline = nothing | bool | simplecolor | underlinestyled;
underlinestyled = '(', ws, ('' | nothing | simplecolor | interpolated), ws,
',', ws, ( symbol | interpolated ), ws ')' ;
inherit = ( '[', inheritval, { ',', inheritval }, ']' ) | inheritval;
inheritval = ws, ':'?, symbol ;
StyledStrings.StyledMarkup.styled
— Functionstyled(content::AbstractString) -> AnnotatedString
スタイル付き文字列を構築します。文字列内の {<specs>:<content>}
構造は、カンマ区切りの仕様 <specs>
のリストに従って <content>
にフォーマットを適用します。各仕様は、フェイス名、インラインフェイス仕様、または key=value
ペアの形式を取ることができます。値には、`,=:{}
のいずれかの文字が含まれている場合、{...}
でラップする必要があります。
これは、補間機能なしの @styled_str
マクロの機能的同等物です。
StyledStrings.Face
— TypeFace
は、テキストを表示するためのグラフィカル属性のコレクションです。Facesは、ターミナルや他の場所でテキストがどのように表示されるかを制御します。
ほとんどの場合、Face
は、face name シンボルとの一意の関連付けとしてグローバルなfaces辞書に保存され、この名前で参照されることが最も多いです。
属性
すべての属性はキーワードコンストラクタを介して設定でき、デフォルトはnothing
です。
height
(Int
またはFloat64
):デシポイント(Int
の場合)または基本サイズの係数(Float64
の場合)での高さ。weight
(Symbol
):最も薄いものから最も濃いものまでのシンボルの1つ:thin
,:extralight
,:light
,:semilight
,:normal
,:medium
,:semibold
,:bold
,:extrabold
, または:black
。ターミナルでは、:normal
より大きい重さは太字として表示され、可変明度テキストをサポートするターミナルでは、:normal
より小さい重さは薄く表示されます。slant
(Symbol
):シンボルの1つ:italic
,:oblique
, または:normal
。foreground
(SimpleColor
):テキストの前景色。background
(SimpleColor
):テキストの背景色。underline
、テキストの下線で、次のいずれかの形式を取ります:Bool
:テキストに下線を引くべきかどうか。SimpleColor
:この色でテキストに下線を引くべき。Tuple{Nothing, Symbol}
:シンボルによって設定されたスタイル(:straight
,:double
,:curly
,:dotted
, または:dashed
のいずれか)を使用してテキストに下線を引くべき。Tuple{SimpleColor, Symbol}
:指定されたSimpleColorでテキストに下線を引き、前述のシンボルによって指定されたスタイルを使用するべき。
strikethrough
(Bool
):テキストに打ち消し線を引くべきかどうか。inverse
(Bool
):前景色と背景色を反転させるべきかどうか。inherit
(Vector{Symbol}
):継承する顔の名前で、早い顔が優先されます。すべての顔は:default
顔から継承します。
StyledStrings.addface!
— Functionaddface!(name::Symbol => default::Face)
名前 name
の新しいフェイスを作成します。この名前のフェイスがすでに存在しない限り、default
が FACES
.default
と (そのコピーが) FACES
.current
に追加され、現在の値が返されます。
フェイス name
がすでに存在する場合、nothing
が返されます。
例
julia> addface!(:mypkg_myface => Face(slant=:italic, underline=true))
Face (sample)
slant: italic
underline: true
StyledStrings.withfaces
— Functionwithfaces(f, kv::Pair...)
withfaces(f, kvpair_itr)
f
をFACES
.current
を一時的にゼロ個以上の:name => val
引数kv
またはkvpair_itr
によって生成されるkv
形式の値で修正して実行します。
withfaces
は一般的にwithfaces(kv...) do ... end
構文を介して使用されます。nothing
の値を使用して、フェイスを一時的に解除することができます(設定されている場合)。withfaces
が戻ると、元のFACES
.current
が復元されます。
例
julia> withfaces(:yellow => Face(foreground=:red), :green => :blue) do
println(styled"{yellow:red} and {green:blue} mixed make {magenta:purple}")
end
red and blue mixed make purple
StyledStrings.SimpleColor
— Typestruct SimpleColor
色の基本的な表現で、文字列スタイリングの目的で使用されます。名前付きの色(例えば :red
)または、8ビット深度の r
、g
、b
色を指定する NamedTuple である RGBTuple
を含むことができます。
コンストラクタ
SimpleColor(name::Symbol) # 例: :red
SimpleColor(rgb::RGBTuple) # 例: (r=1, b=2, g=3)
SimpleColor(r::Integer, b::Integer, b::Integer)
SimpleColor(rgb::UInt32) # 例: 0x123456
また、tryparse(SimpleColor, rgb::String)
も参照してください。
Base.parse
— Methodparse(::Type{SimpleColor}, rgb::String)
tryparse(SimpleColor, rgb::String)
の類似で、nothing
を返す代わりにエラーを発生させます。
Base.tryparse
— Methodtryparse(::Type{SimpleColor}, rgb::String)
rgb
をSimpleColor
として解析しようとします。rgb
が#
で始まり、長さが7の場合、RGBTuple
に基づくSimpleColor
に変換されます。rgb
がa
-z
で始まる場合、rgb
は色名として解釈され、Symbol
に基づくSimpleColor
に変換されます。
それ以外の場合は、nothing
が返されます。
例
julia> tryparse(SimpleColor, "blue")
SimpleColor(blue)
julia> tryparse(SimpleColor, "#9558b2")
SimpleColor(#9558b2)
julia> tryparse(SimpleColor, "#nocolor")
Base.merge
— Methodmerge(initial::Face, others::Face...)
initial
フェイスとothers
のプロパティをマージし、後のフェイスが優先されます。