본문으로 이동

그림 검사

요약

그림 검사는 배치가 끝난 장면과 시간표에서 화면 오류(겹침, 넘침, 뚫고 지나가는 선, 떨어진 선 끝)를 찾아 원본 줄 번호와 함께 알리는 기능이다. render는 그리기 전에 늘 검사하고, check는 검사만 한다. 오류가 있으면 그림 파일을 쓰지 않는다.

동기

첫 구현의 화면 오류는 사람이 그림을 열어 보고서야 찾았다. 선 끝이 상자 아래쪽에 붙은 오류, 순서 그림 메시지가 참여자 옆으로 몰린 오류, 라벨이 겹친 오류가 모두 테스트를 통과한 뒤에 나왔다. 원본을 쓰는 쪽이 그림을 열어 보지 못하는 경우가 있으므로, 화면 오류도 문법 오류처럼 줄 번호가 붙은 메시지로 나와야 고칠 수 있다.

예시

겹친 라벨 알아채기

  1. 원본의 두 선 라벨이 같은 자리에 놓인다.
  2. check가 api.thinkflow:14: edge label "INSERT" overlaps edge label "INSERT 2 rows" (line 16). Shorten a label or change a group direction를 내고 실패한다.

비율 경고

  1. 가로 그림이 20:1로 길다.
  2. check가 api.thinkflow:1: warning: figure aspect 20.0 is outside 1/3 to 3. Add "aspect 1.6"을 경고로 낸다. 이미 aspect가 있으면 더 작은 값을 권한다.
  3. 그룹이 있는 그림에서 비율을 줄이는 쪽으로 방향을 바꿀 그룹이 있으면 aspect 대신 Set direction=down on group "{가장 넓은 그룹}"을 먼저 권한다. 방향을 바꿀 그룹은 안에 도형이나 하위 그룹이 둘 이상 있는 그룹뿐이다.
  4. 그런 그룹이 없거나 이미 그 방향이면 그룹 그림에도 Add "aspect 1.6"을 권한다.

상세 설계

검사 항목

표는 src/check/items.js의 항목 목록에서 npm run checkdoc으로 만든다. 번호, code, 등급, 설명을 바꾸면 그 목록을 고치고 표를 다시 쓴다. 표와 목록이 다르면 테스트가 실패한다.

<!-- check-table:start -->

