매크로 (Macros)
매크로는 명명된 변수를 치환하여 파일 경로를 생성하는 템플릿 문자열입니다. 매크로는 시츄에이션(situation) 템플릿 및 디렉터리 정의에서 사용됩니다.
참고
이 문서는 프로젝트 시스템에서 사용되는 파일 경로 매크로에 관한 것입니다. 텍스트 파라미터의 {name} 치환을 포함하여 워크플로 내부에서 생성하고 읽는 명명된 값에 대한 내용은 워크플로 변수를 참조하세요.
전체 구문을 살펴보기 전에, 매크로가 실제로 어떻게 사용되는지 보여주는 두 가지 예시를 확인해 보세요:
템플릿: {outputs}/{node_name?:_}{file_name_base}{_index?:03}.{file_extension}
모든 변수가 제공된 경우:
outputs="outputs", node_name="ImageGen", file_name_base="render", _index=2, file_extension="png"
→ outputs/ImageGen_render002.png
선택적 변수가 생략된 경우:
outputs="outputs", file_name_base="render", file_extension="png"
→ outputs/render.png
{outputs}는 프로젝트 시스템이 자동으로 제공하는 디렉터리 이름입니다. {node_name?:_}는 선택적(optional) 항목으로, 값이 있으면 뒤에 _가 붙고, 값이 없으면 해당 블록이 완전히 생략됩니다. {_index?:03} 역시 선택적 항목이며, 값이 존재할 경우 3자리 숫자로 0(zero) 패딩됩니다.
변수 구문 참조
필수 변수
{variable_name}
변수 값이 반드시 제공되어야 합니다. 매크로를 해석(resolve)할 때 이 값이 누락되면 오류가 발생하여 실패합니다.
선택적 변수
{variable_name?}
?는 해당 변수가 선택 사항임을 표시합니다. 변수가 제공되지 않으면 {} 블록 및 모든 형식 지정자(format spec)가 출력에서 완전히 생략됩니다. 매크로의 나머지 부분은 정상적으로 계속 처리됩니다.
후행 형태. ?는 마지막 형식 지정자의 끝에도 올 수 있습니다. 즉, {shot:upper?}는 {shot?:upper}와 동일합니다. 두 표기법 모두 변수를 선택적으로 표시합니다. 이는 일반 변수와 시퀀스 축약형 모두에 동일하게 적용됩니다({###:upper?}는 {###?:upper}와 동일). 구분자에 ? 문자를 리터럴로 유지하려면 따옴표로 감싸세요({shot:'lower?'}).
구분자 포맷
{variable_name:separator}
변수 값 뒤에 separator(구분자)를 추가합니다. 인식된 키워드(아래의 문자열 변환 참조) 및 숫자 패딩이 아닌 모든 텍스트는 구분자로 처리됩니다.
이는 변수가 없을 때 깔끔하게 사라지는 경로 접두사를 만들 때 매우 유용합니다. 예를 들어 {node_name?:_}는 노드 이름을 알 수 있을 때는 파일 이름 앞에 node_name_을 추가하지만, 노드 이름이 없을 때는 아무것도 생성하지 않습니다:
{node_name?:_}{file_name_base}
node_name="ImageGen", file_name_base="render" → ImageGen_render
node_name 제공되지 않음, file_name_base="render" → render
경로 구분 기호도 동일하게 작동합니다. {sub_dirs?:/}는 하위 디렉터리가 지정된 경우에만 하위 디렉터리 접두사를 추가합니다:
{outputs}/{sub_dirs?:/}{file_name_base}.{file_extension}
sub_dirs="lighting/pass_a", file_name_base="render", file_extension="exr"
→ outputs/lighting/pass_a/render.exr
sub_dirs 제공되지 않음, file_name_base="render", file_extension="exr"
→ outputs/render.exr
선행 구분자
{variable_name:^prefix}
구분자 포맷과 유사하지만, 텍스트가 변수 값의 뒤가 아니라 앞에 추가(prepend)됩니다. 형식 지정자 텍스트 시작 부분의 ^로 표시되며, ^ 뒤의 모든 내용은 리터럴 접두사 페이로드가 됩니다. 변수가 값을 출력할 때만 렌더링되며, 바인딩되지 않은 선택적 변수는 선행 구분자와 함께 완전히 생략됩니다.
{file_name_base}{version?:^_v}.{file_extension}
file_name_base="render", version=3, file_extension="png" → render_v3.png
file_name_base="render", version 제공되지 않음 → render.png
주요 활용 패턴: 시퀀스 슬롯과 함께 사용하여 시퀀스 유무에 따라 나타나고 사라지는 버전 접미사를 만듭니다:
render{###?:^_v}.png
첫 번째 저장 (슬롯 생략) → render.png
두 번째 저장 (슬롯 동작) → render_v001.png
세 번째 저장 → render_v002.png
파일 이름 외의 다른 텍스트에서도 작동합니다. 후행 구분자나 선행 구분자 모두 경로 접두사용으로만 제한되지 않습니다:
Hello, {name?}!{intro?:^ Nice to meet you.}
name="Alice", intro="y" → Hello, Alice! Nice to meet you.y
name="Alice", intro 제공 안됨 → Hello, Alice!
name 제공 안됨, intro 제공 안됨 → Hello, !
조합 규칙
- 하나의 변수는 최대 하나의 선행 구분자만 가질 수 있습니다.
- 선행 구분자는 템플릿에 작성된 위치와 관계없이 동일한 변수의 다른 모든 형식 지정자 이후에 적용됩니다.
{shot:03:^_v}와{shot:^_v:03}는 둘 다shot=5일 때_v005로 렌더링됩니다. 파서는 선행 지정자를 목록의 끝으로 정규화하므로 순서로 인해 접두사가 왜곡되지 않습니다.
관련 문법 오류
| 오류 | 원인 |
|---|---|
EMPTY_LEADING_SEPARATOR |
캐럿(^) 뒤에 페이로드가 없는 :^ 사용 |
MULTIPLE_LEADING_SEPARATORS |
동일한 변수에 두 개 이상의 :^ 지정자 사용 |
제한 사항. 형식 지정자 시작 부분의 ^는 선행 구분자 식별자로 예약되어 있으므로, 현재 리터럴 ^_v 접두사를 직접 표현할 수는 없습니다. 향후 이스케이프 메커니즘(예: \^ 또는 '^' 인용 형식)이 도입될 수 있습니다.
숫자 패딩
{variable_name:03}
지정된 자릿수 너비로 값을 0(zero) 패딩합니다. 변수는 정수 값을 가져야 합니다.
{_index:03} (_index = 5 일 때) → "005"
{_index:04} (_index = 12 일 때) → "0012"
create_new 충돌 정책에서 파일 이름을 자동 증가시킬 때 사용됩니다. 단일 미해결 변수에 숫자 패딩(:NN)을 적용하는 것이 옵트인 방식입니다. 첫 번째 저장은 인덱스 1(선택적 형식인 경우 생략)에 도달하고, 후속 저장은 동일한 템플릿에 대해 계속 증가하며 전체 시퀀스에 걸쳐 패딩 형식이 유지됩니다.
- 선택적 형식
{_index?:03}— 첫 번째 저장 시 생략된 후 충돌 시_001,_002, …로 진행(패딩 너비 유지). - 필수 형식
{_index:03}— 첫 번째 저장부터_001,_002,_003, …으로 존재하며 전체 시퀀스에 걸쳐 일관된 자릿수 너비 유지.
템플릿: {file_name_base}_v{_index:03}.{file_extension}
저장 #1 → render_v001.png
저장 #2 → render_v002.png
저장 #3 → render_v003.png
변수 이름이 반드시 _index일 필요는 없습니다. :NN 패딩이 지정된 단일 미해결 필수 변수는 모두 자동 할당됩니다. 패딩이 없으면 미해결 필수 변수는 바인딩 누락(구성 오류)으로 처리되어 저장이 실패합니다. 이는 사용자가 실수로 {shot}을 연결하지 않았을 때 자동으로 1, 2, 3, …으로 채워지는 것을 방지합니다.
시퀀스 슬롯 ({###})
{#} → 최소 1자리 (1, 2, ..., 9, 10, 11, ...)
{###} → 최소 3자리 (001, 002, ..., 999, 1000, ...)
{####} → 최소 4자리 (0001, 0002, ..., 9999, 10000, ...)
{##?} → 최소 2자리, 선택 사항 (첫 저장 시 생략, 충돌 시 01, 02, …)
{} 중괄호 안의 연속된 # 문자는 시퀀스 슬롯을 나타내는 명시적 구문입니다. 각 #은 최소 렌더링 자릿수 1자리를 의미합니다. 10 ^ width 미만의 값은 해당 너비에 맞춰 0으로 패딩되며, 그 이상의 값은 잘림 없이 원래 너비대로 렌더링됩니다. 이는 ffmpeg(%03d), Houdini($F4), Nuke(####) 및 Python의 :03 형식 지정자에서 널리 쓰이는 ### 규칙과 일치합니다.
중괄호 내부의 후행 ?(예: {##?})는 슬롯을 선택적으로 표시합니다(다른 변수와 동일한 규칙). 선택적 슬롯은 첫 저장 시 생략되고 충돌 시에만 채워집니다.
템플릿: {file_name_base}_v{###}.{file_extension}
저장 #1 → render_v001.png
저장 #2 → render_v002.png
...
저장 #999 → render_v999.png
저장 #1000 → render_v1000.png (오버플로: 잘리지 않고 4자리로 출력)
템플릿 (선택적): {file_name_base}{##?}.{file_extension}
저장 #1 → render.png (슬롯 생략)
저장 #2 → render01.png (충돌 시 슬롯 채워짐)
저장 #3 → render02.png
시스템이 자동 할당하는 시퀀스 인덱스가 필요할 때마다 {###}를 사용하세요. 이는 위에서 설명한 숫자 패딩 휴리스틱에 의존하지 않고 "create_new가 충돌 시 이 슬롯을 증가시켜야 함"을 명시하므로, 사용자가 바인딩한 {shot:03} 변수가 필요한 매크로 작성자가 모호함 없이 작성할 수 있습니다.
{}로 감싸는 이유. 매크로 템플릿은 일반 # 문자가 다른 의미(마크다운 헤더, 주석, 셸 스크립트 등)를 갖는 환경에서 자주 사용됩니다. 기호를 {}로 감싸면 시퀀스 슬롯 구문이 이미 "이것은 매크로 변수임"을 나타내는 구분 기호 안에 머물게 되므로, 정적 텍스트의 불필요한 # 문자에 대한 이스케이프 규칙이 필요 없습니다.
매크로당 하나의 시퀀스 슬롯. 두 개의 {###} 블록이 포함된 템플릿(예: {###}_take_{##}.png)은 파싱 시점에 거부됩니다. 시스템이 어떤 슬롯을 자동 할당해야 할지 알 수 없기 때문입니다. 두 번째 숫자가 필요한 경우 명시적인 {var}로 구성하세요.
{_index:NN}과의 관계. 내부적으로 {###}는 시퀀스 형식 마커를 포함하는 _index라는 이름의 변수로 변환(desugar)됩니다. 기존의 {_index:03} / {_index?:03} 구문도 이전 버전과의 호환성을 위해 계속 작동하며 시퀀스 슬롯으로 처리되지만, 앞으로는 {###} 형식을 권장합니다. 프로젝트 템플릿이 마이그레이션되면 향후 버전에서 {_index:NN} 단축형이 지원 중단될 수 있습니다(이슈 #4902 참조).
미해결 시퀀스 슬롯
필수 {###} 슬롯은 쓰기 경로에서 할당하기 전까지 값이 없습니다. 해당 할당이 발생하기 전에 매크로를 해석하는 모든 코드(출력이 저장될 위치를 미리 보는 노드, 사용자 입력을 절대 경로와 상대 경로로 분류하는 UI 등)는 빈 슬롯에 대해 리졸버가 어떻게 동작해야 하는지 지정해야 합니다. GetPathForMacroRequest는 UnresolvedSequenceSlotBehavior 열거형 값인 unresolved_sequence_slot_behavior로 이 옵션을 제공합니다:
| 동작 | 렌더링 결과 | 사용 시점 |
|---|---|---|
FAIL (기본값) |
MISSING_REQUIRED_VARIABLES 실패 |
쓰기 경로(write path) — 실패 신호는 on_write_file_request가 첫 번째 인덱스를 시드하고 충돌 시 재시도하는 데 사용하는 신호입니다. 다른 용도에서는 기본값을 재정의하지 마세요. |
RENDER_SEQUENCE_PATTERN |
### (또는 소스 너비에 맞춘 ####) |
표시(Presentation) 전용. 슬롯을 일반 해시 기호(범용 ffmpeg / Houdini / Nuke 규칙)로 렌더링하여 결과 경로가 디스크 상의 패턴 모양으로 읽히도록 합니다. 이 패턴은 유효한 파일 시스템 경로가 아니므로 절대 파일을 열거나 쓰거나 I/O 프리미티브에 전달하지 마세요. |
START_AT_ZERO |
000 |
첫 번째 저장 전에 0부터 시작하는 인덱스 시퀀스를 미리 볼 때 사용합니다. |
START_AT_ONE |
001 |
"첫 번째 저장이 어디에 저장될지" 미리 볼 때 사용합니다. 쓰기 경로 시드와 일치하므로 대상이 비어 있을 때 미리보기가 실제 저장과 일치합니다. |
선택적 슬롯({###?})은 영향을 받지 않습니다. 바인딩되지 않은 경우 이미 생략되므로 플래그는 필수 슬롯에만 적용됩니다.
기본 원칙. 코드가 파일을 열려고 하는 경우 플래그를 전달하지 마세요. 쓰기 경로가 자체적으로 처리하도록 둡니다. 사용자에게 문자열을 표시하려는 경우에는 RENDER_SEQUENCE_PATTERN을 사용하세요. START_AT_ZERO / START_AT_ONE은 실제 첫 번째 저장을 미리 보기 위한 특수한 도구입니다.
문자열 변환
| 형식 지정자 | 설명 | 결과 예시 |
|---|---|---|
:lower |
모두 소문자 | "my autumn shoot" |
:upper |
모두 대문자 | "MY AUTUMN SHOOT" |
:title |
단어 첫 글자 대문자 (Title Case) | "My Autumn Shoot" |
:snake |
스네이크 케이스 (snake_case) | "my_autumn_shoot" |
:pascal |
파스칼 케이스 (PascalCase) | "MyAutumnShoot" |
:camel |
카멜 케이스 (camelCase) | "myAutumnShoot" |
:screaming_snake |
대문자 스네이크 케이스 (SCREAMING_SNAKE_CASE) | "MY_AUTUMN_SHOOT" |
:slug |
슬러그 (공백→하이픈, 영숫자가 아닌 문자 제거) | "my-autumn-shoot" |
:dot |
점 표기법 (dot.case) | "my.autumn.shoot" |
:abbrev |
각 단어의 첫 글자 약어 | "MAS" |
:trim |
앞뒤 공백 제거 | "My Autumn Shoot" |
예를 들어, workflow_name이 "My Autumn Shoot"인 경우:
{workflow_name:lower} → "my autumn shoot"
{workflow_name:upper} → "MY AUTUMN SHOOT"
{workflow_name:title} → "My Autumn Shoot"
{workflow_name:snake} → "my_autumn_shoot"
{workflow_name:pascal} → "MyAutumnShoot"
{workflow_name:camel} → "myAutumnShoot"
{workflow_name:screaming_snake} → "MY_AUTUMN_SHOOT"
{workflow_name:slug} → "my-autumn-shoot"
{workflow_name:dot} → "my.autumn.shoot"
{workflow_name:abbrev} → "MAS"
:snake, :pascal, :camel, :dot, :screaming_snake는 대소문자 전환 지점을 기준으로 분할하여 camelCase 및 PascalCase 입력도 올바르게 처리하므로 {varName:snake} → "var_name"으로 예상대로 작동합니다.
:trim은 다른 변환 전의 사전 처리 단계로 매우 유용합니다. 예를 들어 {name:trim:snake}는 주변 공백을 제거한 후 snake_case로 변환합니다.
기본값
{variable_name|default_value}
변수가 제공되지 않으면 default_value가 대신 사용됩니다.
{workflow_name|untitled} → workflow_name이 제공되지 않으면 "untitled" 사용
형식 지정자 체이닝 (연결)
여러 형식 지정자는 :로 구분되며 왼쪽에서 오른쪽으로 순서대로 적용됩니다. 구분자를 사용하는 경우 반드시 맨 처음에 와야 합니다:
{variable_name:_:lower} → 밑줄(_)이 추가된 소문자 값
{variable_name:lower:slug} → 소문자 변환 후 슬러그 변환
따옴표로 감싼 구분자
구분자 텍스트가 lower 또는 upper와 같은 키워드와 일치하는 경우, 작은따옴표로 감싸서 리터럴 구분자로 처리하세요:
{variable_name:'lower'} → 텍스트 "lower"를 구분자로 추가
매크로 해석 (Resolution)
매크로가 해석될 때 디렉터리 이름과 내장 변수는 프로젝트 시스템에서 자동으로 제공됩니다. 사용자는 특정 작업과 관련된 변수(예: file_name_base 및 file_extension)만 제공하면 됩니다.
예를 들어, save_node_output 시츄에이션 매크로를 해석하는 경우:
템플릿: {outputs}/{sub_dirs?:/}{node_name?:_}{file_name_base}{_index?:03}.{file_extension}
자동 제공: outputs → "outputs" 디렉터리 정의에서 확인됨 → "outputs"
사용자 지정: node_name="StyleTransfer", file_name_base="portrait", _index=3, file_extension="png"
결과: outputs/StyleTransfer_portrait003.png
디렉터리 이름(outputs 등)은 구성된 경로로 자동 해석됩니다. 자세한 내용은 디렉터리를 참조하세요.
내장 변수(workflow_name, project_dir 등)도 자동으로 제공됩니다. 자세한 내용은 환경 및 내장 변수를 참조하세요.
역방향 매칭 (Reverse matching)
매크로 시스템은 역방향으로도 작동할 수 있습니다. 실제 경로와 매크로 템플릿이 주어지면 변수 값을 추출할 수 있습니다. 이는 시스템이 파일이 알려진 프로젝트 디렉터리에 속하는지 확인하고 해당 이름에 어떤 메타데이터가 인코딩되어 있는지 식별해야 할 때 사용됩니다(예: create_versioned_workflow 저장 경로는 기존 파일 이름을 다시 읽어 증가시킬 _index를 파악함).
공개 API는 ParsedMacro.extract_variables(path, known_variables, secrets_manager)입니다(불리언 확인의 경우 matches(...)).
기본 예시:
템플릿: {outputs}/{node_name?:_}{file_name_base}{_index?:03}.{file_extension}
경로: outputs/StyleTransfer_portrait003.png
추출 결과: outputs="outputs", node_name="StyleTransfer", file_name_base="portrait", _index=3, file_extension="png"
추출 시 각 변수의 끝을 결정하는 방법
{a}/{b}/{c}.{ext}와 같은 템플릿의 경우 추출기는 왼쪽에서 오른쪽으로 탐색합니다. 각 변수의 값은 경로에 나타나야 하는 고정 텍스트인 다음 앵커(anchor)에서 끝납니다. 두 종류의 앵커가 존재합니다:
- 다음 세그먼트 앵커(Next-segment anchor). 다음 정적 세그먼트의 텍스트(예:
.png) 또는 다음 변수의 선행 구분자 접두사(예:{###?:^_v}내부의_v). - 자체 앵커(Self-anchor). 변수 자체의 후행 구분자(예:
{node_name?:_}의_).
추출기는 가장 엄격하고 일관된 분할을 생성하는 앵커를 사용합니다. 둘 다 사용 가능한 경우 검색 방향은 뒤에 오는 항목에 따라 달라집니다. 다음 세그먼트가 정적인 경우 정적 세그먼트 앞의 가장 마지막(LATEST) 자체 앵커를 선택하고(가장 엄격한 오른쪽 가장자리 분할), 다음 세그먼트가 다른 변수인 경우 첫 번째(FIRST) 자체 앵커를 선택합니다(뒤따르는 변수가 사용할 수 있는 공간 확보). 이를 통해 first_second_file.png에 대한 {a?:_}{b?:_}file.png 템플릿이 a=first_second, b=""가 아닌 a=first, b=second로 분할됩니다.
선택적 변수(?) — 모호성 해결 방법
선택적 변수는 경로가 기록될 당시 출력되었을 수도 있고 생략되었을 수도 있습니다. 역방향 매칭은 "각 선택적 변수의 출력 여부"에 대한 모든 2ᵏ가지 조합($k$는 템플릿의 바인딩되지 않은 선택적 변수 수)을 열거하고 각 조합을 추출한 다음 왕복 검증(round-trip)을 통해 유효성을 검사합니다. 추출된 값을 템플릿을 통해 다시 해석했을 때 그 결과가 입력 경로와 바이트 단위로 정확히 일치해야 합니다.
조합은 popcount 내림차순(가장 많은 선택적 변수가 출력되어 가장 많은 정보가 복구된 해석 우선)으로 시도됩니다. 왕복 검증에 성공하는 첫 번째 조합이 채택됩니다.
대표적인 예시:
템플릿: {workspace_dir}/{sub_dirs?:/}{file_name_base}{###?:^_v}.{file_extension}
알려진 값: workspace_dir="/ws", file_extension="py"
경로: /ws/my_flow_v001.py
시도 1 (두 선택적 변수 모두 출력): sub_dirs="my_flow", file_name_base="",
_index=1 → "/ws/my_flow/_v001.py"로 해석됨 — 불일치(MISS).
시도 2 (sub_dirs 켬, _index 끔): sub_dirs="my_flow_v001", file_name_base=""
→ "/ws/my_flow_v001/.py"로 해석됨 — 불일치(MISS).
시도 3 (sub_dirs 끔, _index 켬): file_name_base="my_flow", _index=1
→ "/ws/my_flow_v001.py"로 해석됨 — 일치(MATCH) ✓
3번째 시도가 성공하면 4번째 조합은 시도되지 않습니다.
알아두어야 할 사항:
- 빈 문자열을 캡처하는 출력된 선택적 변수는 왕복 검증이 실행되기 전에 거부됩니다. 빈 값을 캡처하는 것은 "해당 슬롯이 값을 출력했다"는 가설과 모순되기 때문입니다.
- 왕복 검증은 탐욕적 잘못 읽기를 포착합니다. 입력 경로와 다른 문자열로 해석되는 추출은 절대 채택될 수 없습니다. 이것이 추출기의 탐욕적 앵커 선택이 안전한 이유입니다. 잘못된 선택은 왕복 검증에 실패하고 다음 조합이 시도됩니다.
- 여러 조합이 왕복 검증을 통과하는 경우 popcount가 가장 높은 조합이 승리합니다. popcount 내에서 동률인 경우 마스크 값(오름차순)으로 결정되며, 이는 결정론적이지만 의미론적 의미는 없습니다(아래 "모호하지 않은 템플릿 작성하기" 참조).
모호하지 않은 템플릿 작성하기
사이에 고정 텍스트가 없는 두 변수가 모두 바인딩되지 않은 경우 문법적으로 모호해집니다. 문법으로는 모호한 경계의 어느 쪽에 문자가 속하는지 알 수 있는 방법이 없습니다. 역방향 매칭은 여전히 왕복 검증을 통과하는 유효한 결과를 반환하지만, 특정 해석이 템플릿 전반에 걸쳐 예측 가능하지는 않습니다.
설계 지침:
- 신뢰할 수 있는 역방향 매칭을 원할 경우 인접한 변수 사이에 정적 구분자(또는 고유한 선행 구분자 접두사)를 배치하세요.
{name}_{version}은 명확하지만{name}{version}은 모호합니다. - 선행 구분자가 있는 시퀀스 슬롯 형태(
{###?:^_v})는 버전이 지정된 파일 이름에 권장되는 패턴입니다._v접두사는 추출기가 앞에 어떤 내용이 오든 버전 경계를 찾을 수 있도록 해주는 고유한 앵커 역할을 합니다. - 이미 알고 있는 값은
known_variables를 통해 미리 제공하세요. 알려진 변수마다 2ᵏ 검색에서 차원을 하나씩 제거하고 모호성의 원인을 없앱니다.
역방향 경로에서의 형식 지정자
모든 형식 지정자에 무손실 역변환이 가능한 것은 아닙니다. 지정자를 명확하게 되돌릴 수 없는 경우 추출기는 원시 문자열을 반환하고 호출자가 처리 방법을 결정하도록 합니다.
| 형식 지정자 | 역방향 동작 |
|---|---|
:03 (숫자 패딩) |
정수로 파싱됨("005" → 5). 숫자가 아닌 값은 지정자 검증에 실패하여 해당 추출 시도가 제외됩니다. |
{###} / {###?} (시퀀스 슬롯) |
숫자 패딩과 동일 — int로 파싱됩니다. 바인딩되면 _index로 값을 사용할 수 있습니다. |
:_ (후행 구분자) |
후행 구분자가 있는 경우 이를 제거합니다. 없는 경우 멱등성을 유지합니다. |
:^_v (선행 구분자) |
접두사가 있는 경우 이를 제거합니다. 없는 경우 멱등성을 유지합니다. 이전 변수의 추출이 뒤따르는 경우 접두사는 앵커 역할도 수행합니다. |
:lower / :upper / :title / … |
대소문자 변환은 추출된 부분 문자열을 그대로 반환합니다. 원래 대소문자는 복구할 수 없습니다. 일치 키에서 왕복 정확도가 필요한 경우 피하세요. |
:slug / :snake / :pascal / … |
단방향 변환은 원시 추출 값을 그대로 반환합니다. |
|default_value |
기본값은 순방향 전용 구조입니다. 역방향 경로에서는 변수가 경로에서 추출되거나 바인딩되지 않은 상태로 유지되며, 기본 텍스트는 주입되지 않습니다. |
실질적 제한 사항
- 역방향 매칭은 바인딩되지 않은 선택적 변수의 수를 최대 5개(2⁵ = 32개 조합)로 제한합니다. 6개 이상의 바인딩되지 않은 선택적 변수가 있는 템플릿은
MacroParseFailureReason.TOO_MANY_OPTIONAL_VARIABLES를 발생시킵니다. 실제 트리 템플릿은 최대 3개의 선택적 변수를 가지며, 이 제한은 비정상적인 문법에 대한 과도한 연산을 방지하기 위해 존재합니다. - 이 상한선은
known_variables에 의해 바인딩되지 않은 선택적 변수만 계산합니다. 선택적 변수를 미리 바인딩하면 검색 공간에서 제거되므로, 호출자가 6개의 변수를 모두 제공하는 경우 선택적 변수가 6개인 템플릿도 여전히 역방향 매칭이 가능합니다. - 경로 일치는 바이트 단위로 정확(byte-exact)합니다. 크로스 플랫폼 호출자는
extract_variables를 호출하기 전에 경로 구분 기호를 슬래시(/)로 정규화해야 합니다(자동 해석되는 디렉터리 내장 변수의 경우 기본 제공 프로젝트 디렉터리 매칭 핸들러가 이를 자동으로 수행함).
구문 오류
매크로 파서는 문제 해결을 돕기 위해 위치 번호와 함께 구문 오류를 보고합니다:
- 닫히지 않은 중괄호:
{variable_name(닫는}없음) - 짝이 맞지 않는 닫는 중괄호:
variable}name - 중첩된 중괄호:
{outer{inner}} - 빈 변수:
{}