feat: add pattern alias mode to crafting shortcode

This commit is contained in:
FlipWind
2026-08-09 00:12:06 +08:00
parent c1a8ffb323
commit cd19dddad1
4 changed files with 107 additions and 24 deletions
+21
View File
@@ -39,3 +39,24 @@
- 需要显示堆叠数量时写 `名称:数量`,例如 `b2="stick:2"`
- `caption` 可选,显示在组件下方居中说明文字;
- 未运行自动同步且贴图缺失时,格子内会显示一个 `?` 占位,方便发现写错的名字。
### pattern 别名模式(另一种写法)
不想数格子时,可以用 `pattern` 先画好形状,再为每个字符别名指定物品:
```markdown
{{< crafting
pattern="a a a\nb b b\nc c c"
a="diamond"
b="stick"
c=""
out="diamond_pickaxe"
caption="钻石镐"
>}}
```
- `pattern` 共 9 个 token(3 行 × 3 列),**必须写在一行内**,行间用 `\n` 表示;
- 每个 token 对应一个同名参数(`a``b``c`…),参数值就是物品 id
- token 也可以直接写物品 id`pattern="diamond stick ."`
- `.` 表示空格子;
- 同时给出 `pattern``a1`~`c3` 时,以 `pattern` 为准(`out` 两者通用)。
+1 -1
View File
@@ -1,4 +1,4 @@
{{- $val := trim (.ctx.Get .key) " " -}}
{{- $val := .val -}}
{{- $item := "" -}}
{{- $count := 0 -}}
{{- if $val -}}
+64 -17
View File
@@ -1,6 +1,11 @@
{{- /* SFCraft 合成配方组件
- 调用: 页面内写 shortcode, 名为 crafting
- a1..c3 为 3x3 合成格, out 为输出格
两种用法:
1) 九格直填: a1..c3 为 3x3 合成格, out 为输出格
2) pattern 别名模式(提供 pattern 时优先):
pattern="a a a\nb b b\nc c c" 行间用 \n(必须写在一行内), 也可用空格或 ; 分隔, 共 9 个 token
a="diamond" b="stick" c="" 每个 token 对应一个同名参数, 值为物品 id
token 也可以直接写物品 id, 如 pattern="diamond stick ."
"." 表示空格子
- 值为 assets/items/ 下贴图的文件名(不含 .png), 留空表示空格子
- 名称后可加 ":数量" 显示堆叠数, 例如 a1="stick:2"
- 引用的贴图不存在时, 格子内显示 ? 占位提示
@@ -21,6 +26,16 @@
(dict "key" "out" "cls" "out" "x" "70%" "y" "37.5%")
-}}
{{- $ctx := . -}}
{{- $pattern := $ctx.Get "pattern" -}}
{{- $tokens := slice -}}
{{- if $pattern -}}
{{- $flat := replace (replace (replace (replace $pattern "\\n" " ") ";" " ") "\n" " ") "\r" " " -}}
{{- range split (trim $flat " ") " " -}}
{{- if ne . "" -}}{{- $tokens = $tokens | append . -}}{{- end -}}
{{- end -}}
{{- end -}}
{{- $cssOnce := .Page.Store.Get "sfc_crafting_css" -}}
{{- if not $cssOnce -}}
{{- .Page.Store.Set "sfc_crafting_css" true -}}
@@ -104,21 +119,53 @@
font-size: 0.85rem;
color: var(--gray-600, #6c757d);
}
.sfc-error {
max-width: 540px;
margin: 1rem 0;
padding: 0.6rem 1rem;
border: 1px solid #f5c2c7;
border-radius: 6px;
background: #f8d7da;
color: #842029;
font-size: 0.9rem;
}
</style>
{{- end -}}
<figure class="sfc-crafting" style="background-image: url('{{ $table.RelPermalink }}');">
{{- range $slots -}}
{{- partial "crafting-slot.html"
(dict
"ctx" $
"key" .key
"cls" .cls
"x" .x
"y" .y
) -}}
{{- end -}}
{{- with .Get "caption" -}}
<figcaption class="sfc-caption">{{ . }}</figcaption>
{{- end -}}
</figure>
{{- if and $pattern (ne (len $tokens) 9) -}}
<div class="sfc-error">
crafting 的 pattern 需要恰好 9 个 token3 行 × 3 列),当前是 {{ len $tokens }} 个。
请检查 pattern="a a a\nb b b\nc c c" 的写法。
</div>
{{- else -}}
<figure class="sfc-crafting" style="background-image: url('{{ $table.RelPermalink }}');">
{{- range $i, $slot := $slots -}}
{{- $val := "" -}}
{{- if eq $slot.key "out" -}}
{{- $val = trim ($ctx.Get "out") " " -}}
{{- else if $pattern -}}
{{- $token := "" -}}
{{- if lt $i (len $tokens) -}}{{- $token = index $tokens $i -}}{{- end -}}
{{- if and (ne $token "") (ne $token ".") -}}
{{- $v := trim ($ctx.Get $token) " " -}}
{{- if eq $v "" -}}
{{- if findRE "^[a-z0-9_]+$" $token -}}{{- $v = $token -}}{{- end -}}
{{- end -}}
{{- $val = $v -}}
{{- end -}}
{{- else -}}
{{- $val = trim ($ctx.Get $slot.key) " " -}}
{{- end -}}
{{- partial "crafting-slot.html"
(dict
"val" $val
"cls" $slot.cls
"x" $slot.x
"y" $slot.y
) -}}
{{- end -}}
{{- with $ctx.Get "caption" -}}
<figcaption class="sfc-caption">{{ . }}</figcaption>
{{- end -}}
</figure>
{{- end -}}
+21 -6
View File
@@ -77,16 +77,31 @@ try {
Write-Step '2/4 扫描组件物品 id'
$ids = @{}
$shortcodePat = [regex]'(?s){{<[ ]*crafting\b(.*?)}}'
$paramPat = [regex]'(?:a[123]|b[123]|c[123]|out)="([^"]*)"'
$pairPat = [regex]'(\w+)="([^"]*)"'
$slotKeys = @('a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3', 'out')
function Add-ItemId([string]$raw) {
$v = $raw.Trim()
if ($v.Length -gt 0) {
$id = ($v -split ':')[0].Trim()
if ($id.Length -gt 0) { $ids[$id] = $true }
}
}
Get-ChildItem -Path $contentDir -Recurse -Filter '*.md' -File | ForEach-Object {
$text = Get-Content -LiteralPath $_.FullName -Raw -Encoding UTF8
foreach ($m in $shortcodePat.Matches($text)) {
foreach ($p in $paramPat.Matches($m.Groups[1].Value)) {
$val = $p.Groups[1].Value.Trim()
if ($val.Length -gt 0) {
$id = ($val -split ':')[0].Trim()
if ($id.Length -gt 0) { $ids[$id] = $true }
$params = @{}
foreach ($p in $pairPat.Matches($m.Groups[1].Value)) { $params[$p.Groups[1].Value] = $p.Groups[2].Value }
foreach ($key in $slotKeys) {
if ($params.ContainsKey($key)) { Add-ItemId $params[$key] }
}
if ($params.ContainsKey('pattern')) {
$pat = $params['pattern'] -replace '\\n|;|\r?\n', ' '
foreach ($tok in @($pat -split '\s+' | Where-Object { $_ })) {
if ($tok -eq '.') { continue }
if ($params.ContainsKey($tok)) { Add-ItemId $params[$tok] }
elseif ($tok -match '^[a-z0-9_]+$') { Add-ItemId $tok }
}
}
}