Compare commits

..

3 Commits

Author SHA1 Message Date
482837d7f0 doc up to date 2022-04-21 01:05:50 +09:00
220416c734 add w option alias watch 2022-04-21 01:05:01 +09:00
d771810eff requirement update from issues 2022-04-21 00:51:31 +09:00
4 changed files with 257 additions and 53 deletions

View File

@ -42,49 +42,55 @@
## 2.2. 제품 기능(Product functions) ## 2.2. 제품 기능(Product functions)
본 프로젝트의 결과물은 다음과 같은 기능을 수행한다. 본 프로젝트의 결과물은 다음과 같은 기능을 수행한다.
### 2.2.1 Scrap Opreration
1. Focus, Unfocus ### 2.2.1 Chunk Operation
2. 수정/읽기
3. 삭제 1. #1 Chunk: Focus/Unfocus
4. 다른 것과 스왑 2. #2 Chunk: remove
- Alt 화살표로 스왑 3. #3 Chunk: read
5. 편집 미리보기 4. #4 Chunk: previews
6. 캐싱 5. #10 Chunk: autocomplete
7. 링크 타입 6. #11 Chunk: swap positions
8. git 히스토리 보여주기 7. #27 Chunk: edit
9. LaTex 타입
10. 그림, 비디오 ### 2.2.2 Document Operation
11. 워드, 한글 뷰어
12. 자동 완성 1. #5 Document: view Chunk
### 2.2.2 Document Opreration 2. #6 Document: remove
1. Scrap 얻어오기 3. #7 Document: add/delete tag
2. 삭제 4. #8 Document: Drag And Drop Upload
3. 태그 붙이기 5. #9 Document: Auto-Refresh
4. 드래그 앤 드롭 업로드 6. #12 Document: Share
5. 외부 변경 감지 자동 리로드 7. #13 Document: 네비게이터
6. 공유
7. navigator ### 2.2.3 File Operation
### 2.2.3 File TreeView Opreration
1. 파일 삭제 1. #14 File: create/delete/rename file
1. 파일 다운로드 2. #15 File: upload/download files
1. 파일 업로드 3. #18 File: export document
1. Document 오픈
1. 드래그앤드롭 파일 move ### 2.2.4 Search Operation
### 2.2.4 Search Opreration
1. 문서 검색 1. #16 Search: 문서 검색
### 2.2.5 Stash Opreration
1. 보기 ### 2.2.5 Stash Operation
1. 추가
1. 삭제 1. #17 Stash: 보기
1. 드래그앤드롭 2. #19 Stash: 추가
### 2.2.6 Management Opreration 3. #20 Stash: 삭제
1. Login 4. #21 Stash: 드래그 앤 드롭
2. Configure
3. 현지화(localization) ### 2.2.6 Management Operation
4. 테마
### 2.2.7 Extension Opreration 1. #22 Management: Login
1. 샘플: 체스 형식 뷰어 2. #23 Management: Configure
2. 로그인이 필요한 곳을 위한 캐시된 웹사이트 제공하는 브라우저 플러그인 3. #24 Management: 현지화
4. #25 Management: 테마
### 2.2.7 Extension Operation
1. #28 Extension: API
2. #29 Extension: Plugin
### 2.2.8 비기능적 기능 ### 2.2.8 비기능적 기능
- Docker 배포 - Docker 배포

View File

