본문으로 건너뛰기

Playground

브라우저에서 프레젠테이션을 작성하면 슬라이드가 바로 따라옵니다. WebAssembly로 컴파일한 go-slides에 자동 완성, 도움말, 예제를 갖췄습니다.

Playground 열기 →

Playground는 WebAssembly로 컴파일되어 브라우저에서 실행되는 go-slides v0.18.0 그 자체입니다. 왼쪽에 프레젠테이션을 입력하면 오른쪽에 슬라이드가 따라 나타납니다. 프레젠테이션도, 공유 링크도 서버로 전송되지 않습니다.

Playground 자체의 인터페이스(리본, 도움말, 메시지)는 페이지의 언어로 표시됩니다. 한국어는 /ko/playground/를 열면 되고, 이 사이트의 열두 언어 모두 마찬가지입니다. 페이지의 언어 선택기로 바꿀 수 있으며 선택은 이 브라우저에 저장됩니다. 언어가 지정된 링크가 항상 우선합니다. 예제 프레젠테이션은 영어로 유지됩니다. 우크라이나어, 러시아어, 중국어, 일본어, 한국어는 페이지가 해당 언어에 한해 내려받는 Noto Sans 부분집합(0.06~2.3 MiB)으로 그려집니다.

제공 기능

  • 모든 슬라이드의 실시간 미리 보기: 페이지 스레드와 분리된 Web Worker에서 렌더링하므로 입력이 미리 보기 때문에 멈추지 않습니다. 슬라이드를 클릭하면 편집기가 해당 줄로 이동하고, 캐럿을 옮기면 미리 보기가 해당 슬라이드로 스크롤됩니다.

  • 슬라이드 쇼: 키보드, 화면 컨트롤러, 전환 효과를 갖춘 실제 발표 화면입니다.

  • 발표자 보기: Present(또는 슬라이드 쇼에서 p)를 누르면 두 번째 창에 열립니다. 현재 슬라이드, 다음 단계, 발표자 노트(프레젠테이션의 <!-- comments -->), 시계, 타이머가 표시됩니다. 화살표 키, Space, Home, End는 어느 창에서나 동작하며, 프레젠테이션을 편집할 때도 두 창이 서로 연동됩니다. 창이 열리지 않으면 이 사이트의 팝업을 허용하십시오. 개요 보기(o)는 내려받은 페이지에서만 쓸 수 있습니다.

  • 입력 중 자동 완성: 디렉티브 키(주석 안에서는 _로 시작하는 스폿 디렉티브), kind, theme, size, paginate의 값, 그리고 {{ }} 안의 템플릿 함수와 데이터 필드.

  • 캐럿 위치에 있는 요소의 도움말: 디렉티브, kind(슬라이드 유형, 설정하는 내용), 템플릿 함수. 도움말 창에서 이 문서로 연결되는 링크도 제공합니다. v0.16.0부터 디렉티브 도움말은 인터페이스 언어를 따르며, 11개 언어를 지원합니다.

  • 해당 줄에 표시되는 문제: 템플릿, YAML, HCL 오류가 편집기에서 강조되고 그 아래에 나열되며, 미리 보기는 마지막으로 렌더링에 성공한 프레젠테이션을 유지합니다.

  • 예제: 환영 프레젠테이션, 슬라이드를 생성하는 템플릿, 슬라이드 kind, HCL 프런트 매터, 테마와 스폿 디렉티브, 그리고 수식, 이미지, 배경(![bg], 화면을 나누는 ![bg left:40%], 필터).

  • 파일: 편집기 왼쪽 패널은 프레젠테이션의 프로젝트이며, 명령과 VS Code 확장이 읽는 구조와 같습니다: deck.md, slides.yaml, themes/, kinds/, media/.

    • 파일을 클릭하면 편집할 수 있습니다. 편집기는 파일 언어(Markdown, YAML, HCL, JSON, CSS)에 따라 색을 입히고 문제를 표시합니다.
    • 마우스 오른쪽 버튼(또는 Shift+F10)으로 New File, New Folder, Rename(F2), Delete(먼저 확인), New theme / New kind를 실행합니다. 파일을 폴더로 끌어다 놓으면 이동합니다. 키보드 조작은 미리 입력 검색을 포함해 WAI-ARIA 트리 패턴을 따릅니다.
    • Project ▸ New theme은 themes/my-gaia.css(또는 default, uncover 기반)를 만듭니다. 기본 제공 테마의 @import와 직접 추가하는 규칙으로 이루어지며, Theme 목록에 추가됩니다. New kind와 New data file도 템플릿에서 시작합니다. 각각 slides.yaml에 등록되므로 slides build deck.md가 찾을 수 있습니다.
    • **Project ▸ Download project (.zip)**은 전체를 저장합니다. 압축을 풀면 slides build deck.md로 빌드할 수 있습니다. Open project는 .zip이나 폴더를 다시 불러옵니다. 자기 폴더 밖으로 나가는 아카이브(.., 절대 경로), 파일이 256개를 넘거나 한 파일이 8 MiB를 넘는 아카이브, 압축 해제 시 100배 넘게 커지는 아카이브는 거부됩니다.
    • 모든 내용은 초안과 함께 이 브라우저에 보관됩니다. 프로젝트는 최대 64 MiB까지 담을 수 있으며, 파일 목록 아래 줄에 사용량이 표시됩니다.
  • 미디어: 이미지, 동영상, 소리를 편집기에 끌어다 놓거나 붙여 넣으면 media/에 들어가고 프레젠테이션에서 ![](media/photo.png)처럼 참조됩니다. 패널의 폴더에 파일을 끌어다 놓으면 그 폴더에 들어갑니다. 프레젠테이션은 작고 읽기 쉬운 상태로 유지되며, 아무것도 업로드되지 않습니다. 미리 보기 샌드박스는 제한을 풀지 않고도 미디어를 불러옵니다(페이지가 바이트를 직접 넘겨줍니다). Save as ▸ HTML page는 미디어를 페이지 안에 넣습니다. https: 이미지도 쓸 수 있지만 브라우저가 해당 서버에서 가져오므로 그 서버에 사용자의 주소가 노출됩니다. 미리 보기는 리퍼러를 보내지 않습니다.

  • 크기 조절 가능한 창: 파일 패널, 편집기, 슬라이드 썸네일, 미리 보기, 도움말은 끌어서 움직일 수 있는 막대로 나뉩니다(막대 위에서는 포인터가 크기 조절 커서로 바뀝니다). 막대 옆의 창이 공간을 차지하고 나머지 창은 크기를 유지합니다. 막대를 더블클릭하거나 막대에서 Enter를 누르면 창을 접었다가 다시 펼칩니다. 키보드에서는 F6으로 막대 사이를 이동하고, 화살표 키로 막대를 16 px씩 옮기며, Home과 End로 막대 앞의 창을 최소·최대 크기로 만들고, Escape로 편집기로 돌아갑니다. View 탭으로 창을 끌 수도 있습니다. 직접 설정한 크기는 초안과 함께 이 브라우저에 보관되며, 기본 크기(190, 168, 280 px, 편집기와 미리 보기가 나머지를 6 대 5로 나눔)는 저장되지 않습니다.

  • 서식: Format 탭이 Markdown을 대신 편집해 주며, 한 번 누를 때마다 Undo 한 단계가 됩니다.

    • 텍스트: Bold, Italic, Strikethrough, Inline code는 선택 영역이나 캐럿 위치의 단어에 적용되며 켜고 끄는 방식입니다(Ctrl+B, Ctrl+I, Ctrl+Shift+X, Ctrl+E, Mac에서는 Cmd). 캐럿이 해당 표식 안에 있으면 버튼이 눌린 상태로 표시됩니다. Markdown에는 밑줄이 없으므로 Underline(Ctrl+U)은 텍스트를 <u>…</u>로 감쌉니다. 이 태그는 Marp의 기본 HTML 허용 목록에 포함되므로 원시 HTML을 꺼도 동작합니다.
    • 문단: Heading 1~3(Ctrl+Alt+1..3), 글머리 기호(Ctrl+Shift+8), 번호 매기기 (Ctrl+Shift+7), 인용은 선택한 줄에 적용되며 켜고 끄는 방식입니다. 수평선은 <hr> 태그입니다. ---, ***, ___는 Marp에서 모두 새 슬라이드를 시작하기 때문입니다.
    • 표: 격자에서 열과 행 수를 고릅니다. 표 안에 캐럿이 있으면 행이나 열을 추가·삭제하고 열 정렬(:--, :-:, --:)을 지정할 수 있으며, 편집할 때마다 표가 정렬된 형태로 다시 작성됩니다.
    • 슬라이드 텍스트 왼쪽·가운데·오른쪽 정렬은 현재 슬라이드에 <style scoped> 블록을 씁니다. Marp에는 정렬 문법이 없고 style 속성은 기본 HTML 허용 목록을 통과하지 못하지만, scoped 블록은 통과합니다. 따라서 원시 HTML을 꺼도 동작하며 미리 보기, HTML 페이지, PDF에 반영됩니다.
    • 링크(Ctrl+K)는 url이 선택된 상태로 [text](url)을 씁니다.
  • 프런트 매터 키의 구문 강조: 깊이와 관계없이 YAML({a: 1} 매핑 포함)과 HCL 모두에서 강조합니다.

  • 테마 선택기: default, gaia, uncover, 프로젝트의 테마(themes/*.css), 프레젠테이션이 정의한 테마(<style> 안의 /* @theme name */). 선택하면 프런트 매터(YAML 또는 HCL)에 theme:를 쓰므로 공유 링크에도 유지되며, 프런트 매터를 편집하면 선택기도 따라 바뀝니다.

  • 입력하는 동안 미리 보기가 위치를 유지합니다. 바뀐 슬라이드만 교체되며, 테마를 바꾸면 미리 보기가 같은 슬라이드에서 다시 열립니다.

  • 공유 링크: 프레젠테이션이 링크 자체(# 부분에 압축된 형태)에 담기므로 링크를 열면 프레젠테이션이 열립니다. 링크에는 압축 후 64 KiB까지, 프레젠테이션만 담을 수 있습니다. 프로젝트에 그 밖의 파일(테마, kind, 미디어)이 있으면 Share가 이를 알리고 .zip을 제안합니다.

  • 다른 이름으로 저장:

    • slides deck.md가 쓰는 것과 같은 HTML 페이지
    • PDF(벡터, 텍스트 선택 가능, 개요 포함)
    • 편집 가능한 PowerPoint 또는 OpenDocument 프레젠테이션

    모두 slides --pdf, --pptx, --odp와 같은 코드로 브라우저에서 만들어집니다. 슬라이드 100장 벤치마크 프레젠테이션의 PDF는 명령으로 만든 것과 바이트 단위까지 같습니다. 처음 내보낼 때 진행률 표시와 함께 내보내기 엔진(약 5 MiB, 한 번만 받으며 다음 업데이트까지 브라우저가 보관)을 내려받고, 받는 동안 컴파일합니다. 그다음에는 슬라이드가 그리는 글꼴만 내려받습니다. 3 MB/s 회선에서 환영 프레젠테이션의 첫 PDF는 3초 안에 완성됩니다. 그 뒤 슬라이드 100장 프레젠테이션은 약 3초가 걸립니다. https: 이미지는 서버가 허용할 때(CORS)만 포함되며, data: 이미지는 항상 포함됩니다.

  • 초안이 보관됩니다:

    • 프레젠테이션은 입력하는 동안 이 브라우저에 저장되며(IndexedDB, 이 사이트 전용), 새로 고침하면 다시 나타납니다. 어디에도 전송되지 않습니다. 프로젝트의 텍스트 파일(테마, kind, 데이터, slides.yaml)도 같은 방식으로 보관되며, 입력 직후 탭을 닫아도 유지됩니다. 미디어는 끌어다 놓는 즉시 저장됩니다.
    • 공유 링크를 열면 해당 프레젠테이션이 열리고 내 초안은 보관됩니다. Draft ▸ Restore my draft로 되돌릴 수 있습니다.
    • 예제를 열거나, Draft ▸ Reset to the example(먼저 확인)을 실행하거나, 다른 탭을 써도 초안은 지워지지 않습니다. Draft ▸ Restore replaced로 다시 바꿀 수 있습니다.
    • Draft ▸ Forget my drafts는 저장된 모든 내용을 지웁니다.

모든 내보내기는 미리 보기에 표시된 프로젝트를 렌더링합니다. slides.yaml, 테마, kind, 데이터 파일, 미디어가 포함되며, 미디어는 문서 안에 들어갑니다.

이미지 파일 출력(slides --images)은 브라우저에서 만들 수 없습니다. 명령이나 VS Code 확장을 사용하십시오.

실행 취소, 다시 실행, 버전

Undo(실행 취소)와 Redo(다시 실행)는 Home 탭에 있으며 Ctrl+Z, Ctrl+Shift+Z, Ctrl+Y(Mac에서는 Cmd)로도 쓸 수 있습니다. 먼저 표시 중인 파일의 마지막 편집을 되돌리고 (파일마다 자기 기록이 있습니다), 그다음에는 프로젝트 전체에 대한 마지막 작업을 되돌립니다. 고른 예제, Reset, 연 .zip 이나 폴더, 복원한 초안, 삭제하거나 이름을 바꾼 파일이나 폴더, 복원한 버전이 그 대상입니다. Redo는 Undo를 눌렀을 때의 상태로 모두 되돌립니다.

버전은 프로젝트 전체를 이 브라우저에 보관하며, 어디로도 전송하지 않습니다. 입력을 멈춘 뒤 잠시 후(최대 2분마다), 프로젝트 전체에 대한 작업 전마다, 내보내기와 공유 링크를 만들 때마다 버전이 하나 보관됩니다. **Save version…**은 이름을 붙여 하나를 보관합니다. Home ▸ Versions는 Versions 창을 엽니다.

  • Preview는 버전을 미리보기에 보여 줍니다.
  • Compare with now는 각 파일의 변경 사항을 줄 단위로, 인라인 또는 나란히 보여 줍니다. F7과 Shift+F7로 변경 사항 사이를 이동합니다.
  • Restore는 버전을 되돌려 놓습니다. Undo로 복원을 취소할 수 있습니다.
  • Delete는 버전을 삭제합니다.

보관되는 것: 가장 최근의 자동 버전 20개, 그다음 하루 동안은 한 시간에 하나, 한 달 동안은 하루에 하나. 이름 붙인 버전은 삭제할 때까지 남습니다(최대 50개). 모든 버전을 합쳐 최대 96 MiB이며, 바뀌지 않은 파일은 한 번만 저장됩니다. 브라우저 저장 공간이 가득 차면 가장 오래된 자동 버전부터 사라집니다.

GitHub

Home ▸ History ▸ GitHub는 GitHub 저장소에서 발표 자료 폴더를 불러오고, 변경 사항을 풀 리퀘스트로 제안하는 창을 엽니다. 다음을 입력합니다.

  • 저장소 (소유자/이름)
  • 브랜치 (비우면 기본)
  • 폴더 (비우면 루트): 폴더에 deck.md가 있어야 합니다
  • 토큰 (가려서 표시)
  • 이 기기에 기억

토큰은 세분화된 개인 액세스 토큰 (만들기)이며, 선택한 저장소로 제한하고 권한은 Contents 읽기/쓰기와 Pull requests 읽기/쓰기입니다 (Metadata 읽기는 암묵적으로 포함됩니다). 그다음:

  • 연결은 토큰과 저장소를 확인하고, 연결 해제는 토큰을 잊습니다.
  • 불러오기는 프로젝트를 GitHub의 폴더로 바꿉니다. Undo로 되돌릴 수 있으며, 원래 프로젝트는 “GitHub에서” 버전으로 남습니다.
  • **변경 제안…**은 제목을 묻고, 새 브랜치 slides/<제목>-<날짜-시간>을 만들어 풀 리퀘스트를 엽니다. 기존 브랜치나 기본 브랜치에는 절대 쓰지 않습니다. 풀 리퀘스트 열기는 그곳으로 이동합니다.
  • 변경 확인은 GitHub의 더 새로운 버전을 내 버전과 Compare 보기에서 비교합니다. 상대 것 받기는 그것을 불러옵니다.

GitHub에는 프록시를 쓰지 않습니다. playground가 직접 통신합니다.

토큰은 탭의 메모리에만 있고 api.github.com으로만 전송됩니다. 페이지의 Content Security Policy가 다른 호스트를 허용하지 않기 때문입니다. 초안, 버전, 공유 링크, 내보내기에는 저장되지 않으며 슬라이드 미리보기나 렌더링 worker에도 전달되지 않습니다. 이 기기에 기억을 선택하면 연결 해제(또는 Forget my drafts)까지 이 브라우저의 localStorage에 저장됩니다. 위험이 하나 남습니다. playground 페이지 자체에 주입된 스크립트가 토큰을 읽을 수 있다는 점입니다. 필요한 저장소로 제한한 토큰을 쓰세요. 팀에는 토큰을 서버에 두는 자체 호스팅 서버 모드(곧 제공)가 있습니다.

GitLab.com

창에는 forge 목록이 있으며 GitHub와 GitLab.com 중에서 고릅니다. GitLab에서는 범위 api의 개인 액세스 토큰을 입력하거나 GitLab으로 로그인(PKCE를 쓰는 OAuth 인증 코드, 시크릿 없음)을 누릅니다. 로그인하면 페이지가 gitlab.com으로 갔다가 돌아오며 주소는 즉시 정리됩니다. 그 토큰은 이 탭의 메모리에만 있고(이 기기에 기억을 선택해도 기기에 기억되지 않음), 만료 전에 스스로 갱신되며, 연결 해제가 GitLab에서 토큰을 취소합니다. 다른 탭에서 시작한 로그인이나 재사용한 링크는 거부됩니다. 로그인은 사이트의 GitLab 애플리케이션이 등록된 뒤에 쓸 수 있으며, 그전에는 개인 액세스 토큰을 사용하세요.

요청은 api.github.com과 gitlab.com으로만 갑니다. 페이지의 Content Security Policy가 다른 호스트를 허용하지 않으며, 페이지는 referrer를 보내지 않습니다.

왜 api인가요? GitLab의 범위 표는 write_repository를 “Does not support API authentication”이라고 적고 있습니다. 이는 HTTP를 통한 git 전용이며 GitLab이 CORS 없이 제공하므로 브라우저에서는 쓸 수 없습니다. 변경 제안은 REST API를 쓰고, 여기에는 api(“complete read and write access to the API”)가 필요합니다. 도난당한 api 토큰은 그 사용자가 API로 할 수 있는 모든 일을, 그 사용자가 닿는 모든 프로젝트에서 할 수 있습니다. 발표 자료 저장소로 제한한 프로젝트 또는 그룹 액세스 토큰, 또는 발표 자료 프로젝트의 구성원일 뿐인 전용 GitLab 계정을 쓰세요.

보안

프레젠테이션은 페이지의 출처(origin)를 갖지 않는 샌드박스 iframe에 표시됩니다. 따라서 Playground에도, 그 저장소에도 접근할 수 없고, 양식을 제출하거나 페이지를 이동할 수도 없습니다. 이 페이지에는 자체 스크립트만 실행하는 Content Security Policy가 적용됩니다. 프레젠테이션의 원시 HTML은 slides의 기본 동작과 마찬가지로 Marp 허용 목록을 따릅니다. 5초 넘게 걸리는 렌더링(무한 반복하는 템플릿 등)은 중단됩니다.

발표자 창도 이 샌드박스를 유지합니다. 발표자 창은 Playground가 직접 열며, 같은 방식으로 샌드박스 처리된 iframe에 프레젠테이션을 표시합니다. 두 iframe은 저장소를 공유할 수 없으므로 Playground가 메시지로 슬라이드 번호를 중계합니다. 프레젠테이션을 실행하는 어떤 프레임도 Playground의 출처를 얻지 못합니다.

프로젝트의 미디어는 메시지에 담긴 바이트로 샌드박스 프레임에 전달되며, 각 프레임은 자신의 출처에서 직접 blob: URL을 만듭니다. Playground가 만든 blob: URL은 그 안에서 로드되지 않으며, 프레임 정책에는 미디어와 글꼴용 blob:만 추가됩니다.

Playground는 로그인 뒤에서 자신의 컴퓨터로 서비스할 수 있습니다. 셀프 호스팅을 참고하세요.

크기와 속도

모듈은 GitHub Pages가 제공하는 상태(gzip, Pages는 brotli를 제공하지 않음)로 8.8 MiB입니다. 진행률 막대와 함께 한 번 내려받으며, 이후 다음 배포까지 브라우저가 캐시합니다. Apple M4 Max의 Chrome 155에서 실제 페이지로 측정한 결과, 편집기는 페이지를 연 뒤 2.1 s(그중 1.5 s는 내려받기)에 준비되고 첫 슬라이드는 2.4 s에 나타납니다. 슬라이드 100장 벤치마크 프레젠테이션을 수정하면 약 30 ms 만에 미리 보기에 반영됩니다. go-slides는 바뀐 슬라이드만 렌더링하고, 미리 보기에서도 그 슬라이드만 교체합니다.

Created on by tannevaled

Modified on by tannevaled