Files

8 lines
9.5 KiB
JavaScript

const p=s=>'<p>'+s+'</p>';const ul=xs=>'<ul>'+xs.map(s=>'<li>'+s+'</li>').join('')+'</ul>';
export default {
133:({a,pre})=>p('간단한 위젯을 만들고 버튼을 눌렀을 때 메시지를 표시하는 예제입니다. 원문에서 누락된 HTML 템플릿을 아래 예제에 보완했습니다.')+'<h3>1. 기본 구조</h3>'+pre(0).replace('this.$widget = $("");','this.$widget = $(\'&lt;div id="my-widget"&gt;&lt;/div&gt;\');')+p('프런트엔드 JavaScript 코드 노트를 만들고 위 코드를 넣으세요. <code>#widget</code> '+a(0,'속성')+'을 '+a(1,'노트')+'에 지정한 뒤 창을 새로고침합니다.')+p('개발자 도구에서 <code>document.querySelector("#my-widget")</code>로 요소가 있는지 확인할 수 있습니다. 결과가 <code>null</code>이면 '+a(2,'노트')+'의 <code>#widget</code> '+a(3,'속성')+'과 코드 오류를 확인하세요.')+'<h3>2. 버튼 추가</h3>'+pre(1).replace('const template = ``;','const template = `&lt;div id="my-widget"&gt;&lt;button&gt;인사하기&lt;/button&gt;&lt;/div&gt;`;')+p('다시 불러오면 왼쪽 영역에 버튼이 나타납니다.')+'<h3>3. 모양과 위치</h3>'+p('Trilium에 포함된 '+a(4,'Boxicons')+'를 사용해 아이콘을 표시할 수 있습니다.')+pre(2).replace('const template = ``;','const template = `&lt;div id="my-widget"&gt;&lt;button title="인사하기" aria-label="인사하기"&gt;&lt;i class="bx bxs-magic-wand"&gt;&lt;/i&gt;&lt;/button&gt;&lt;/div&gt;`;')+p('CSS로 왼쪽 아래에 배치합니다.')+pre(3)+'<h3>4. 클릭 동작</h3>'+p(a(5,'스크립트 API')+'의 <code>api.showMessage</code>를 사용합니다.')+pre(4).replace('Hello World!','안녕하세요!')+p('새로고침한 뒤 버튼을 누르면 안녕하세요!라는 메시지가 나타납니다.'),
134:({a})=>'<aside class="admonition warning">'+p('더 이상 제공되거나 정상 작동하지 않는 Evernote Legacy를 경유하는 과거의 이전 방법입니다. 현재 사용할 수 있는 절차로 안내하는 문서가 아닙니다.')+'</aside><h2>OneNote 자료 준비</h2>'+ul(['OneNote 태그는 이미지로 가져와질 수 있으므로 필요하면 이모지로 바꿉니다.','제목 서식을 사용하고 불필요한 공백을 정리합니다.','매우 긴 페이지는 짧은 노트와 하위 노트로 나누는 편이 편리합니다.','번호 목록 사이의 불필요한 빈 줄을 없앱니다. 가져온 뒤 번호가 다시 1부터 시작하는 문제를 줄일 수 있습니다.'])+'<h2>과거의 이전 절차</h2>'+p(a(0,'Evernote Legacy 보관 문서')+'를 참고한 방법입니다. 당시에는 계정이 필요했지만 인터넷 연결 없이 가져올 수 있었으며 Evernote 서버에 노트를 동기화하지 않는 방식으로 설명되었습니다. 파일 → 가져오기 → OneNote에서 전자 필기장과 구역을 선택했습니다.')+p('여러 구역을 한 번에 가져오면 폴더가 합쳐질 수 있습니다. 순서는 유지되므로 이후 다시 나눌 수 있습니다. 가져온 전자 필기장을 오른쪽 클릭해 노트 내보내기를 선택하고 ENEX로 저장합니다.')+'<h3>ENEX 정리</h3>'+p('OneNote 페이지 머리말을 제거하려면 텍스트 편집기에서 정규식 <code>.&lt;div.*&gt;&lt;h1</code>을 찾아 <code>&lt;h1</code>로 바꾸는 방법이 원문에 소개되어 있습니다. 원본을 보관하고 바뀌는 범위를 확인하세요.')+'<h3>Trilium으로 가져오기</h3>'+p('상위 노트를 오른쪽 클릭해 가져오기를 선택하고 ENEX 파일을 지정합니다. 큰 파일은 몇 분이 걸릴 수 있습니다. 파일마다 반복하세요.')+'<h2>가져온 뒤 확인할 내용</h2>'+ul(['가운데 정렬이 왼쪽 정렬로 바뀔 수 있습니다.','OneNote 내부 링크는 자동으로 Trilium 노트에 연결되지 않습니다. onenote://를 찾아 대상 노트로 다시 연결해야 합니다. 원문의 문단 연결 관련 제한은 당시 버전 기준입니다.','글자색과 강조 및 일반 서식은 대체로 유지됩니다.','기존 수정 이력은 가져오지 못합니다. 이후 수정은 Trilium에서 기록합니다.','노트 순서는 유지되지만 하위 구조는 다시 정리해야 할 수 있습니다.','OneNote 구역은 Evernote 태그가 되어 Trilium 속성으로 들어옵니다. 필요하지 않으면 Evernote 내보내기에서 제외합니다.','Created with OneNote라는 문구가 필요 없으면 가져오기 전에 ENEX에서 찾아 지울 수 있습니다.','일부 링크는 클릭할 수 없는 상태로 들어올 수 있습니다.','원문에서는 파일과 화면 캡처 및 첨부 파일이 보존된다고 설명합니다.']),
135:({a,pre})=>p('이 문서는 Trilium 사용 중 발생하는 문제를 해결하는 기본 절차입니다.')+'<h2>먼저 다시 불러오기</h2>'+p('화면 문제는 <kbd>Ctrl</kbd>+<kbd>R</kbd>로 프런트엔드를 다시 불러오면 해결될 수 있습니다. 계속되거나 백엔드 문제라면 앱 전체를 다시 시작하세요. 데스크톱 앱은 닫았다 다시 열고 Docker는 컨테이너를 재시작합니다.')+'<h2>특정 노트를 열 때 종료되는 경우</h2>'+p('잘못된 스크립트가 있는 노트를 시작할 때 다시 열면 오류가 반복될 수 있습니다. <code>TRILIUM_START_NOTE_ID</code>로 처음 열 노트를 지정해 탭을 초기화할 수 있습니다.')+pre(0)+'<h2>시작 스크립트 문제</h2>'+p('시작 스크립트나 '+a(0,'사용자 위젯')+' 때문에 실행되지 않으면 안전 모드로 시작하세요.')+pre(1)+p('배포판에 따라 <code>trilium-safe-mode.bat</code>나 <code>trilium-safe-mode.sh</code>가 제공됩니다. 실행한 뒤 원인이 된 노트를 찾아 수정하거나 제거하세요.')+'<h2>일관성 검사</h2>'+p('Trilium은 노트의 상위 연결 등 데이터베이스의 논리 구조를 주기적으로 확인합니다. 오류 알림이 나오면 문제를 보고하고 필요할 경우 '+a(1,'익명화한 데이터베이스')+'를 제공하세요.')+'<h2>백업 복원</h2>'+p('문제가 심각하다면 '+a(2,'백업에서 복원')+'할 수 있습니다.')+'<h2>비밀번호를 잊은 경우</h2>'+p('보호된 노트는 비밀번호 없이 복구할 수 없습니다. 아래는 보호하지 않은 노트에 다시 접근하기 위한 원문의 복구 절차입니다. '+a(3,'데이터베이스')+'가 있는 '+a(4,'데이터 폴더')+'를 먼저 백업하고 앱을 종료한 뒤 '+a(5,'SQLite 편집기')+'로 document.db를 엽니다.')+pre(2)+p('변경 사항을 저장하면 로그인 비밀번호가 <code>password</code>로 바뀝니다. 이 절차로 기존 보호 노트가 복구되는 것은 아닙니다. 접근 가능한 노트를 내보내 새 데이터베이스로 옮기거나 기존 DB를 계속 사용한다면 설정에서 즉시 새 비밀번호를 지정하세요.')+'<h2>오류 보고</h2>'+p(a(6,'GitHub 문제 보고')+'에 발생 상황을 적고 '+a(7,'오류 로그')+' 안내에 따라 필요한 정보를 함께 제공하세요.'),
136:({a})=>p('다중 인증은 비밀번호 외에 추가 확인 수단을 요구합니다. 비밀번호가 유출되더라도 다른 사람이 접속하기 어렵게 합니다. 이 버전에서는 OpenID와 TOTP를 동시에 사용할 수 없습니다.')+'<h2>인증 방식</h2>'+p('OpenID는 Google 같은 외부 서비스 계정으로 신원을 확인하는 방식입니다. TOTP는 인증 앱에서 짧은 시간마다 바뀌는 일회용 코드를 생성하는 방식입니다. 일반적으로 30초마다 코드가 바뀝니다.')+'<h2>설정</h2>'+p('다중 인증은 서버 인스턴스에서 설정합니다. 원문 작성 당시에는 다중 인증이 켜진 서버와 새 데스크톱 앱의 최초 동기화에 문제가 있어 최초 동기화 동안만 끄는 임시 방법을 안내했습니다. 이는 해당 버전의 제약에 관한 설명입니다.')+'<h3>TOTP</h3>'+ul(['메뉴 → 설정 → 다중 인증을 엽니다.','다중 인증 사용을 켜고 시간 기반 일회용 비밀번호 방식을 선택합니다.','TOTP 비밀 키 생성 버튼을 누릅니다.','생성한 키를 사용할 인증 앱에 등록합니다.','복구 코드를 생성해 안전한 곳에 보관합니다.','인증 앱을 사용할 수 없을 때 복구 코드를 한 번씩 사용할 수 있습니다. 사용한 코드는 설정에 사용 시각이 기록됩니다.','설정을 마친 뒤 새로고침하면 다시 로그인해야 합니다.'])+'<h3>OpenID</h3>'+p('먼저 인증 제공자에 애플리케이션을 등록합니다. Google은 '+a(0,'공식 OpenID 연결 안내')+'를 참고하세요.')+p('<code>config.ini</code>에 <code>oauthBaseUrl</code>과 <code>oauthClientId</code> 및 <code>oauthClientSecret</code>을 지정합니다. '+a(1,'설정 안내')+'를 참고하세요. 환경 변수 <code>TRILIUM_OAUTH_BASE_URL</code>과 <code>TRILIUM_OAUTH_CLIENT_ID</code> 및 <code>TRILIUM_OAUTH_CLIENT_SECRET</code>도 사용할 수 있습니다.')+p('서버를 다시 시작한 뒤 설정 → 다중 인증에서 사용을 켜고 OAuth/OpenID 방식을 선택하세요. 페이지를 새로고침한 뒤 제공자 계정으로 로그인합니다.')+p('기본 제공자는 Google입니다. 다른 제공자는 <code>oauthIssuerBaseUrl</code>과 <code>oauthIssuerName</code> 및 <code>oauthIssuerIcon</code>으로 지정합니다. 대응하는 환경 변수는 <code>TRILIUM_OAUTH_ISSUER_BASE_URL</code>과 <code>TRILIUM_OAUTH_ISSUER_NAME</code> 및 <code>TRILIUM_OAUTH_ISSUER_ICON</code>입니다. 이름과 아이콘은 로그인 화면의 제공자 표시에도 필요합니다.')
};