@ -15,6 +15,188 @@
해당되지 않음. 해당되지 않음.
## 3.2. 기능 요구사항(Functional requirements) ## 3.2. 기능 요구사항(Functional requirements)
### (1) Chunk: Focus/Unfocus
액터: 사용자
시작 조건: Chunk를 편집할 수 있는 권한을 가져야 한다.
1. 사용자가 Chunk의 영역에 클릭을 했을때, Focus 된다. 그떄 다른 Chunk의 Focus를 사라지게 한다.
2. Focus를 얻었을때, Focus를 얻은 Chunk을 눈에 띄이도록 표시한다.
3. Focus가 사라졌을때, 변경되었으면 변경된 Chunk를 저장한다.
### (2) Chunk: remove
액터: 사용자
시작 조건: Chunk를 수정가능한 권한을 가지고 있어야함.
1. Chunk의 좌측 상단의 Context Menu에 삭제 아이콘을 클릭할 때나 빈 내용의 Chunk에서 <kbd>Backspace</kbd><kbd>Del</kbd>를 입력할 때 시작한다.
2. 해당 Chunk를 삭제한다.
3. 서버에서 그 Chunk를 삭제한다.
4. 아래의 Chunk가 있다면 끌어 올린다.
### (3) Chunk: read
액터: 사용자
시작조건: 없음
1. 서버에서 내용을 읽는다.
2. 그 내용을 chunk안 영역에 사람이 보기 좋게 그 타입에 따라 렌더링한다.
render하는 대상 목록은 다음과 같다.
- markdown
- latex
- link (image, video, site)
- FEN
- etc
대안 흐름:
A. 렌더링 실패
1. 렌더링 실패에 실패하면 실패의 이유를 보여준다.
### (4) Chunk: previews
액터: 사용자
사용조건: 편집 중일때
1. Chunk의 내용을 바꾸면 시작된다.
2. 보기모드에서 어떻게 보여질지 미리보기 창을 띄워준다. 미리보기는 기본적으로 하단에 띄우고 밑에 공간이 없으면 상단에 띄운다.
3. 내용이 바뀌면 미리보기 창의 내용도 갱신한다.
### (5) Document: view Chunk
액터: 사용자
시작조건: 없음.
1. Document가 로딩되면 시작한다.
2. 경로가 주어지면 Document Component에서 그 경로의 문서를 읽고 파싱한다. 그동안 로딩 바를 보여준다.
3. 로딩이 완료되면 파싱된 결과물인 Chunk들을 보여준다.
대안흐름:
A. 읽기 실패:
1. 읽기에 실패한 경우 읽기에 실패한 이유를 띄운다.
B. 파싱 실패:
1. 파싱에 실패한 경우 파싱에 실패한 이유를 띄우고 raw text가 담긴 Chunk로 렌더링한다.
### (6) Document: remove
액터: 사용자
시작조건: 문서를 삭제할 권한이 있어야함.
1. Document의 AppBar에 놓여있는 삭제 아이콘을 클릭하면 시작한다.
2. 정말로 삭제하겠냐는 다이얼로고가 띄운다.
3. 거기서 예스를 누르면 Document를 삭제한다.
대안 흐름:
1. 다이얼로그에서 아니오를 누르면 다이얼로고를 닫고 종료한다.
### (7) Document: add/delete tag
액터: 사용자
시작조건: 태그 수정 권한이 있을 때
1. Document의 AppBar에 놓여있는 태그 수정 아이콘을 클릭하면 시작한다. 태그 수정 다이얼로그를 띄운다.
2. 태그 수정 다이얼로그에서 태그를 생성, 삭제한다.
3. 수정을 완료하고 저장 버튼을 누르면 태그 수정이 종료된다.
대안 흐름:
1. 취소 버튼을 누르면 다이얼로그를 닫고 종료한다.
### (8) Document: Drag And Drop Upload
액터: 사용자
시작조건: 문서 수정 권한이 있어야 한다.
1. 웹사이트의 그림이나 비디오 등의 파일을 Drag And Drop 해서 Chunk 사이에 놓으면 시작된다.
2. Drag And Drop된 파일을 서버에 업로드한다. 업로드시 파일 이름이 중복될 때 파일 이름이 밑줄과 숫자로 끝나지 않으면 이름의 뒤에 "_1"을 붙여 업로드 한다. 숫자로 끝나면 다음 숫자를 붙여서 업로드 한다. 파일 이름이 없다면 임의의 이름을 붙여서 업로드 한다.
3. 그 파일을 새로운 Chunk로 추가한다. 이때 웹에서 표시가능한 파일(이미지, 동영상)이면 파일을 표시하는 Chunk를 추가하고 아니면 다운로드 링크를 가진 Chunk를 추가한다.
대체흐름:
A. 파일 사이즈 큼
1. 기본단계 2에서 파일 사이즈가 설정보다 크면 시작한다.
2. 파일 크기가 너무 크다는 메세지로 띄우고 종료한다.
B. 작은 파일 사이즈
1. 기본단계 2에서 파일 사이즈가 설정보다 작으면 시작한다.
2. 파일을 base64로 인코딩해서 Chunk로 삽입한다.
### (9) Document: Auto-Refresh
액터: 외부 편집기
시작조건: 없음
1. Document나 Document가 포함하는 미디어의 파일이 다른 편집 프로그램에 의해서 변경되었을 시에 시작한다.
2. 보고 있는 사용자의 Document 뷰를 변경 부분만 Refresh한다. 이때 보고 있던 스크롤이 변하지 않게 유의한다.
### (10) Chunk: autocomplete
액터: 사용자
시작조건: chunk 수정시어야 한다.
1. <kbd>Ctrl+Space</kbd>로 자동완성 창을 띄울 수 있다.
2. 방향키로 고른다.
3. <kbd>Tab</kbd>이나 <kbd>Enter</kbd>를 통해 선택한다.
4. 선택한 단어로 완성시킨다.
### (11) Chunk: swap positions
액터: 사용자
시작 조건: Document 수정권한이 있어야 한다.
1. Focus를 얻고 핸들 아이콘을 누를때 시작한다.
2. 이때 오버레이를 표시해서 놓여졌을 때의 상황을 미리 볼 수 있게 한다.
3. 드래그해서 원하는 장소에 놓으면 위치를 바꿀 수 있다.
### (12) Document: Share
액터: 사용자
시작 조건: 문서를 공유할 수 있는 권한을 가져야한다.
1. Document의 AppBar에 놓여있는 공유 아이콘을 누르면 시작한다.
2. 공유 링크를 복사한다. 그리고 공유 설정아이콘을 띄워준다. 여기서 종료할 수 있다.
3. 공유 설정아이콘을 클릭하면 공유 설정 다이얼로그를 띄운다. 이 다이얼로그에서는 공유 기간과 편집 가능여부 등을 설정할 수 있고 공유 링크를 복사할 수 있다.
### (13) Document: 네비게이터
액터: 사용자
시작 조건: 없음
1. 만일 문서가 속하는 디렉토리에 Summary.md 가 있고 링크와 리스트로 이루어져 있으면 시작한다.
2. Document의 왼쪽에 Summary의 내용을 네비게이터 역할로 표시한다.
### (14) File: create/delete/rename file
앱상에서 파일을 생성하거나 삭제 할 수 있어야 한다. Treeview에서 오른쪽 클릭을 하면 Context Menu가 나오고 새파일을 클릭하면 이름을 지정해서 파일을 생성할 수 있다. Context Menu에서 삭제를 클릭하면 해당 파일을 삭제한다. 이름 바꾸기를 클릭하거나 Treeview에서 파일에 포커스가 간 상태에서 <kbd>F2</kbd>를 입력하면 이름을 바꿀 수 있도록 한다.
### (15) File: upload/download files
파일을 업로드하거나 다운로드 할 수 있어야 한다. Treeview의 Context menu에서 다운로드 버튼을 클릭해서 다운로드 할 수 있다. Treeview에 파일을 드래그 앤 드롭하는 것으로 업로드 할 수 있다.
### (16) Search: 문서 검색
Drawer에서 문서 검색 버튼을 누르면 문서 검색 창이 뜬다. 문서 검색 창에서 태그 검색을 선택하고 태그를 입력한다. 검색 버튼을 누르면 태그를 가진 문서를 리스트로 보여준다. 내용 검색을 선택하고 텍스트를 입력해서 검색하면 텍스트를 포함한 문서를 리스트로 보여준다.
### (17) Stash: 보기
오른쪽에 작은 버튼을 두고 버튼을 클릭하면 오른쪽 Drawer가 열려서 Stash의 내용을 보여준다.
최대 지정된 숫자만큼의 내용들을 보여준다.
모바일에선 보여주지 않는다.
### (18) File: export document
문서를 보기 모드에서 보이는 것처럼 출력할 수 있다. 메뉴의 Context menu에서 접근 할 수 있다. 문서 타입에만 가능하다.
### (19) Stash: 추가
Stash 창을 연 상태에서 포커스가 Stash 창에 주어져 있을때 <kbd>Ctrl+V</kbd>를 누르면 Stash에 클립보드의 내용이 추가되고 클립보드는 비워진다.
### (20) Stash: 삭제
Stash 창의 각각 항목의 삭제 아이콘을 클릭하면 선택된 항목을 삭제한다. Stash에 붙어있는 삭제 아이콘을 클릭하면 전체 항목을 삭제한다.
### (21) Stash: 드래그 앤 드롭
Stash 창의 항목을 Document에 드래그해서 드롭하면 그 자리에 Chunk가 삽입된다. 그리고 항목을 그 위치로 업로드시킨다. 업로드는 #8 와 한 것 같이 한다.
### (22) Management: Login
사용자가 로컬에서 지정된 프로그램이 아닌 외부에서 접근한다면 로그인을 요구한다. 초기 로그인 암호는 환경변수에 의해서 결정된다.
### (23) Management: Configure
편집기 내부에서 <kbd>F1</kbd>키를 입력하거나 설정 아이콘을 클릭하면 설정창을 보여준다. 설정창은 프로그램의 속성을 설정할 수 있고 로그를 볼 수 있다. 설정창은 다음 항목들을 포함한다.
- 로그인 암호
- 테마 설정
- 언어 설정
### (24) Management: 현지화
어플리케이션을 여러가지 다양한 언어로 제공한다. 설정창에서 다른 언어로 바꿀 수 있다.
### (25) Management: 테마
테마를 설정할 수 있다. 설정창에서 바꿀 수 있고 기본적으로 밝은 테마과 어두운 테마를 제공한다. 커스텀 css 를 테마로 등록할 수 있다.
### (27) Chunk: edit
액터: 사용자
시작조건: Chunk의 Focus를 얻어야 한다.
1. Chunk 안의 text를 수정한다.
> - 기능 요구사항은 소프트웨어가 입력을 처리하고 출력을 생성하는 기본적인 행동을 정의해야 한다. > - 기능 요구사항은 소프트웨어가 입력을 처리하고 출력을 생성하는 기본적인 행동을 정의해야 한다.
> - 포함하는 행동들 > - 포함하는 행동들
> 1. Validity checks on the inputs > 1. Validity checks on the inputs
@ -130,5 +312,4 @@
### 3.7.8. Additional comments ### 3.7.8. Additional comments
> - 새로운 SRS를 고려할 때 두 가지 이상의 조직 기법이 적합할 수 있다. > - 새로운 SRS를 고려할 때 두 가지 이상의 조직 기법이 적합할 수 있다.
> - 이 경우 명세에 따른 시스템의 상세 요구사항에 맞춘 다중 계층의 요구사항을 구성한다. > - 이 경우 명세에 따른 시스템의 상세 요구사항에 맞춘 다중 계층의 요구사항을 구성한다.

