StyledStrings
واجهة برمجة التطبيقات لـ StyledStrings و AnnotatedStrings تعتبر تجريبية وقابلة للتغيير بين إصدارات جوليا.
Styling
عند العمل مع السلاسل النصية، غالبًا ما تظهر التنسيقات والأساليب كقضية ثانوية.
على سبيل المثال، عند الطباعة إلى وحدة التحكم، قد ترغب في رش ANSI escape sequences في المخرجات، وعند إخراج بناءات تنسيق HTML (<span style="...">
، إلخ) تخدم غرضًا مشابهًا، وهكذا. من الممكن ببساطة إدراج بناءات التنسيق الخام في السلسلة بجوار المحتوى نفسه، ولكن سرعان ما يتضح أن هذا ليس مناسبًا إلا لأبسط حالات الاستخدام. ليست جميع وحدات التحكم تدعم نفس رموز ANSI، ويجب إزالة بناءات التنسيق بعناية عند حساب عرض المحتوى المنسق بالفعل، وذلك قبل أن تبدأ حتى في التعامل مع تنسيقات الإخراج المتعددة.
بدلاً من ترك هذه المشكلة لتُعاني منها الأجزاء السفلية بشكل واسع، يتم التعامل معها بشكل مباشر من خلال إدخال نوع سلسلة خاص (AnnotatedString
). هذا النوع من السلاسل يلف أي نوع آخر AbstractString
ويسمح بتطبيق معلومات التنسيق على المناطق (على سبيل المثال، الأحرف من 1 إلى 7 تكون بالخط العريض والأحمر).
تُنسق مناطق النص عن طريق تطبيق 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
—أخذ أجزاء فرعية منها، وتوسيعها، ودمجها مع سلاسل نصية أخرى— وسترافق التعليقات التوضيحية للبيانات الوصفية "الرحلة".
هذا النوع من السلاسل أساسي لـ StyledStrings stdlib، الذي يستخدم تعليقات معنونة بـ :face
للاحتفاظ بمعلومات التنسيق.
عند دمج AnnotatedString
، تأكد من استخدام annotatedstring
بدلاً من string
إذا كنت ترغب في الاحتفاظ بتعليقات السلسلة.
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
A Face
يحدد تفاصيل نوع الخط الذي يمكن ضبط النص فيه. يغطي مجموعة من السمات الأساسية التي تتعمم بشكل جيد عبر تنسيقات مختلفة، وهي:
خط
الارتفاع
الوزن
ميل
foreground
خلفية
underline
strikethrough
عكسي
وراثة
للحصول على تفاصيل حول الأشكال المحددة التي تتخذها هذه السمات، راجع Face
docstring، ولكن ما يهم بشكل خاص هو inherit
لأنه يسمح لك بـ وراثة السمات من 4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
s.
The global faces dictionary
لجعل الإشارة إلى أنماط معينة أكثر ملاءمة، هناك Dict{Symbol, Face}
عالمي يسمح بالإشارة إلى Face
ببساطة عن طريق الاسم. يمكن للحزم إضافة الوجوه إلى هذه القاموس عبر addface!
، ويمكن تحميل الوجوه بسهولة customized.
يجب على أي حزمة تسجل وجوه جديدة التأكد من أنها مسبوقة باسم الحزمة، أي اتباع التنسيق mypackage_myface
. هذا مهم للتنبؤ، ولمنع تصادم الأسماء.
علاوة على ذلك، يجب على الحزم أن تأخذ في الاعتبار استخدام (وتقديم) الوجوه الدلالية (مثل code
) بدلاً من الألوان والأساليب المباشرة (مثل cyan
). هذا مفيد بعدة طرق، بدءًا من جعل النية في الاستخدام أكثر وضوحًا، ومساعدة التكوين، وجعل تخصيص المستخدم أكثر سهولة.
هناك مجموعتان من الاستثناءات لقواعد بادئة الحزمة:
- مجموعة الوجوه الأساسية التي هي جزء من القيمة الافتراضية لقاموس الوجوه
- الوجوه التي قدمتها مكتبة جوليا القياسية الخاصة بها، وهي
JuliaSyntaxHighlighting
Basic faces
الوجوه الأساسية تهدف إلى تمثيل فكرة عامة قابلة للتطبيق على نطاق واسع.
لإعداد بعض النصوص بصفة معينة، لدينا الوجوه bold
و light
و italic
و underline
و strikethrough
و inverse
.
هناك أيضًا أسماء محددة للألوان الطرفية الـ 16: أسود
، أحمر
، أخضر
، أصفر
، أزرق
، ماغنتا
، سيان
، أبيض
، أسود ساطع
/رمادي
/رمادي
، أحمر ساطع
، أخضر ساطع
، أزرق ساطع
، ماغنتا ساطع
، سيان ساطع
، وأبيض ساطع
.
للنص المظلل (أي الخافت ولكن موجود) هناك وجه 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"
عند التهيئة، يتم تحميل ملف config/faces.toml
الموجود تحت أول مستودع جوليا (عادةً ~/.julia
).
Applying faces to a AnnotatedString
بموجب الاتفاق، فإن سمات :face
ل AnnotatedString
تحمل معلومات عن Face
التي تنطبق حاليًا. يمكن تقديم ذلك بأشكال متعددة، كرمز واحد Symbol
يسمي 4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
في القاموس العالمي للوجوه، أو 4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365
نفسه، أو متجه من أي منهما.
تقوم الطريقتان show(::IO, ::MIME"text/plain", ::AnnotatedString)
و show(::IO, ::MIME"text/html", ::AnnotatedString)
بالنظر إلى سمات :face
ودمجها جميعًا معًا عند تحديد التنسيق العام.
يمكننا تزويد :face
السمات إلى AnnotatedString
أثناء الإنشاء، إضافتها إلى قائمة الخصائص لاحقًا، أو استخدام 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
s مع Face
s المطبقة، فإن styled"..."
سلسلة حرفية مصممة تسمح بالتعبير عن المحتوى والسمات بسهولة معًا عبر قواعد نحوية مخصصة.
داخل حرفية styled"..."
، تعتبر الأقواس المعقوفة رموزًا خاصة ويجب الهروب منها في الاستخدام العادي (\{
, \}
). وهذا يسمح باستخدامها للتعبير عن التعليقات مع تراكيب {annotations...:text}
(قابلة للتعشيش).
مكون annotations...
هو قائمة مفصولة بفواصل من ثلاثة أنواع من التعليقات التوضيحية.
- أسماء الوجوه
- تعبيرات
Face
المضمنة(key=val,...)
مفتاح=قيمة
أزواج
التداخل ممكن في كل مكان باستثناء مفاتيح الوجه المضمنة.
للمزيد من المعلومات حول القواعد، راجع المساعدة الموسعة لـ styled"..."
docstring.
كمثال، يمكننا توضيح قائمة الوجوه المدمجة المذكورة أعلاه على النحو التالي:
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>}
التنسيق على <content>
، وفقًا لقائمة المواصفات المفصولة بفواصل <specs>
. يمكن أن تأخذ كل مواصفة شكل اسم وجه، أو مواصفة وجه داخلية، أو زوج 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>}
التنسيق على <content>
، وفقًا لقائمة من المواصفات المفصولة بفواصل <specs>
. يمكن أن تأخذ كل مواصفة إما شكل اسم وجه، أو مواصفة وجه داخلية، أو زوج key=value
. يجب أن تكون القيمة محاطة بـ {...}
إذا كانت تحتوي على أي من الأحرف ,=:{}
.
هذا هو المعادل الوظيفي لماكرو @styled_str
، فقط بدون قدرات الاستبدال.
StyledStrings.Face
— TypeA Face
هو مجموعة من الخصائص الرسومية لعرض النص. تتحكم الوجوه في كيفية عرض النص في الطرفية، وربما في أماكن أخرى أيضًا.
معظم الوقت، سيتم تخزين Face
في القواميس العالمية للوجوه كارتباط فريد مع اسم الوجه Symbol، وسيتم الإشارة إليه غالبًا بهذا الاسم بدلاً من كائن Face
نفسه.
الخصائص
يمكن تعيين جميع الخصائص عبر مُنشئ الكلمات الرئيسية، وتكون افتراضيًا nothing
.
height
(نوعInt
أوFloat64
): الارتفاع إما بوحدة الديسي-نقطة (عندما يكونInt
)، أو كعامل من الحجم الأساسي (عندما يكونFloat64
).weight
(نوعSymbol
): واحدة من الرموز (من الأضعف إلى الأقوى):thin
,:extralight
,:light
,:semilight
,:normal
,:medium
,:semibold
,:bold
,:extrabold
, أو:black
. في الطرفيات، يتم عرض أي وزن أكبر من:normal
كخط عريض، وفي الطرفيات التي تدعم النص المتغير السطوع، يتم عرض أي وزن أقل من:normal
كخط خفيف.slant
(نوعSymbol
): واحدة من الرموز: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
)، أو RGBTuple
وهو NamedTuple يحدد لون r
و g
و b
بعمق بت يبلغ 8.
المنشئات
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، يتم تحويله إلى SimpleColor
مدعوم بـ RGBTuple
. إذا كان rgb
يبدأ بـ a
-z
، يتم تفسير rgb
كاسم لون ويتم تحويله إلى SimpleColor
مدعوم بـ Symbol
.
بخلاف ذلك، يتم إرجاع 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
، مع إعطاء الأولوية للوجوه اللاحقة.