Try   HackMD

HackMD

Markdown 協作筆記

jackycute @ 2016 MOPCON


Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

吳承翰 Max Wu

北科大 資訊工程所

我喜歡好的產品,也開發好的產品;
我寫的不是程式,是理想。


HackMD

Realtime collaborative markdown notes on all platforms


工程師看到的時候想:

  • Realtime;那就是很快就可以看到結果的意思
  • Collaborative;就是可以跟別人一起同時工作
  • Markdown;就是 GitHub 還有 堆疊溢出 在用的語法嘛
  • Notes;喔 Evernote 還是 Quip 都用過啦
  • Platforms;阿不就跨平台好棒棒

一般人看到的時候想:

  • Realtime;即時?阿是有多即時?FB 那樣嗎?
  • Collaborative;協作?Google Doc 我聽過
  • Markdown;你給我解釋解釋,解釋解釋
  • Notes;我們公司都用 Word 作筆記傳 FTP
  • Platforms;不懂你的意思,可以說清楚一點嗎?

Hack + MD


Hack

用聰明的方法來完成事情


Markdown

輕量的視覺化標記語言

「蛤?」


文字就可以排版的語法

感謝 @clkao 貢獻此麻瓜咒語


HackMD

  • 靈感來自 Hackpad
  • 更注重速度與靈活度
  • 跨平台的筆記服務

用途

  • 製作筆記
  • 撰寫文件
  • 快速簡報

功能

  • 自動上傳圖片
  • 支援嵌入影片
  • 支援數學公式
  • 支援各式圖表
  • 自動修訂紀錄
  • 自動作者標記

採用

  • PyCon TW 2016
  • g0v
  • CTF write-ups
  • Debater
  • 成大 進階電腦系統理論與實作 (Fall 2016)

現況

  • 2015 年 3 月開始上線服務
  • 累計超過 5.2 萬份筆記
  • 每月超過 3.4 萬的活躍使用者
  • 會員超過 7,500 名
  • 使用者來自 台灣、日本、美國、歐洲、南美洲
  • 支援超過 15 種介面語言

開源

  • 被星星超過 1,000 次
  • 擁有超過 24 名貢獻者
  • 被 Fork 超過 130 次

架構

  • 前端使用 jQuery
  • 後端使用 Node.js
  • 資料庫使用 PostgreSQL

一個人怎麼實踐理想?

「組合肉」


起源

資訊安全 期末專案

好奇即時協作的原理與其中的安全問題

因為我很懶所以愛上優雅的 Markdown


做法:

  1. 上網餵狗搜尋 Collaborate Editor
  2. 找最容易看得懂的範例開始改起
  3. 找可以用的 Open Source 套件加料
  4. 研究原始碼填補接縫
  5. 測試功能正常,美化外皮

結論:兩天完成的夜市牛排

  • 可以多使用者同時協作文字
  • 實作對稱式加解密 (AES)
  • 其實就是實踐 MVP (最小可行產品) 的過程

劇終

  • 這個專案拿到 99 分
  • 做完就去放寒假了 XD
  • 沒有人愛你
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Re: 從零開始的協作筆記

  • 既然用了 Markdown 就要渲染成 HTML 啊!
  • 既然都是網頁了不如支援一下 RWD (響應式網頁設計)
  • 先來場大亂鬥看看會發生甚麼事情?!

選擇 Markdown renderer

  • chjj / marked 10766 298
  • jonschlinkert / remarkable 2881 53
  • markdown-it / markdown-it 2656 2
  • wooorm / remark 715 5

chjj / marked

  • 輕量、效能最好
  • 沒有遵循任何標準
  • 自訂語法較困難

markdown-it / markdown-it

  • 效能佳
  • 遵循 CommonMark
  • 容易自訂語法
  • 外掛多

jonschlinkert / remarkable
基本上已棄用,markdown-it 的前身


wooorm / remark

  • 效能好
  • 遵循 CommonMark
  • 有制定一套 AST (虛擬結構樹)
  • 外掛多
  • 明日之星
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

CommonMark

因為 Markdown 是開放格式
所以各自制定的語法有非常多種

目前 CommonMark 為大多數人遵循的標準


跨平台介面設計

  • 使用 Bootstrap,內建 RWD
  • 無論整合什麼都要看起來像 Bootstrap
  • 盡量讓所有功能可用,不能用的直接藏起來

跨平台也能保持良好的使用者體驗

了解瀏覽器的設計,盡量保留原生功能

  • body scrolling 的時候工具列會縮小
  • 輸入的時候虛擬鍵盤會彈出來
  • #hash 是拿來定位 id anchor 的
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

跨平台介面開發與除錯

  • 善用響應式設計模式預覽 (Safari)
  • 善用 Remote 除錯 (Chrome, Safari)
  • 實機測試最準確
  • 為不同螢幕裝置做更詳細的最佳化

使用者總能挑戰裝置的極限!

  • 這麼小的螢幕上還是要用 IDE!
  • 超小的元素還是被點到了!
  • 行動網路很慢,但是硬要用!
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

