StyledStrings

Note

StyledStrings 및 AnnotatedStrings에 대한 API는 실험적이며 Julia 버전 간에 변경될 수 있습니다.

Styling

문자열 작업 시, 포맷팅과 스타일링은 종종 부차적인 문제로 여겨진다.

예를 들어, 터미널에 출력할 때 ANSI escape sequences를 출력에 추가하고 싶을 수 있습니다. HTML 스타일링 구성 요소(<span style="..."> 등)를 출력할 때도 유사한 목적을 수행합니다. 원시 스타일링 구성 요소를 콘텐츠 자체 옆에 문자열로 삽입하는 것은 가능하지만, 이는 가장 기본적인 사용 사례를 제외하고는 잘 맞지 않는다는 것이 금방 드러납니다. 모든 터미널이 동일한 ANSI 코드를 지원하는 것은 아니며, 스타일이 적용된 콘텐츠의 너비를 계산할 때 스타일링 구성 요소를 신중하게 제거해야 하고, 이는 여러 출력 형식을 처리하기 전에 발생하는 문제입니다.

이 두통을 하류에서 널리 경험하게 두는 대신, 특별한 문자열 유형(AnnotatedString)의 도입으로 정면으로 해결됩니다. 이 문자열 유형은 다른 AbstractString 유형을 감싸고, 특정 영역(예: 문자 1부터 7까지는 굵고 빨간색)으로 서식 정보를 적용할 수 있게 합니다.

문자열의 영역은 Face (타입페이스라고 생각하세요)를 적용하여 스타일링됩니다. 이는 스타일링 정보를 담고 있는 구조입니다. 편의상, 전역 faces 사전의 얼굴(예: 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의 주석은 annotationsannotate! 함수를 통해 접근하고 수정할 수 있습니다.

Styling via AnnotatedStrings

Faces

The Face type

A Face는 텍스트가 설정될 수 있는 서체의 세부 정보를 지정합니다. 이는 다양한 형식에서 잘 일반화되는 기본 속성 집합을 포함합니다. 즉:

  • 글꼴
  • 높이
  • 무게
  • 기울기
  • 전경
  • 배경
  • 밑줄
  • 취소선
  • 상속

특정 속성이 어떤 형태를 취하는지에 대한 자세한 내용은 Face 문서 문자열을 참조하십시오. 특히 관심 있는 것은 inherit로, 이는 다른 4d61726b646f776e2e436f64652822222c2022466163652229_40726566205374796c6564537472696e67732e46616365에서 속성을 상속할 수 있게 해줍니다.

The global faces dictionary

특정 스타일을 더 편리하게 참조할 수 있도록, Dict{Symbol, Face}라는 전역 변수가 있어 Face를 이름으로 간단히 참조할 수 있습니다. 패키지는 addface! 함수를 통해 이 사전에 얼굴을 추가할 수 있으며, 로드된 얼굴은 쉽게 customized할 수 있습니다.

Appropriate face naming

새로운 얼굴을 등록하는 모든 패키지는 패키지 이름으로 접두사가 붙도록 해야 합니다. 즉, 형식 mypackage_myface를 따라야 합니다. 이는 예측 가능성을 위해 중요하며, 이름 충돌을 방지하기 위해서입니다.

또한, 패키지는 직접적인 색상과 스타일(예: cyan)보다 의미론적 얼굴(예: code)을 사용하고 도입하는 데 주의해야 합니다. 이는 사용 의도를 더 명확하게 하고, 조합 가능성을 높이며, 사용자 맞춤화를 더 직관적으로 만드는 등 여러 면에서 유용합니다.

패키지 접두사 규칙에 대한 두 가지 면제 세트가 있습니다:

  • 기본 얼굴 사전의 기본 값에 포함된 기본 얼굴 세트
  • 줄리아의 표준 라이브러리인 JuliaSyntaxHighlighting에 의해 도입된 얼굴들

Basic faces

기본 얼굴은 널리 적용 가능한 일반적인 아이디어를 나타내기 위해 의도되었습니다.

특정 속성을 가진 텍스트를 설정하기 위해 bold, light, italic, underline, strikethrough, 및 inverse 글꼴을 사용합니다.

16개의 터미널 색상에 대한 이름이 지정된 얼굴도 있습니다: 검정, 빨강, 초록, 노랑, 파랑, 마젠타, 청록, 흰색, 밝은 검정/회색, 밝은 빨강, 밝은 초록, 밝은 파랑, 밝은 마젠타, 밝은 청록, 밝은 흰색.

그림자 텍스트(즉, 희미하지만 존재하는 텍스트)를 위해 shadow 페이스가 있습니다. 선택된 영역을 나타내기 위해 region 페이스가 있습니다. 강조 및 하이라이팅을 위해 각각 emphasishighlight 페이스가 정의되어 있습니다. 코드와 유사한 텍스트를 위해 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) 아래의 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 == str2true
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... 구성 요소는 세 가지 유형의 주석으로 구성된 쉼표로 구분된 목록입니다.

  • 얼굴 이름
  • 인라인 Face 표현 (key=val,...)
  • key=value

보간(interpolation)은 인라인 페이스 키를 제외한 모든 곳에서 가능합니다.

자세한 문법 정보는 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_strMacro
@styled_str -> AnnotatedString

