Hugo 로 트럼프 카드 그리기: cards shortcode
이 글은 Claude Fable 5.1 을 이용해 초안이 작성되었으며, 이후 퇴고를 거쳤습니다.
들어가며#
이 블로그에는 포커와 같은 트럼프를 이용한 게임 관련 글이 많습니다. 예제는 늘 이런 식으로 적었습니다. “홀카드 A♠ K♥, 보드 7♦ 8♦ 2♣.” 읽히기는 하지만 카드 열두 장이 한 줄에 늘어서면 눈이 미끄러집니다. 어느 카드가 손에 있고 어느 카드가 보드에 있는지, 여덟 장 가운데 어느 다섯 장이 최고의 손인지를 글자로만 전달하는 데는 한계가 있었습니다.
바둑 글을 쓸 때 같은 문제를 goban shortcode 로 풀었습니다. 본문에는 읽기 쉬운 표기를 쓰고 렌더링만 SVG 로 바꾸는 방식입니다. 이번에는 같은 방식으로 트럼프 카드를 그립니다. 본문에 이렇게 쓰면,
{{< cards labels="홀카드,보드" caption="플랍" >}}
As Kh
7d 8d 2c
{{< /cards >}}
이렇게 나옵니다.
문장 안에 한 장만 넣을 수도 있습니다. {{< card "As" >}} 는
로, {{< card "?" >}} 는
로 그려집니다.
이 글은 그 shortcode 의 사용법과 설계 결정을 정리합니다. Hugo 와 shortcode 가 무엇인지는 goban 글의 1절에 있으니 여기서는 되풀이하지 않습니다.
1. 사용법#
1.1. 카드 표기#
카드 한 장은 랭크 + 무늬 두세 글자입니다. 포커 소프트웨어와 해외 자료가 쓰는 표준 표기 그대로입니다.
| 부분 | 값 |
|---|---|
| 랭크 | A K Q J T 9 8 7 6 5 4 3 2. T 대신 10 을 써도 됩니다. 소문자도 됩니다 |
| 무늬 | s 스페이드 ♠, h 하트 ♥, d 다이아몬드 ♦, c 클럽 ♣. 대문자도 됩니다 |
| 뒷면 | ? |
| 강조 | 토큰 뒤에 *. 예: As*, ?* |
| 그룹 | 줄을 바꾸거나 | 로 나눕니다. 그룹 사이에 간격이 생깁니다 |
이 블로그의 기존 글은 A♠ 처럼 유니코드 무늬 기호를 썼습니다. shortcode 입력으로는 받지 않습니다. 타이핑이 어렵고, 외부 자료를 옮길 때 변환이 필요하며, 입력 규칙이 둘이면 둘 다 검증해야 하기 때문입니다. 본문 문장에서는 지금처럼 A♠ 를 계속 쓰고, 그림이 필요할 때만 shortcode 를 씁니다.
1.2. cards — 도해#
{{< cards labels="라벨,라벨" caption="설명" size="sm|md|lg" >}}
카드들
카드들
{{< /cards >}}
옵션이 필요 없으면 한 줄로 쓸 수 있습니다. 끝의 / 는 Hugo 가 요구하는 자체 종료 표시입니다. Hugo 는 위치 인자와 이름 인자를 한 shortcode 에 섞지 못하므로, 옵션이 하나라도 있으면 위의 닫는 태그 형식을 씁니다.
{{< cards "As Kh | 7d 8d 2c" />}}
| 인자 | 뜻 |
|---|---|
| 본문 (또는 첫 인자) | 카드 문자열. 필수. 줄마다 한 그룹 |
labels | 그룹 위에 붙는 작은 라벨. 쉼표로 나눠 그룹 순서대로 |
caption | 도해 아래 설명 |
size | sm 40px, md 60px(기본), lg 80px. 카드 한 장의 폭입니다 |
1.3. card — 문장 안 한 장#
{{< card "Kh" >}}
인자는 카드 한 장뿐입니다. 라벨·캡션·강조는 없습니다. 글자 높이에 맞춰 작게 그리므로 중앙의 큰 무늬는 생략하고 코너 인덱스만 크게 그립니다.
2. 렌더링 예#
2.1. 포커: 여덟 장 가운데 최고의 다섯 장#
삼평 하이로우는 홀카드 3장과 보드 5장 가운데 아무 5장으로 손을 만듭니다. 어느 다섯 장인지를 강조로 표시합니다.
{{< cards labels="홀카드,보드" caption="스킵 스트레이트 3-5-7-9-J. 홀카드 세 장을 전부 쓰는 손" >}}
9s* 7d* 3c*
5h* Jd* Kh 8c 2d
{{< /cards >}}
2.2. 상대의 카드는 뒷면으로#
{{< cards labels="나,상대,보드" caption="턴" >}}
As Kh | ? ? | 7d 8d 2c Jc
{{< /cards >}}
2.3. 훌라: 긴 나열은 sm#
훌라의 손패는 최대 8장(7장 + 뽑은 카드 1장)이지만, 테이블에 등록한 조합은 붙이기로 계속 자라 열 장을 훌쩍 넘깁니다. sm 으로 그리면 열세 장이 한 줄에 들어갑니다.
{{< cards labels="런,런,셋" size="sm" caption="테이블에 등록된 조합 세 개. 첫 런은 붙이기로 다섯 장까지 자랐다" >}}
3s 4s 5s 6s 7s
10h Jh Qh Kh
9h 9d 9c 9s
{{< /cards >}}
2.4. lg 와 네 무늬#
2.5. 문장 안#
로렌스의 홀카드가 {{< card "As" >}} {{< card "Kh" >}} 이고 플랍이 {{< card "7d" >}} {{< card "8d" >}} {{< card "2c" >}} 라면, …
로렌스의 홀카드가 이고 플랍이 라면, 이 손은 아직 아무것도 아닙니다. 상대가 로 무엇을 들었든 그렇습니다.
2.6. 오타는 눈에 띄게#
1s 나 Ax 처럼 규칙에 맞지 않는 토큰은 조용히 건너뛰지 않고 붉은 ?! 카드로 그립니다. 빌드는 깨지지 않습니다.
{{< cards caption="가운데 두 장이 오타" >}}As 1s Ax Kh{{< /cards >}}
옵션 없이 한 줄로 쓴 형식은 이렇습니다.
{{< cards "As 1s Ax Kh" />}}
3. 설계 결정#
3.1. 왜 이미지도 이모지도 아닌가#
후보는 넷이었습니다.
| 후보 | 버린 이유 |
|---|---|
| 이미지 파일 | 카드 조합마다 파일을 만들어야 합니다. 52장 낱장을 두고 조합하려면 결국 마크업이 필요합니다 |
| 유니코드 플레잉 카드 글자 (🂡 🂮) | 글자 하나로 카드 한 장이라 가장 쉽지만, 모바일·윈도우에서 폰트가 없어 빈 네모로 보이는 일이 잦습니다 |
| 이모지 무늬 (♠️ ♥️) | OS 이모지 폰트가 그립니다. 애플의 하트와 구글의 하트가 다르고, CSS 로 색을 바꿀 수 없습니다 |
| mermaid | 카드 모양을 낼 수 없습니다 |
그래서 goban 과 같은 결론입니다. 소스는 글자, 렌더링은 SVG. 무늬는 ♠♥♦♣ 를 일반 텍스트 글자로 SVG 안에 넣고 색은 CSS fill 로 칠합니다. 어느 OS 에서든 같은 모양이고, 다크 테마에서도 카드는 흰색으로 고정됩니다.
3.2. 카드 한 장의 그림#
기준 좌표계는 60 × 84 로, 실제 카드(63 × 88mm)의 비율입니다. 왼쪽 위에 랭크, 가운데에 큰 무늬를 둡니다. 실제 카드의 코너 인덱스에 있는 작은 무늬와 오른쪽 아래의 뒤집힌 인덱스는 넣지 않았습니다. 무늬는 가운데 하나로 충분하고, sm 크기에서는 지저분해지기 때문입니다. 10 은 두 글자라 폭이 넓어져 랭크 글꼴만 조금 줄입니다.
세 크기는 같은 그림을 transform="scale()" 로 줄이고 늘린 것이라, 크기마다 좌표를 따로 계산하지 않습니다.
3.3. 파일 구성#
| 파일 | 역할 |
|---|---|
layouts/partials/card-svg.html | 카드 한 장을 그리는 공통 partial |
layouts/shortcodes/cards.html | 문자열을 파싱해 카드를 나열하는 도해 |
layouts/shortcodes/card.html | 문장 안 한 장 |
layouts/partials/extended_head.html | 색·크기 CSS |
두 shortcode 가 같은 partial 을 쓰므로 그림을 고치면 양쪽에 함께 반영됩니다. 파싱은 goban 처럼 Hugo 템플릿의 findRE 와 replaceRE 만 씁니다. 빌드 도구나 JavaScript 가 없습니다.
3.4. 접근성#
도해 전체는 role="img" 이고 aria-label 에 “카드: A♠ K♥ | 7♦ 8♦ 2♣” 처럼 카드 목록이 들어갑니다. 캡션이 있으면 캡션이 대신 들어갑니다. 스크린 리더는 그림 대신 이 목록을 읽습니다.
4. 하지 않은 것#
- 조커. 이 블로그의 게임 글에 조커가 나오는 경우가 아직 없습니다.
- 4색 덱. 온라인 포커처럼 ♦ 를 파랑, ♣ 를 초록으로 칠하는 방식은 실제 카드와 달라 넣지 않았습니다. CSS 클래스가 무늬별로 갈리지 않으므로 필요하면 그때 partial 을 고칩니다.
- 기존 글 변환. 발행된 글의
A♠ K♥표기는 그대로 둡니다. 새 글부터 씁니다. - 겹쳐 놓기·부채꼴 배치. 카드는 항상 한 줄로 나열합니다.
References#
- 이 블로그, Hugo 로 바둑판 도해 그리기 Part 1 — 같은 방식의 첫 shortcode
- Hugo 문서, Shortcodes, findRE, replaceRE