社群推廣大亂鬥

  • 分享到 FB 的幾個較大的資訊相關社團
  • 自己分享到 Hacker News
  • 造成空前的流量,很多人一起測試輸入

大爆炸
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 有人嘗試輸入 40 萬字,造成 CPU 負載過重
  • 有人嘗試輸入 不安全的語法
  • 多人一起輸入會搶字

適當且無感的限制

  • 限制最大輸入字數,超過會提醒
  • 自動過濾所有渲染出來的 HTML

如何協作同步?

  • 輸入拼字也需要同步
  • 網路延遲造成同步錯亂

拼字問題

  • 輸入需要拼字的還有 日文、韓文 等
  • 拼字的時候瀏覽器有事件 (compositionStart 等)
  • 但是會因為裝置、瀏覽器而實作有所不同
  • 總之不要忽略拼字,ㄅㄆㄇㄈ也需要同步

Operational Transformation 操作轉換

無法避免因為網路延遲所導致的資料不同步

多人協作的時候需要將輸入的操作結構化
然後按照順序轉換成相對應的操作並同步


共有三種操作

  • Retain 多少字元不更動
  • Insert 插入字元
  • Delete 刪除字元

如何轉換?

以「PPAP」為例


PP→PPAP

Client BServerClient AClient BServerClient AO1: Insert[1, 'P', 1]O2: Insert[1, 'A', 1]O1': Insert[1, 'P', 2]O2': Insert[2, 'A', 1]

PAAP→PPAP

Client BServerClient AClient BServerClient AO1: Delete[1, 'A', 2]O2: Insert[1, 'P', 3]O1': Delete[2, 'A', 2]O2': Insert[1, 'P', 2]

資料儲存架構

  • 將具有即時性的資料暫存在記憶體
  • 變更資料的同時標記此筆資料變更
  • 使用非同步 Workers 掃描變更資料並存回資料庫

Worker 的工作流程

Created with Raphaël 2.2.0資料存取暫存資料至記憶體資料是否被變更?儲存變更資料回資料庫刪除暫存資料是否逾時未變更?yesnoyesno

如何記錄修訂版本?

  • google-diff-match-patch
  • 只記錄 patch 減少重複內容

google-diff-match-patch

  • 基於 Myer's diff algorithm
  • 加上預處理 (加速)
  • 加上後處理 (減少多餘的結構)

diff 範例

  • old: 假的業障重, new: 假的暫時的
  • diff 得到:假的業障重暫時的
  • 轉成 GNU unified format patch
    ​​​​@@ -1,5 +1,5 @@ ​​​​ 假的 ​​​​-業障重 ​​​​+暫時的

只儲存 patch 減少資料量

  • 只有最新與最舊的版本會完整儲存
  • 當拿取中間版本時,由最靠近的完整版本 patch 回來
  • 從舊版本計算出較新版本 → patch
  • 從新版本計算到較舊版本 → inverse patch

如何整合套件

  • 要整合的無縫
  • 要能發揮它的力量
  • 了解它、修正它、Fork 它
  • 不吝給予回饋 (開 Issue、發 PR)

目前已整合的重要套件

  • CodeMirror
  • socket.io
  • OT
  • textcomplete
  • bootstrap
  • markdown-it
  • reveal.js
  • google-diff-match-patch

為何不重造輪子

  • 因為沒那麼多資源
  • 因為沒有那麼專業

為何重造輪子

  • 因為可以完全自訂
  • 因為可以知道細節

設計與核心思想

「懶」

懶得優雅

懶得簡潔


實踐方法

  • 只出現必要的元件
  • 注重微小的細節
  • 好的體驗是由無數個細節構成

自己吃吃看狗糧

  • 最好的電影是連導演都感動
  • 最棒的服務是連自己都驚嘆

社群是你最好的導師

  • 自己的痛點可能也是別人的痛點
  • 用 open source 實踐 MVP

別想單打獨鬥解決所有困難

  • 勇者,不要跟他拼拳,嘗試切他中路!
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 嘗試創造不存在那些痛點的世界 (但是有 tradeoffs)
  • 想法 → 課程專案 → Issue DD → Community DD

樂於與社群互動

  • 關心使用者,提供管道並傾聽他們的聲音
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 與敬佩的對手聯誼,市場夠大不要小氣
  • 研究 → 設計 → 實作 → 驗證 → 回饋

最好是免錢又大碗又好吃

  • 這是不可能的
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 必須在設計、開發、營運之間嘗試平衡
  • 將所有功能都集合的不一定是好產品

感謝貢獻與推廣

@clkao @neil @BlueT @ETblue @EvanWu @yukai @PeterDaveHello @ttcat @BobbyTung @xnum @au @g0v and more


感謝贊助

已收到超過 250 美元的捐贈!


搜尋並加入

Markdown 台灣


Q&A


HackMD
已列入
GitHub Integrations List


謝謝大家!

這份簡報使用 HackMD 製作
https://hackmd.io/p/Bk9X2eJT