이 글은 Claude Fable 5.1 을 이용해 초안이 작성되었으며, 이후 퇴고를 거쳤습니다.


들어가며#

이 블로그에는 포커와 같은 트럼프를 이용한 게임 관련 글이 많습니다. 예제는 늘 이런 식으로 적었습니다. “홀카드 A♠ K♥, 보드 7♦ 8♦ 2♣.” 읽히기는 하지만 카드 열두 장이 한 줄에 늘어서면 눈이 미끄러집니다. 어느 카드가 손에 있고 어느 카드가 보드에 있는지, 여덟 장 가운데 어느 다섯 장이 최고의 손인지를 글자로만 전달하는 데는 한계가 있었습니다.

바둑 글을 쓸 때 같은 문제를 goban shortcode 로 풀었습니다. 본문에는 읽기 쉬운 표기를 쓰고 렌더링만 SVG 로 바꾸는 방식입니다. 이번에는 같은 방식으로 트럼프 카드를 그립니다. 본문에 이렇게 쓰면,

{{< cards labels="홀카드,보드" caption="플랍" >}}
As Kh
7d 8d 2c
{{< /cards >}}

이렇게 나옵니다.

홀카드A♠K♥보드7♦8♦2♣
플랍

문장 안에 한 장만 넣을 수도 있습니다. {{< card "As" >}} 는 A♠ 로, {{< 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도해 아래 설명
sizesm 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 >}}
홀카드9♠7♦3♣보드5♥J♦K♥8♣2♦
스킵 스트레이트 3-5-7-9-J. 홀카드 세 장을 전부 쓰는 손

2.2. 상대의 카드는 뒷면으로#

{{< cards labels="나,상대,보드" caption="턴" >}}
As Kh | ? ? | 7d 8d 2c Jc
{{< /cards >}}
나A♠K♥상대보드7♦8♦2♣J♣
턴

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 >}}
런3♠4♠5♠6♠7♠런10♥J♥Q♥K♥셋9♥9♦9♣9♠
테이블에 등록된 조합 세 개. 첫 런은 붙이기로 다섯 장까지 자랐다

2.4. lg 와 네 무늬#

A♠K♥Q♦J♣10♠
네 무늬와 두 자리 랭크

2.5. 문장 안#

로렌스의 홀카드가 {{< card "As" >}} {{< card "Kh" >}} 이고 플랍이 {{< card "7d" >}} {{< card "8d" >}} {{< card "2c" >}} 라면, …

로렌스의 홀카드가 A♠ K♥ 이고 플랍이 7♦ 8♦ 2♣ 라면, 이 손은 아직 아무것도 아닙니다. 상대가 로 무엇을 들었든 그렇습니다.

2.6. 오타는 눈에 띄게#

1s 나 Ax 처럼 규칙에 맞지 않는 토큰은 조용히 건너뛰지 않고 붉은 ?! 카드로 그립니다. 빌드는 깨지지 않습니다.

{{< cards caption="가운데 두 장이 오타" >}}As 1s Ax Kh{{< /cards >}}
A♠?!?!K♥
가운데 두 장이 오타

옵션 없이 한 줄로 쓴 형식은 이렇습니다.

{{< cards "As 1s Ax Kh" />}}
A♠?!?!K♥

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#