번호 code 검사 등급 기준
1 check-1 글이 도형, 카드, 알약, 글 상자, 차트 이름 칸 안에 들어간다 오류 잰 글 폭과 줄 수가 칸의 안쪽 크기 이하
2 check-2 글끼리 겹치지 않는다 오류 선 라벨, 그룹 제목, 도형 사각형(이름과 카드를 품음)끼리 겹친 넓이 0(서로 다른 장면에서만 보이는 선 라벨끼리는 함께 보이지 않아 견주지 않는다). 단계별 도형 상태 알약은 자기 도형을 뺀 도형 사각형(이름과 카드를 품음), 선 라벨, 그룹 제목과 겹친 넓이 0. 산점도 점 이름은 차트가 위아래와 좌우로 비켜 놓은 뒤에도 서로 겹친 넓이 0
3 check-3 선이 끝 도형이 아닌 도형과 격자 칸을 지나지 않는다 오류 경로 선분이 다른 도형과 그룹 사각형 안쪽을 지나지 않음. 선 끝이거나 선 끝을 품은 그룹(그 선이 드나드는 그룹)은 제외. 끝 격자 안에서도 어느 칸(빈 자리 제외)의 안쪽도 지나지 않음
4 check-4 선 끝이 연결점 규칙 자리에 있다 오류 배치의 도형별 연결점 규칙과 0.5 이내로 일치. 격자 칸 끝은 그 칸의 테두리
5 check-5 나란한 두 선이 붙지 않는다 오류 다른 두 선의 나란한 선분 사이가 토큰 spacing.1-25 이상. 같은 도형에서 함께 나가거나 함께 들어오는 두 선은 그 도형 쪽 끝 선분(경계에서 첫 꺾임까지)을 보지 않는다. 서로 다른 장면에서만 보이는 두 선(순서 그림 메시지)은 함께 보이지 않아 견주지 않는다
6 check-6 도형끼리 겹치지 않는다 오류 도형과 그룹 사각형끼리 겹친 넓이 0. 그룹과 그 안의 도형, 그룹과 그 안의 그룹은 제외
7 check-7 글 상자가 그림 안에 있고 이름을 가리지 않는다 오류, 경고 이동의 계획 지점(2프레임 간격)마다 정한 글 상자(재생 자리 규칙)가 그림 경계 안이면 통과한다. 점 위아래 어디에도 들어가지 않으면 오류. 글 상자가 그림보다 넓은 경우는 배치가 그림을 넓혀서 생기지 않는다. 글자, 아이콘, 선 라벨과 상태 알약, 카드와 큐 안쪽은 어느 자리에서도 가리지 않고(하드), 도형 윤곽은 박자 이동의 둘째 계획에서만 덮일 수 있다. 박자 이동은 글 상자가 보이는 시간이 점이 보이는 시간의 60%(scale.chip-visible-share) 미만이면 경고(배치가 층 간격과 선 옆 폭을 늘려 다시 배치한 뒤에도 남을 때만). 흐름의 글 상자는 점 위, 아래, 옆으로 비켜도 도형 이름, 부제, 테이블 열, 그룹 제목을 가려 점이 보이는 시간(도형 안을 지나는 구간 제외)의 25% 넘게 숨으면 경고(선 틈보다 넓은 글 상자. 배치가 그 선의 간격을 늘려 다시 배치한 뒤에도 남을 때만). 보이는 글 상자끼리 겹쳐도 경고(흐름과 & 동시 이동은 나중에 출발한 점의 글 상자가 숨어 겹치지 않는다)
8 check-8 같은 글이 두 번 보이지 않는다 경고 이동 글 상자 글과 그 선 라벨이 같은 경우
9 check-9 그림 비율 경고 보이는 가로세로 비율(가로는 내용 폭과 캔버스 폭 중 큰 쪽)이 3 초과 또는 1/3 미만. 가로세로가 모두 캔버스 폭 이하인 그림은 제외
10 check-10 문서 폭에서 읽힘 경고 그림을 캔버스 폭(표준 size.figure-canvas, width wide면 size.figure-canvas-wide)으로 줄였을 때 가장 작은 글이 가장 작은 글 토큰(size.text의 최솟값, 9px) 미만. 내용이 캔버스보다 넓으면 줄이는 비율이 곧 글자 비율이다
11 check-11 쓰지 않는 조용한 선 경고 시간 흐름에서 한 번도 지나지 않는 quiet 선
12 check-12 순서 그림 메모가 겹치지 않는다 오류, 경고 메모가 그림 안에 있고 같은 행 메시지의 화살표와 라벨을 가리지 않으면 통과한다(오류). 다른 참여자의 생명선에 걸치면 경고
13 check-13 선이 그룹 제목 줄을 지나지 않는다 오류 경로 선분이 그룹 제목 줄(제목 글, 아이콘, 배지를 감싼 사각형) 안쪽을 지나지 않음
14 check-14 흐름이 점을 그리고 점 수와 큐 값이 상한 안에 있다 오류, 경고 흐름마다 점이 하나 이상 그려지면 통과한다(장면 끝까지 도착하지 못하면 오류. lost, when, wait가 있는 흐름은 점이 없어도 오류가 아니다). 한 그림의 점이 토큰 scale.flow-dots-max 이하이고(초과하면 경고). 출발 수를 for와 every에서 미리 세어 그림 전체가 scale.flow-dots-max의 열 배를 넘으면 시간표를 만들기 전에 오류다. 큐 값이 0 이상 칸 수(slots) 이하다(음수나 칸 수 초과에 닿으면 경고. 장면 set=이 정한 시작 값도 센다. 그림은 음수를 0칸, 초과를 가득 찬 칸으로 그린다). 값 글자의 길이는 제한하지 않는다
<!-- check-table:end -->
  • 3번, 4번, 5번이 실패하면 구조 그림은 줄 바꿈 없는 안전 배치로 한 번 더 그려 실패가 줄면 그 배치를 쓰고, aspect를 적었다면 무시했다고 경고한다(배치 그림 비율). 10번 경고의 고치는 방법은 aspect를 적었으면 그 줄을 지우라고 알리고, 아니면 방향 down이나 그룹 방향을 권한다.
  • 2번과 3번은 멈춘 SVG 상태(모든 선 보임) 하나에서 검사한다. 박자마다 보이는 선은 이 상태의 일부이고, 카드 칸 크기는 가장 큰 내용에 맞춰 고정이라 박자마다 자리가 바뀌지 않기 때문이다.
  • 9번은 flow, state, data에만 적용한다. 문서 폭 안에 드는 그림은 줄어들지 않고 그대로 보이므로 비율을 보지 않는다. 도형 둘을 이은 그림에 aspect를 넣으면 오히려 선이 꺾이기 때문이다. 순서 그림과 차트는 원본에서 비율을 바꿀 수단이 없기 때문이다. 기준(3과 1/3)은 배치와 같다.
  • 5번에서 같은 도형 가까이의 끝 선분을 빼는 것은, 한 도형에서 선이 여럿 나가는 그림이 연결점 근처에서 나란히 붙어 있는 모양이 자연스럽기 때문이다. 서로 다른 도형 사이 선끼리와 첫 꺾임 뒤의 선분은 그대로 본다.
  • 14번의 큐 경고는 값이 0 미만이거나 slots를 넘을 때 큐마다 아래쪽과 위쪽 한 번씩 낸다. 그림은 음수를 0칸, 초과를 가득 찬 칸으로 그리므로 그림은 깨지지 않지만, 그 값은 원본이 잘못 셌거나 칸 수가 모자란 신호라 경고로 알린다. 새 번호를 만들지 않고 14번에 넣은 이유는, 같은 값 줄(timeline.values)의 변화 목록을 읽고 값이 상한 안에 있는지 보는 같은 종류의 판정이기 때문이다. --strict면 실패다.
  • 14번의 점이 그려지지 않는 흐름 오류는 when, wait, lost가 없는 흐름에만 적용한다. 이 셋이 있는 흐름은 조건과 사라짐 때문에 점이 없을 수 있다(그림 문법).
  • 8번과 11번 경고는 그림 문법이 정한 경고를 이 검사가 한 번만 알리는 것이다.
  • 1번, 4번, 6번과 2번의 그룹 제목끼리, 그룹 제목과 도형 사이는 배치가 지키도록 설계한 조건이다. 실패는 원본 오류가 아니라 이 도구의 버그이고, 메시지에 internal을 붙인다. 예외는 1번의 차트 항목 이름이다. 이름 칸은 토큰 size.chart.label-max까지만 넓어지므로 그보다 긴 이름은 원본 오류다.
  • 차트에는 선과 도형이 없어 1번만 검사한다. 대상은 항목 이름, 히트맵 열 이름, 산점도 점 이름이다.
  • 7번은 박자 이동의 글 상자를 글자, 아이콘, 알약, 카드와 큐 안쪽에 대해서는 하드 조건으로 지키고, 도형 윤곽만 둘째 계획에서 덮일 수 있다. 보이는 시간이 60%를 못 채우면 먼저 배치가 지나는 선의 층 간격과 선 옆 폭을 늘려 다시 배치하고(그룹 제목과 끝 라벨은 그 옆 폭 밖에 선다. 배치 7단계), 그래도 남을 때만 경고한다. 이 경고는 글을 지우거나 이동 시간을 바꾸지 않는다.
  • 5번과 2번의 선 라벨 견줌은 같은 장면에서 함께 보이는 선만 대상이다. 서로 다른 장면에서만 보이는 순서 그림 메시지는 같은 행을 써도 겹침이 아니다. 같은 장면의 붙은 선과 장면 번호가 없는 그래프의 선은 늘 견준다.
  • 좁은 배치는 HTML을 만들 때(render --html, gallery) 함께 만들고 같은 검사를 받는다. 넓은 배치가 통과해도 좁은 폭(272)에서 글이 칸에 들지 않으면(예: 열이 많은 히트맵의 칸 폭, 한 좌표에 몰린 긴 산점도 이름) 1번이나 2번 오류로 HTML 만들기가 줄 번호와 함께 끝난다. 이때 check와 SVG 출력은 성공할 수 있다. 원본에서 이름을 줄이거나 열 수를 줄여 푼다.