View File

@ -2,10 +2,26 @@
## getIssue ## getIssue
Github token을 받아서 최신 100개의 Issues 들의 내용을 긁어옵니다. Github token을 받아서 최신 100개의 Issues 들의 내용을 긁어옵니다. 그리고 그 내용을 json으로 출력합니다.
```sh ```sh
deno run --allow-net --allow-env getIssue.ts 'YOUR GIHTUB TOKEN' deno run --allow-net --allow-env --allow-write getIssue.ts --token 'YOUR GIHTUB TOKEN'
``` ```
으로 실행하면 됩니다. 으로 실행하면 됩니다.
토큰을 발급받기 위해선 [다음 링크](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)를 참조하면 됩니다. 토큰을 발급받기 위해선 [다음 링크](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)를 참조하면 됩니다.
인자로 token과 path를 받습니다. token 인자가 지정되어 있지 않으면 `GITHUB_TOKEN` 환경변수에서 가져옵니다. path가 지정되어있지 않으면 `stdout`에 출력합니다.
## printDocument
json으로 표현된 Github의 Issues를 받아서 template에 따라 문서로 만듭니다.
```sh
deno run --allow-read --allow-write printDocument.ts --overall --path ./issues.json --outpath ssr.md
```
으로 실행하면 됩니다.
다음과 같은 인자를 가집니다:
- `overall`: overall을 출력
- `outpath`: 지정된 경로에 출력. 설정되지 않으면 `stdout`에 출력함.
- `path`: json 파일 위치. 지정되지 않으면 `stdin`에서 읽으려고 시도.
- `w`, `watch`: 파일에 변경이 있을 때 자동으로 업데이트.

