Project GoMarkdown
Project GoMarkdown
This is a Google-Doc-like online document collaboration web application. Instead of supporting complicated Word document formating or simple plaint text format, we chose to implement a flexible, widely-used format: Markdown. In order to make it fully customized, I decided to implement all syntax by myself, this left room for more customized syntax. In this project, I am mainly responsible for the websocket communication, Markdown syntax parse and data synchronization. Thanks for efficient and funny collaboration with Jiupeng, Lu and Shiyue :)
Project Brief
- Description: A online collaborative markdown editor that support real-time synchornized edit of multiple users
- Related Techques: Javascript, Python, Websocket, Syntax tree, Django
- Features & Markdown Parse: real-time, line-based parse without referencing any other libraries. supported syntax include: heading, code block, list, nested list, bold, hyper text, underline, image.
- Feature & Collaborative Editing: edit operation synchronize with all other users, utilize different types of operations to represent operations. Restore cursor position to avoid cursor conflict
- Feature & File Management: Support document create, update, delete and access control
- Duration: 2016.09 - 2016.12
- Team member: Hongkun Leng, Rui Lu, Jiupeng Sun, Shiyue Liu
- Project Url: 52.87.188.28/login.html
Features:
Markdown Edit & Display
- The editing page is mainly splited into two parts, the left part is the editing area, the right is the display area.
- User can edit markdown text in the left area, while the translated markdown text will be displayed in the right area
Realtime Editing
- There would be multiple users viewing one document and one (or multiple) user writing a document (the first milestone is to develop single-writer multiple-users mode)
- When the writer is editing the document, the edited content would be displayed realtime on all viewers’ display area
Create, List, Delete Documents
- There is a personal page where the user can see all his documents (documents created by him and shared with him)
- The user can create a new document by clicking on the “Add” button
- For every document listed under the page, there would be a “Delete” button, user can delete the button to remove the document from his documents. (When the owner of the documents delete the document, all users the owner shared with would also have the document removed from their list)
Access Control
- At any time, there would be only one user who has the writing control of the document
- The user can share his document with other users by clicking the “Edit” button on each document and add the target user in the poping up dialog
- A viewing user of a document can request the writing permission of a document by clicking the “Request” button on document editing page. Then, there would be a notification requesting the document writer-permission on current writer’s editing page, if the current writer accepts the request, then the writing control is transferred to the requesting user.
- After all users go offline, the write control is taken back to server. And the control will be given to the first user who access the document next time.
Design & Wireframe
Design & Visual Design
Data Flow & Server-Client Communication
Development & Markdown Parse
Supported Genetic Notations:
- Heading
- Bold
- List
- Quote
- Paragraph
Supported Nested Notations:
- Bold in paragraph, quote, list
- Nested List
Single Line Notations
- Heading
- Paragraph
Multiple Line Notations
- List
- Quote
Process procedure
- after every line, put current element into stack
- if current depth is deeper than the stack >> into the stack
- if current depth is smaller or equal to the stack depth >> pop out (the poped out element end), add the element into the
Supported Structure
- Cross-line element: quote, table
- In-line nested element: li,
- In-line genetic element: bold, italic, hypertext, image, @time
Basic Procedure
Pre-line parse
- since quote is a cross-line element and it violate the structure of line parsing (although in same line, it still consider next line as it’s children)
we need pre-process the depth first (add depth to every line after quote start)
Line parse
- Give each line it’s basic element type
since genetic inline-element such as bold, italic are not basic line element, it should be replaced with paragraph element
In-line parse
- inside some line element (paragraph, li), we should parse inside these element
IO for Each Step
- Pre-line parse
- input: lines
- output: lineObject(raw_text, depth, content_start)
- Line parse
- input: lineObject
- output: element(raw_text[excerpt_the heading], depth, )
1 | ElementObject{ |