메시지

  • 형식은 그림 문법 오류 형식과 같다. 줄 번호는 문제를 일으킨 줄들 가운데 첫 줄이고, 나머지 줄 번호는 (line N)으로 괄호에 넣는다.
  • 고치는 방법은 원본에서 바꿀 수 있는 것만 적는다. 라벨 줄이기, 그룹 방향 바꾸기, aspect 넣기다.
  • --json이면 진단마다 { "file", "line", "message", "severity", "code", "column" } 한 줄을 표준 출력에 쓴다. severity는 error나 warning이고, code는 검사 번호이면 check-7처럼, 문법 진단은 syntax 등이다(그림 문법의 진단 모양). 이 밖의 필드는 없다. 함께 문제를 일으킨 줄은 메시지 안 (line N)에 있다. 다른 도구가 한 줄씩 읽어 처리하게 하기 위해서다.

요구사항

시험 칸이 "검증 요구사항, 미완료"인 항목은 직접 확인하는 자동 시험이 아직 확인되지 않았다는 뜻이다.

요구사항 검증 계획
검사 항목마다 실패하는 원본에서 그 항목 메시지를 낸다. 검증 요구사항, 미완료. 일부러 실패하게 만든 원본으로 항목을 사람이 확인한다
박자 이동의 글 상자가 글자, 아이콘, 알약, 카드 안쪽을 가리지 않고, 윤곽만 둘째 계획에서 덮이며, 예제가 strict로 7번 경고 없이 만들어진다. 서로 다른 장면에서만 보이는 선 쌍은 5번과 2번이 견주지 않는다. 예제의 strict 빌드는 test/examples.test.js. 나머지는 검증 요구사항, 미완료
큐 값이 0 미만이거나 slots를 넘으면 14번 경고를 내고, 0과 slots는 경고하지 않는다. test/kinds.test.js(K-queue)
lost, when, wait가 있는 흐름은 점이 하나도 그려지지 않아도 14번 오류가 없고, 없는 흐름은 오류다. 검증 요구사항, 미완료
단계별 도형 상태 알약이 이름, 다른 도형, 선 라벨, 그룹 제목을 가리면 상태를 적은 단계 줄에 2번 오류를 낸다. 검증 요구사항, 미완료
14번이 단계 set=이 정한 시작 값의 글자 수와 큐 칸 수도 센다. 검증 요구사항, 미완료
모든 예제가 오류 없이 검사를 통과한다. test/examples.test.js, 예제 전체에 check 실행
오류가 있으면 그림 파일을 쓰지 않는다. test/cli.test.js(L2)
--json 출력이 한 줄에 메시지 하나이고 필드가 여섯 개다. test/cli.test.js(L2)
check는 파일을 쓰는 render 전용 선택 사항(--html, --static, --out, --scene)과 --title을 받지 않고 사용법 오류(종료 2)로 거절한다. test/cli.test.js(L3)

단점

  • 선과 도형, 그룹 쌍을 모두 비교해서 도형과 선이 많으면 검사 시간이 늘어난다.
  • 9번, 10번 경고 기준은 화면을 보고 정한 값이라 문서 폭이 다른 곳에서는 맞지 않을 수 있다.

미해결 질문

  • 10번 기준 9px가 GitHub README와 설계 문서 폭에서 읽기에 충분한가. 예제 그림을 두 곳에 올려 정한다.