View File

@ -15,6 +15,7 @@ async function readContent(path?: string): Promise<string> {
const buf = await readAll(Deno.stdin); const buf = await readAll(Deno.stdin);
content = decoder.decode(buf); content = decoder.decode(buf);
} }
else throw new Error("No input provided. path or stdin.");
return content; return content;
} }
@ -47,8 +48,8 @@ async function readAndPrint(args: {
async function main() { async function main() {
const parsedArg = argParse(Deno.args); const parsedArg = argParse(Deno.args);
const { path, outpath, overall, w } = parsedArg; const { path, outpath, overall, w, watch } = parsedArg;
const watchMode = w || watch;
if (typeof path !== "undefined" && typeof path !== "string") { if (typeof path !== "undefined" && typeof path !== "string") {
console.log("Please provide a path to the json file."); console.log("Please provide a path to the json file.");
Deno.exit(1); Deno.exit(1);
@ -61,11 +62,11 @@ async function main() {
console.log("Please provide a boolean value for overall."); console.log("Please provide a boolean value for overall.");
Deno.exit(1); Deno.exit(1);
} }
if (typeof w !== "undefined" && typeof w !== "boolean") { if (typeof watchMode !== "undefined" && typeof watchMode !== "boolean") {
console.log("Please provide a boolean value for w."); console.log("Please provide a boolean value for w.");
Deno.exit(1); Deno.exit(1);
} }
if (w && typeof path === "undefined") { if (watchMode && typeof path === "undefined") {
console.log("Could not set watch mode without a path."); console.log("Could not set watch mode without a path.");
Deno.exit(1); Deno.exit(1);
} }
@ -82,7 +83,7 @@ async function main() {
const issues = JSON.parse(c) as Issue[]; const issues = JSON.parse(c) as Issue[];
issues.sort((a, b) => a.number - b.number); issues.sort((a, b) => a.number - b.number);
await readAndPrint({ path, outpath, overall }); await readAndPrint({ path, outpath, overall });
if (w) { if (watchMode) {
const watcher = Deno.watchFs([viewPath, path as string]); const watcher = Deno.watchFs([viewPath, path as string]);
for await (const event of watcher) { for await (const event of watcher) {
if (event.kind === "modify") { if (event.kind === "modify") {