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 :)

Alt text

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:


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

Alt text
Alt text
Alt text

Design & Visual Design

Alt text
Alt text

Data Flow & Server-Client Communication

Alt text
Alt text

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

  1. Pre-line parse
  • input: lines
  • output: lineObject(raw_text, depth, content_start)
  1. Line parse
  • input: lineObject
  • output: element(raw_text[excerpt_the heading], depth, )
depth: //only useful for line-element and cross-line element
display_text: “”//if the element has this, this means it does not has children
parsed:true //flag for whether this element is parsed


//return the jQuery node