스타일이 적용된 문자열을 생성합니다. 문자열 내에서 {<specs>:<content>} 구조는 <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 = [^${},:], [^,:]* ;

위 문법에서 plainspecialchar를 유지한 채로 unescape_string에 유효한 입력이어야 한다는 추가 조건이 있습니다.

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 ;
source
StyledStrings.StyledMarkup.styledFunction
styled(content::AbstractString) -> AnnotatedString

스타일이 적용된 문자열을 생성합니다. 문자열 내에서 {<specs>:<content>} 구조는 <content>에 대해 쉼표로 구분된 사양 목록 <specs>에 따라 형식을 적용합니다. 각 사양은 얼굴 이름, 인라인 얼굴 사양 또는 key=value 쌍의 형태를 취할 수 있습니다. 값이 ,=:{} 중 하나의 문자를 포함하는 경우 {...}로 감싸야 합니다.

이는 @styled_str 매크로의 기능적 동등물로, 단지 보간 기능이 없습니다.

source
StyledStrings.FaceType

A Face는 텍스트를 표시하기 위한 그래픽 속성의 모음입니다. Faces는 텍스트가 터미널 및 아마도 다른 장소에서 어떻게 표시되는지를 제어합니다.

대부분의 경우, Face는 고유한 face name 기호와의 연관으로 전역 faces dicts에 저장되며, Face 객체 자체보다 이 이름으로 더 자주 참조됩니다.

속성

모든 속성은 키워드 생성자를 통해 설정할 수 있으며 기본값은 nothing입니다.

  • height (an Int or Float64): 높이는 deci-pt(정수일 때) 또는 기본 크기의 배수(실수일 때)로 설정됩니다.

  • weight (a Symbol): 가장 연한 것부터 가장 진한 것까지의 기호 중 하나인 :thin, :extralight, :light, :semilight, :normal, :medium, :semibold, :bold, :extrabold, 또는 :black. 터미널에서는 :normal보다 큰 모든 무게가 굵게 표시되며, 가변 밝기 텍스트를 지원하는 터미널에서는 :normal보다 작은 모든 무게가 연하게 표시됩니다.

  • slant (a Symbol): 기호 중 하나인 :italic, :oblique, 또는 :normal.

  • foreground (a SimpleColor): 텍스트 전경 색상.

  • background (a SimpleColor): 텍스트 배경 색상.

  • underline, 텍스트 밑줄로, 다음 형태 중 하나를 취합니다:

    • a Bool: 텍스트에 밑줄을 긋는지 여부.
    • a SimpleColor: 이 색상으로 텍스트에 밑줄을 긋습니다.
    • a Tuple{Nothing, Symbol}: 기호에 의해 설정된 스타일로 텍스트에 밑줄을 긋습니다. 스타일은 :straight, :double, :curly, :dotted, 또는 :dashed 중 하나입니다.
    • a Tuple{SimpleColor, Symbol}: 지정된 SimpleColor로 텍스트에 밑줄을 긋고, 이전과 같이 기호에 의해 지정된 스타일을 사용합니다.
  • strikethrough (a Bool): 텍스트에 취소선을 긋는지 여부.

  • inverse (a Bool): 전경색과 배경색을 반전시킬지 여부.

  • inherit (a Vector{Symbol}): 상속할 face의 이름으로, 이전 face가 우선합니다. 모든 face는 :default face에서 상속됩니다.

source
StyledStrings.addface!Function
addface!(name::Symbol => default::Face)

이름 name으로 새로운 얼굴을 생성합니다. 이 이름으로 이미 얼굴이 존재하지 않는 한, defaultFACES.default와 (복사본) FACES.current에 추가되며, 현재 값이 반환됩니다.

얼굴 name이 이미 존재하는 경우, nothing이 반환됩니다.

예시

julia> addface!(:mypkg_myface => Face(slant=:italic, underline=true))
Face (sample)
         slant: italic
     underline: true
source
StyledStrings.withfacesFunction
withfaces(f, kv::Pair...)
withfaces(f, kvpair_itr)

fFACES.current가 0개 이상의 :name => val 인수 kv 또는 kv 형식의 값을 생성하는 kvpair_itr에 의해 일시적으로 수정된 상태에서 실행합니다.

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
source
StyledStrings.SimpleColorType
struct 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)를 참조하십시오.

source
Base.parseMethod
parse(::Type{SimpleColor}, rgb::String)

tryparse(SimpleColor, rgb::String)의 유사체로, nothing을 반환하는 대신 오류를 발생시킵니다.

source
Base.tryparseMethod
tryparse(::Type{SimpleColor}, rgb::String)

rgbSimpleColor로 파싱하려고 시도합니다. rgb#로 시작하고 길이가 7인 경우, RGBTuple 기반의 SimpleColor로 변환됩니다. rgba-z로 시작하는 경우, rgb는 색상 이름으로 해석되어 Symbol 기반의 SimpleColor로 변환됩니다.

그렇지 않으면 nothing이 반환됩니다.

예제

julia> tryparse(SimpleColor, "blue")
SimpleColor(blue)

julia> tryparse(SimpleColor, "#9558b2")
SimpleColor(#9558b2)

julia> tryparse(SimpleColor, "#nocolor")
source
Base.mergeMethod
merge(initial::Face, others::Face...)

initial 얼굴과 others의 속성을 병합하며, 나중의 얼굴이 우선권을 가집니다.

source