SHA256
200 lines
11 KiB
Typst
200 lines
11 KiB
Typst
// 연구실 실습일지 양식 (원본 docx 1페이지 복제 + 템플릿 함수)
|
||
// 원본: 연구실실습일지작성양식_컴퓨터소프트웨어실습HY-UP(실용연구실습)2_(1-15회차).docx
|
||
//
|
||
// 이 파일을 직접 컴파일하면 빈 양식이 나오고,
|
||
// #import "연구실실습일지작성양식.typ": 실습일지
|
||
// #실습일지(소속대학: "…", 일시: "…", 내용: […])
|
||
// 처럼 호출하면 채워진 실습일지 1페이지가 나온다 (예: day1.typ).
|
||
//
|
||
// 모든 요소는 절대 좌표(place) 배치 — 글꼴에 따라 줄이 바뀌지 않는다.
|
||
// 수치는 docx의 twips/EMU → pt 환산값:
|
||
// 페이지 595×841pt / 배경 이미지 (0, 30.8) 594.88×810.2
|
||
// 제목 상자 (45.35, 73.7) 504.35×42.6, 테두리 1.44pt
|
||
// 표: (46.1, 143.15) 폭 505.75, 높이 630.15 (4행 높이 34.6pt는 원본 그대로,
|
||
// 원본에선 '3시간'이 2줄로 접혀 늘어난 높이지만 렌더는 1줄로 한다)
|
||
|
||
// kr-font: report/fonts/ChosunSm.ttf = 조선신명조 풀 폰트(17,147 글리프).
|
||
// typst는 패밀리를 Mac 플랫폼(1/0) name 레코드로만 매칭하는데 원본은 이 레코드가
|
||
// 빈 문자열이라(Windows 레코드의 '조선신명조'는 무시됨) 폰트에 'ChosunSm'으로 기입해 둠.
|
||
// Regular face만 존재 — 굵게/기울임은 아래 show strong/emph에서 처리.
|
||
#let kr-font = ("ChosunSm", "NanumGothic")
|
||
|
||
// 코드 폰트: 한글 지원 모노스페이스 우선(주석 한글도 모노폭), 없는 글리프는 kr-font로 폴백
|
||
#let code-font = ("NanumGothicCoding", "DejaVu Sans Mono", "Liberation Mono")
|
||
|
||
#let X0 = 46.1pt // 표 왼쪽 (좌 여백 37 + 표 들여쓰기 9.1)
|
||
#let Y0 = 143.15pt // 표 위쪽 (외곽 테두리 기준)
|
||
#let BX = (0pt, 100.75pt, 264.35pt, 339.9pt, 362.45pt, 419.05pt, 433.2pt, 505.75pt) // 열 경계
|
||
#let RY = (0pt, 23.05pt, 43.25pt, 63.55pt, 98.15pt, 121.7pt, 533.9pt, 557.6pt, 630.15pt) // 행 경계
|
||
|
||
// 굵은 라벨 / 값 (10pt). trk = Word 자간(spc, twips→pt)
|
||
#let lab(body, trk: 0pt) = text(font: kr-font, size: 10pt, weight: "bold", tracking: trk, body)
|
||
#let val(body, trk: 0pt) = text(font: kr-font, size: 10pt, tracking: trk, body)
|
||
|
||
// 셀 안내선: 가는 내부선 0.5pt (Word sz=4), 굵은 선 1.5pt (Word sz=12)
|
||
#let hline(i, j, y, w) = place(dx: X0 + BX.at(i), dy: Y0 + y, line(length: BX.at(j) - BX.at(i), stroke: w * 1pt + black))
|
||
#let vline(x, y0, y1, w) = place(dx: X0 + x, dy: Y0 + y0, line(angle: 90deg, length: y1 - y0, stroke: w * 1pt + black))
|
||
|
||
// 셀 텍스트: (x0, x1) = 셀 좌우, r = 행 번호. 셀 정중앙 배치
|
||
#let cell-text(x0, x1, r, body, li: 5.4pt, ri: 5.4pt) = place(
|
||
dx: X0 + x0, dy: Y0 + RY.at(r),
|
||
box(width: x1 - x0, height: RY.at(r + 1) - RY.at(r),
|
||
inset: (top: 0pt, bottom: 0pt, left: li, right: ri),
|
||
align(center + horizon, body)))
|
||
|
||
#let cell-left(x0, x1, r, body, li: 5.4pt, ri: 5.4pt) = place(
|
||
dx: X0 + x0, dy: Y0 + RY.at(r),
|
||
box(width: x1 - x0, height: RY.at(r + 1) - RY.at(r),
|
||
inset: (top: 0pt, bottom: 0pt, left: li, right: ri),
|
||
align(left + horizon, body)))
|
||
|
||
// 날짜 칸의 탭 정지 토큰 (원본 탭: 1210/1810/2511/3909 twips, 문단 들여쓰기 611 기준 상대 위치)
|
||
// 오프셋 기준점 = 셀 왼쪽 + 셀 여백 5.4 + 문단 들여쓰기 30.55 = +35.95
|
||
#let date-token(r, x-offset, body) = place(
|
||
dx: X0 + 100.75pt + 35.95pt + x-offset, dy: Y0 + RY.at(r),
|
||
box(height: RY.at(r + 1) - RY.at(r), inset: (top: 0pt, bottom: 0pt, left: 0pt, right: 0pt),
|
||
align(horizon, body)))
|
||
|
||
// ── 템플릿 함수 ────────────────────────────────────────────────────
|
||
// 소속대학/소속학과/학번/성명/의견: 문자열(빈 값이면 원본처럼 빈 칸)
|
||
// 일시: none이면 빈 양식의 '년 월 일 시 부터 ~ 시 까지' 스캐폴드, 문자열이면 그대로 출력
|
||
// 내용: none이면 빈 칸, content/문자열이면 실습 내용 칸(왼쪽 위)에 출력
|
||
#let 실습일지(소속대학: "", 소속학과: "", 학번: "", 성명: "", 일시: none, 내용: none, 의견: "") = {
|
||
set page(width: 595pt, height: 841pt, margin: 0pt)
|
||
set par(spacing: 0pt)
|
||
set text(lang: "ko", cjk-latin-spacing: none)
|
||
|
||
// 코드 블록 스타일 (내용 칸의 ``` 코드): 둥근 박스 + 연한 배경 + 테두리
|
||
show raw.where(block: true): it => block(
|
||
width: 100%,
|
||
above: 6pt,
|
||
below: 6pt,
|
||
fill: rgb("#F6F8FA"),
|
||
stroke: 0.5pt + rgb("#C9D1D9"),
|
||
radius: 3pt,
|
||
inset: (x: 8pt, y: 6pt),
|
||
text(font: code-font + kr-font, size: 8.5pt, it))
|
||
// 인라인 코드: 옅은 배경만
|
||
show raw.where(block: false): it => box(
|
||
fill: rgb("#EEF1F4"),
|
||
inset: (x: 3pt, y: 0pt),
|
||
radius: 2pt,
|
||
text(font: code-font + kr-font, size: 9pt, it))
|
||
|
||
// *굵게*: 조선신명조엔 Bold face가 없으므로 같은 조선일보 서체 계열인
|
||
// 조선굵은명조(report/fonts/ChosunKm.ttf, name 테이블 동일 패치)로 렌더한다
|
||
show strong: it => text(font: ("ChosunKm",) + kr-font, it)
|
||
// box로 감싸지 않으면 skew가 문단을 분리해 par(spacing: 0pt) 하에서 줄이 겹친다
|
||
show emph: it => box(skew(ax: -12deg, text(font: ("Liberation Serif",) + kr-font, it)))
|
||
[
|
||
// 배경 (한양대 양식 이미지)
|
||
#place(dx: 0pt, dy: 30.8pt, image("hy-bg.png", width: 594.88pt, height: 810.2pt))
|
||
|
||
// 제목 상자
|
||
#place(dx: 45.35pt, dy: 73.7pt,
|
||
rect(width: 504.35pt, height: 42.6pt, stroke: 1.44pt + black, fill: none, inset: 0pt,
|
||
align(center + horizon,
|
||
text(font: kr-font, size: 25pt, weight: "bold")[연구실]
|
||
+ text(font: kr-font, size: 25pt, weight: "bold", tracking: 3pt)[ ]
|
||
+ text(font: kr-font, size: 25pt, weight: "bold", tracking: -0.2pt)[실습일지])))
|
||
|
||
// 표 테두리: 가로선 (바깥 1.5pt, 내부 0.5pt — 학번↔교과목명 경계만 1.5pt)
|
||
#hline(0, 7, 0pt, 1.5)
|
||
#hline(0, 7, 23.05pt, 0.5)
|
||
#hline(0, 7, 43.25pt, 1.5)
|
||
#hline(0, 7, 63.55pt, 0.5)
|
||
#hline(0, 7, 98.15pt, 0.5)
|
||
#hline(0, 7, 121.7pt, 0.5)
|
||
#hline(0, 7, 533.9pt, 0.5)
|
||
#hline(0, 7, 557.6pt, 0.5)
|
||
#hline(0, 7, 630.15pt, 1.5)
|
||
// 세로선: 셀 경계가 실제로 존재하는 구간만
|
||
#vline(0pt, 0pt, 630.15pt, 1.5) // 왼쪽 외곽
|
||
#vline(505.75pt, 0pt, 630.15pt, 1.5) // 오른쪽 외곽
|
||
#vline(100.75pt, 0pt, 630.15pt, 0.5) // 라벨 열 오른쪽 (전 행)
|
||
#vline(264.35pt, 0pt, 43.25pt, 0.5) // 소속대학 값 | 소속학과 (1–2행)
|
||
#vline(339.9pt, 0pt, 98.15pt, 0.5) // 소속학과 값 | 수업번호 열 (1–4행)
|
||
#vline(362.45pt, 557.6pt, 630.15pt, 0.5) // 의견 칸 | 담당 교수 확인 (8행)
|
||
#vline(419.05pt, 43.25pt, 98.15pt, 0.5) // 수업번호 칸 | 11725 칸 (3–4행)
|
||
#vline(433.2pt, 557.6pt, 630.15pt, 0.5) // 담당 교수 확인 | (인) (8행)
|
||
|
||
// 1행: 소속대학 / 소속학과
|
||
#cell-text(0pt, 100.75pt, 0, lab(trk: -0.2pt)[소속대학])
|
||
#cell-text(264.35pt, 339.9pt, 0, lab(trk: -0.2pt)[소속학과])
|
||
#if 소속대학 != "" [#cell-left(100.75pt, 264.35pt, 0, val(소속대학))]
|
||
#if 소속학과 != "" [#cell-left(339.9pt, 505.75pt, 0, val(소속학과))]
|
||
|
||
// 2행: 학번 / 성명
|
||
#cell-text(0pt, 100.75pt, 1, lab(trk: -0.25pt)[학번])
|
||
#cell-text(264.35pt, 339.9pt, 1, lab(trk: -0.25pt)[성명])
|
||
#if 학번 != "" [#cell-left(100.75pt, 264.35pt, 1, val(학번))]
|
||
#if 성명 != "" [#cell-left(339.9pt, 505.75pt, 1, val(성명))]
|
||
|
||
// 3행: 교과목명 / 컴퓨터소프트웨어실습… / 수업번호 / 11725
|
||
#cell-text(0pt, 100.75pt, 2, lab(trk: -0.2pt)[교과목명])
|
||
#cell-left(100.75pt, 339.9pt, 2,
|
||
val(trk: -0.1pt)[컴퓨터소프트웨어실습HY-UP(실용연구실습)2], li: 11pt)
|
||
#cell-text(339.9pt, 419.05pt, 2, lab(trk: -0.2pt)[수업번호])
|
||
#cell-left(419.05pt, 505.75pt, 2, val(trk: -0.1pt)[11725], li: 10.4pt)
|
||
|
||
// 4행: 실습 일시 / 실습진행시간 / 3시간(1줄 — 높이만 원본 그대로 34.6pt)
|
||
#cell-text(0pt, 100.75pt, 3, lab[실습] + lab(trk: -0.1pt)[ ] + lab(trk: -0.25pt)[일시])
|
||
#if 일시 == none [
|
||
// 빈 양식: 원본 탭 정지 스캐폴드
|
||
#date-token(3, 0pt, val(trk: -0.5pt)[년])
|
||
#date-token(3, 29.95pt, val[월])
|
||
#date-token(3, 59.95pt, val[일])
|
||
#date-token(3, 95pt, val[시] + val(trk: -0.15pt)[ ] + val[부터] + val(trk: -0.15pt)[ ] + val[\~])
|
||
#date-token(3, 164.9pt, val[시] + val(trk: -0.1pt)[ ] + val(trk: -0.25pt)[까지])
|
||
] else [
|
||
#cell-left(100.75pt, 339.9pt, 3, val(일시), li: 35.95pt)
|
||
]
|
||
#cell-text(339.9pt, 419.05pt, 3, lab(trk: -0.1pt)[실습진행시간])
|
||
#cell-text(419.05pt, 505.75pt, 3, val(trk: -0.25pt)[3시간])
|
||
|
||
// 5행: 실습 장소
|
||
#cell-text(0pt, 100.75pt, 4, lab[실습] + lab(trk: -0.1pt)[ ] + lab(trk: -0.25pt)[장소])
|
||
#cell-left(100.75pt, 505.75pt, 4,
|
||
val[IT/BT] + val[관] + val(trk: -0.45pt)[ ] + val[811호와] + val(trk: -0.3pt)[ ] + val(trk: -0.2pt)[코드트리],
|
||
li: 10.5pt)
|
||
|
||
// 6행: 실습 내용 (라벨은 Word vAlign=center — 세로 중앙) + 기재 내용(왼쪽 위)
|
||
#cell-text(0pt, 100.75pt, 5, lab[실습] + lab(trk: -0.1pt)[ ] + lab(trk: -0.25pt)[내용])
|
||
#if 내용 != none [
|
||
#place(dx: X0 + 100.75pt, dy: Y0 + RY.at(5),
|
||
box(width: 405pt, height: 412.2pt,
|
||
inset: (top: 5.4pt, bottom: 5.4pt, left: 5.4pt, right: 5.4pt),
|
||
align(top + left, {
|
||
// 전역 par(spacing: 0pt)를 상속하면 문단/목록 사이 간격이 사라지므로 내용 칸에서만 복구
|
||
set par(spacing: 0.8em)
|
||
text(font: kr-font, size: 10pt, 내용)
|
||
})))
|
||
]
|
||
|
||
// 7행: 담당 교수명 / 박희진
|
||
#cell-text(0pt, 100.75pt, 6, lab[담당] + lab(trk: -0.2pt)[ ] + lab(trk: -0.25pt)[교수명])
|
||
#cell-left(100.75pt, 505.75pt, 6, val(trk: -0.25pt)[박희진], li: 10.5pt)
|
||
|
||
// 8행: 담당교수 의견 / 담당 교수 확인 / (인)
|
||
#cell-text(0pt, 100.75pt, 7, lab[담당교수] + lab(trk: -0.3pt)[ ] + lab(trk: -0.25pt)[의견])
|
||
#if 의견 != "" [#cell-left(100.75pt, 362.45pt, 7, val(의견))]
|
||
// 담당 교수 확인: 원본 들여쓰기 때문에 '담당 교/수 확인'으로 접히는 양식 결함을
|
||
// '담당 교수' / '확인' 2줄 중앙 정렬로 명시 배치
|
||
#cell-text(362.45pt, 433.2pt, 7,
|
||
lab[담당] + lab(trk: -1.25pt)[ ] + lab[교수] + linebreak() + lab(trk: -0.3pt)[확인])
|
||
#cell-text(433.2pt, 505.75pt, 7, lab(trk: -0.25pt)[(인)])
|
||
|
||
// 빨간 안내문
|
||
#let r(body, trk: 0pt) = text(font: kr-font, size: 11pt, weight: "bold", fill: red, tracking: trk, body)
|
||
#place(dx: 42.45pt, dy: 774pt,
|
||
r[※] + r(trk: -0.1pt)[ ] + r[1회차에] + r(trk: -0.05pt)[ ] + r[3시간,] + r(trk: 0.1pt)[ ]
|
||
+ r[15회차] + r(trk: -0.05pt)[ ] + r[이상의] + r(trk: 0.1pt)[ ] + r[연구실] + r(trk: -0.05pt)[ ]
|
||
+ r[실습일지] + r(trk: 0.1pt)[ ] + r[작성] + r(trk: 0.1pt)[ ] + r[필수] + r(trk: 0.1pt)[ ]
|
||
+ r[(] + r(trk: -0.05pt)[ ] + r[한학기] + r(trk: -0.05pt)[ ] + r[45시간] + r(trk: -0.05pt)[ ]
|
||
+ r[실습] + r(trk: -0.05pt)[ ] + r[필수] + r(trk: -0.05pt)[ ] + r(trk: -0.5pt)[)])
|
||
]
|
||
}
|
||
|
||
// 이 파일을 직접 컴파일하면 빈 양식
|
||
#실습일지()
|