Mark Text
By Zhewei Du, Ruijing Guo, Ke Qian, Wenke Huang
Group 9
School of Computer Science Wuhan University
Group information
Zhewei Du
Student ID: 2017302580148
GithHub: 450686168
E-mail address: [email protected]
TEL: 17371124051
Ruijing Guo
Student ID: 2017302580158
GithHub: 1301702486
E-mail address: [email protected]
TEL: 15932685926
Ke Qian
Student ID: 2017302580161
GithHub: Noseason
E-mail address: [email protected]
TEL: 15952626931
Wenke Huang
studentID: 2017302580159
GithHub: WenkeHuang
e-mail address: [email protected]
TEL: 13873185291
Abstract
Mark Text is a simple and elegant open-source markdown editor that focused on speed and usability. In this report, our team will analyze and discuss the architecture of Mark Text. Starting with the stakeholders. We give a context view to describe the different components involved and a development view to outline how Mark Text is developed and the ways in which contributions can be made. We discuss the functions view, which provides the functionalities and evolution of Mark Text. Lastly, we discuss Mark Text from a scalability and performance perspective. We end with a short conclusion summarizing our most interesting findings regarding Mark Text’s architecture.
Mark Text is a simple and elegant open-source markdown editor that focused on speed and usability. Mark Text has abandoned the way of writing on the left and previewing on the right like many markdown editors. On the contrary, Mark Text skillfully integrates editing and previewing together in one screen.
Many stakeholders play a part in the project-Marktext.
Assessors
The team of this project is consisted of two core developers and many other developers. As the projects are still in development where they can perfect the project step by step, they will take responsibilities to make the project better and plan the development of its future. They usually concern about the system’s conformance to standards and legal regulation.
Communicators
The people or introductions that explain the architecture of the project are the communicators. The biggest communicator is the Github, on which the developers can put up the documentation and get the bug reports about the project through the issue tracker. It’s very flexible and convenient. On the other hand, users can also contact the communicators by email named [email protected].
Developers
There are two kinds of developers. The one is core developers, the other is contributors.
As for other runtime qualities like Availability, Security, Scalability, Interoperability and robustness. They are also important, but not as important as the attributes above. And for other quality attributes during development, such as understandability, extensibility, reusability, testability and maintainability. They also play a certain roles in the Development period.
Power versus Interest
We extend upon the previous classification of stakeholders to include the power and interest of the various stakeholders. We do so by means of a power interest grid, of which the result is shown below. The stakeholders are classified into four categories.
Figure 2: Power-Interest grid for the stakeholders of Marktext
The context view describes the relationships, dependencies, and interactions between the system and its environment (the people, systems, and external entities with which it interacts). This section examines Mark Text’s scope, its dependencies on others and the interaction with other parties.
System scope
The system scope and responsibilities define what the system should do in order to fulfil its objective. For this application, Mark Text describes itself as a simple and elegant open-source markdown editor focused on speed and usability. Mark Text is a real-time preview (WYSIWYG) editor for markdown with various markdown extensions and our philosophy is to keep things clean, simple and minimal. It also uses virtual DOM to render pages which has the added benefits of being highly efficient and being open source.
Context model
Figure 3: Context Model of Mark Text
Users
Any markdown editor user.
Programming languages
Mark Text is built with HTML, JS and CSS on top of Electron. Currently they are using a few native node libraries and their UI is built with Vue/Vuex.
Supported platforms
Mark Text is a desktop application and available for:
Linux x64 (tested on Debian and Red Hat based distros)
macOS 10.10 x64 or later
Windows 7-10 x86 and x64
Testing frameworks
Mark Text is built with HTML+CSS+JavaScript, using karma
, mocha
, and spectron
testing framework.
Continuous integration
Mark Text uses AppVeyor (for Windows) and Travis CI (for Linux) for continuous integration.
Code quality
Mark Text uses ESLint to ensure its code quality and code style. Developers can execute the script yarn run lint
to check their code quality.
ESLint
ESLint is a static code analysis tool for identifying problematic patterns found in JavaScript code. Rules in ESLint are configurable, and customized rules can be defined and loaded. ESLint covers both code quality and coding style issues. ESLint supports current standards of ECMAScript, and experimental syntax from drafts for future standards.
Dependencies
Mark Text uses Electron as its backend framework and Vue as its frontend framework. It uses a few native Node.js modules to provide an interface between JavaScript running in Node.js and C/C++ libraries, and CodeMirror to assist with source code editing functionality (recall that Mark Text provides users with Source Code mode, Typewriter mode and Focus mode).
Sponsors
Sponsoring occurs in three ways: via Patreon, One Time Donations or Open Collective. Sponsored by Patreon/One Time Donation, it will be directly sponsored to Luo Ran (@jocs), who create Mark Text and continue to maintain Mark Text. Sponsored by Open Collective, all expenses are transparent, and these sponsorship funds will be used for the development of Mark Text. Qordoba and readme are two major sponsors.
Development
Development is carried on by the contributors of GitHub open source community using GitHub as a version control and issue tracking tool. Mark Text offers a Contributing Guide to those who want to make improvements.
Communication
Communication and support is provided via GitHub and Twitter.
Competitors
There are many other free-of-charge markdown editors available, and the most similar one is Typora. Typora supports all the features that Mark Text supports, and its advantage is that it can export files in more formats. But for the novice, it’s not as easy to use as Mark Text.
License
Mark Text is licensed under the MIT License—a short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.
The deployment view looks at parts of the system that are relevant once it has been built. It defines physical, computational, and software-based requirements for running the system.
A diagram of the deployment view is given in the below figure.
Figure 4: * Deployment view*
High-level view
Figure 5: * High-level view*
Each time a user opens a file, a new tab is created. First, the user opens a markdown file from a local path, then the application (App instance) calls openTab on the specified editor window. The editor window then loads the file and raise open-new-tab event to send the file to renderer process. The renderer process handles the event, creates a markdown document and a new tab. The created tab is either opened and raises file-changed event or nothing is changed if the newly opened file is the same as current file. Text editors–Muya and source code editor–handle the file-changed event and make according changes to the markdown document.
Module structure view
The module structure model defines the organization of the system’s code clustering related source code files into modules and determining the dependencies between them. In this section, first the modules of the project are briefly described and then the dependencies between them are visualized in a diagram. It should be also noted that this section focuses only on the internal modules of the project and not the external dependencies.
app
– accessor.js
Construct the application environment instance
– env.js
Create a (global) application environment instance and bootstraps the application
Returns an unique identifier that can be used with IPC to identify messages from this environment
– index.js
It is the entry point of the application.
–path.js
Configure and sets all application paths
–windowManage.js
Control the windows list
cli
–index.js
Check for portable mode and ensure the user data path is absolute.
We assume that the path is writable if not this lead to an application crash.
–parse.js
Parse the given arguments or the default program arguments.
dataCenter
–index.js
Different data
–schema.json
Define the structure of different types of data when passing through the application.
fileSystem
–index.js
Param {string} pathname The path or link path.
returns {string}
Returns the absolute path and resolved link. If the link target
Cannot be resolved, an empty string is returned.
–markdown.js
Function to normalize directory and markdown file paths
Write the content into a file.
Reads the contents of a markdown file.
–watcher.js
Watch a file or directory and return an unwatched function
Just to be sure when a file is replaced with a directory don’t watch recursively.
Ignore the next changed event within a certain time for the current file and window.
Check whether we should ignore the current event because the file may be changed from Mark Text itself.
keyboard
Full list of supported virtual keys
preference
–index.js
In charge of constructing the Preference class which extends from EventEmitter
–schema.json
this file define the construct of different tasks two properties: description and type.
utils
–index.js
Read the title from the renderer cache because this regex matches in code blocks
–pandoc.js
–imagePathAutoComplement.js
Return an array of directories and files without caching and watching
windows
–base.js
Make a Mark Text window
–editor.js
The application accessor for application instances.
Creates a new editor window.
Enable native or custom/frameless window and titlebar
Create a menu for the current window
Restore and focus window
Open a new tab from a markdown file
Open new tabs from the given file paths.
–setting.js
Creates a new setting window.
The module structure and dependencies are shown below:
Figure 6: Module structure and dependencies
Source code structure view
All the structure of the directory hierarchy of the MarkText is organized in the way below. The root folder consists of some files that are used to configure the system. At first, there are some YAML files that are responsible for configuring the continuous integration of the project, like travis.yml, appveyor.yml and electron-builder.yml. Moreover, the file named yarn.lock is also very important. It’s used to check and share the dependencies for it contains the exact information of every version and it can also verification the codes. As for other files, they include the description document and the configuration file of Vue frame.
Furthermore, the root folder is divided into nine different folders. The electron-vue\ folder is used to supportand build the desktop application and then use the web page as the GUI. The guthub\ folder contains the change log files about the projects including the bug-report and etc. The .vscode/ sets up the settings and launch parameters when it’s opened in vscode. The doc/ is the folder where all the documentation files that are built using Markdown editor located. The resources/ contains all the assets being used while the Application is at build time in the Windows and Linux. The tools/ folder contains tools used in the build process and the test/ folder contains(unit) tests. The static/ folder includes All the application assets(images, themes, etc).
The most important folder is called src/ and it’s also divided into four folders. The common/ is the folder where common source files that only require Node.js APIs. Code from this folder can be used in all other folders except muya. The main/ includes main process source files that require Electron main-process APIs. The muya/ contains Mark Texts backend that only allow pure JavaScript, BOM and DOM APIs. It’s it the editor backend with modules for markdown parsing, data store as block structure, markdown document transformations according CommonMark and GitHub Flavored Markdown specification with some extra specifications, event listeners and an exporter to generate standalone HTML and markdown files but also to generate the WYSIWYG editor. The renderer/ Fontend that require Electron renderer-process APIs and may use common or muya source code. It’s responsible for all graphical elements, data and data synchronization. A renderer process is spawned for each window, operates on its own and is controlled by the main process.
Figure 7: Source code structures
Continuous integration and testing approach
Testing Approach
Mark Text is built with HTML+CSS+JavaScript, using karma
, mocha
, and spectron
testing framework.
Karma
is a simple tool that allows you to execute JavaScript code in multiple real browsers.
Mocha
is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.
Spectron
is an open source framework for easily writing integrations tests for Electron apps. Spectron sets up and tears down your app and allows it to be test-driven remotely with full support for the Electron APIs.
Mark Text writes its own test cases to perform e2e (end to end) tests and XSS (cross-site scripting) tests, as well as unit tests to ensure the conformance with GFM (GitHub Flavored Markdown). A developer can run unit tests by executing the following commands: yarn run e2e
, or yarn run unit
, or yarn run test
, which includes th former two. You can also use npm
instead of yarn
.
Continuous Integration
Continuous Integration (CI) refers to the development practice in which developers integrate the code to a shared repository frequently. Each integration is verified by an automated build and test system. Mark Text uses Travis CI
for testing on Linux, and AppVeyor
for testing on Windows.
Travis CI
is a hosted continuous integration service used to build and test software projects hosted at GitHub. It is configured by adding a file named .travis.yml
, which is a YAML format text file, to the root directory of the repository. AppVeyor
woks in a similar way.
Mark Text has configured both Travis CI and AppVeyor, such that testing is done on Node.js 12
, while automatically checking code quality using ESLint, validating license, running unit and e2e tests, and calculating checksums.
The functional view defines the architectural elements that deliver the function of the system being described. This view documents the key runtime functional elements, their responsibilities, interfaces and primary interactions. In the marktext project, different key functional elements are present that interact with internal and external elements during run-time. But these functional elements do behave like interfaces, as they have well-defined functions that can be called by other elements, to perform different actions. The functional view of our project is visualised on figure 1. The key elements and the interaction between them is described next.
Figure 8: * Functional view*
There are two entry points to the application: src/main/index.js for the main process that is executed first and only once per instance. Once the application is initialized, it’s safe to access all the environment variables and single-instances and the application (App) is started (src/main/app/index.js). You can use the application after App::init() is run successfully. src/renderer/main.js for each editor window. At the beginning libraries are loaded, the window is initialized and Vue components are mounted.
Muya is the core of Mark Text. Muya provides real-time preview and markdown editing via multiple modules based on a block structure. It is the editor backend with modules for markdown parsing, data store as block structure, markdown document transformations according CommonMark and GitHub Flavored Markdown specification with some extra specifications, event listeners and an exporter to generate standalone HTML and markdown files but also to generate the WYSIWYG editor. Muya is single threaded as well as Mark Text but use asynchronous functions to boost performance.
Mark Text’s source-code editor is provided by CodeMirror and not well optimized nor feature rich. It’s not part of Muya and an editor (renderer process) feature that load the markdown text from Muya (export), operate on it and re-import the text into Muya when switching to preview mode.
The editor represents the view and is split into two parts. The first is the main process that have full access to Electron and all OS features. It’s mainly used for IO, user interaction with native dialogs and controls the editor windows. The main process should not (be long) blocked by synchronous operations. The renderer process is the real editor and also a host for Muya. It’s responsible for all graphical elements (src/renderer/components), data (src/renderer/store) and data synchronization. A renderer process is spawned for each window, operates on its own and is controlled by the main process. It contains two text editors: the real-timepreview editor provided by Muya and the source-code one by CodeMirror with special features such as tabs, sidebar and editing features.
The technical debt concept is mostly related to some development work that is still not very suitable for the project in the long run. It is usually easy to implement in the short run, and can fulfill the require during a period. Not only the code, but also the (lack of) documentation and low testing coverage can be a part of it.
And in this section, we will focus on the following three kinds of technical debt: code debt, testing debt, and documentation debt.
Code Debt
For the code section, it’s significant for us to deal with the debt before it’s too late. Cause the size of code is continuously increasing, it will be more difficult for us to maintain the code. And in this project, the code debt has been paying through both analysis tools and manual inspection.
This project is in full development and everyone has chance to contribute to it. One must read the Contributing Guide before making a pull request, and there are lots of rules in the documentation. As for the code style, the contributor has to ESLint(yarn run lint) to follow the style guide. For example, is must use 2 space indent and have no semicolons. The JS language is dynamic and you can write it arbitrarily, so the test of ESLint can make the code stronger and help to keep our code style consistent. After pass the test, the contributor can finally submit the PR.
Another way to check the code debt is to look through the ROADMAP documentation or keep an eye on the issues where some users will report the bug. The ROADMAP has a long TODO lists. At the Optimization and Refactor part, there is a mission to Optimize Muya’s data structure and split the current block into Block and Delta. Block is a data structure parallel to the DOM, children is a linked list, and the entire Block is a tree. This will better render the block into a DOM. Delta is a data structure corresponding to the Markdown text. It supports additions and deletions, and supports Undo and Redo for History. Support collaborative editing. At the New Feature part, it requests to rewrite mark text side bar UI, add more custom markdown syntax, subscript and superscript etc. and so on. At the websites part, it requests to update the official website, add detailed documents and videos, sponsor advertisements, and so on. And some features in the ROADMAP has been finished already. For the FIX part, one has to check the issues and find the bug. Then add the “fix: # ” in the PR tittle which you will submit. Up to now there are hundreds of bugs has been fixed and you can check them in the CHANGELOG documentation.
Test Debt
Mark Text’s unit testing is analyzed by karma
and e2e testing is analyzed by mocha
, and the code coverage of unit tests is reported by Istanbul
. To view the result of unit tests, however, one has to build the project first, then execute the command yarn run unit
, which will create a subfolder coverage
in test\unit\
that contains the coverage result for all files by running unit test cases in test\unit\data\
folder. The result is shown below:
=================== Coverage summary ==================
Statements : 11.37% ( 1483/13040 )
Branches : 5.43% ( 374/6886 )
Functions : 5.44% ( 114/2097 )
Lines : 11.33% ( 1437/12684 )
====================================================
(and Muya (the markdown parser) failed to parse certain cases of List into html format, which is a bug)
Part of the coverage result in graphical representation is illustrated below:
Figure 8: Part of the converage result
We can conclude that Mark Text currently has significant test debt, since most of its code bases are untested, plus there is a pretty serious bug needed to be fixed. Besides, this approach of examining coverage result is really confusing for new beginners, and very inconvenient.
Documentation Debt
Developers need to write documentation of their source code to help others understand the system and its setup, so that one can learn how to contribute to this project. In addition, user documentation is also necessary for illustrating how to install and use the product. The biggest debt of Mark Text is found in the documentation for developers.
First of all, as mentioned above, where to find the test coverage result is not mentioned in the documentation, nor is the information of continuous integration framework and testing framework (which is eventually extracted from the file package.json). If a developer wanted to increase the code coverage of unit tests, it would be very difficult to start with.
More importantly, the documentation for explaining the system architecture is severely in debt—the explanation for its core module, Muya, is basically none, nor is the illustration for Editor window (renderer process). This lack of explanation prevents other developers from improving Mark Text to a large extend.
The past:
Markdown editors have always been popular in the two-window structure (one window editing, one window previewing), then came Typora, its concise, elegant appearance and WYSIWYG (what you see is what you get) design concept immediately attracted many Markdown writers. And it is very efficient for writers to quickly write their ideas. So the preference of the Markdown style has gradually changed from two-window structure to WYSIWYG. But related Markdown editor is not very mature or satisfying.
The present:
Nowadasy, Mark Text has become a famous high-performance Markdown editor. And it can run on Mac, Windows and Linux platform. Its simple appearance and the process of operation give you a comfortable writing experience. Mark Txt will be permanently open source Markdown editor. And the current version is still not prefect. It still need everyone contribute code to improve Mark Text.
The Future:
The revolution of Mark Text has never stopped. The main developers of the project have been posting issues on GitHub to solicit comments on the features of it. In the future, more features will be implemented. For example, turn into menu item in the Front menu will be migrated to the touch bar. Migrate the format tool bar to the touch bar and hope to customize it. There will be table operations such as adding rows/columns, deleting rows/columns, moving rows/columns, cell alignment, copying, and deleting tables. There will also be list operations such as conversions between lists (task list, bullet list and order list), list indentation, etc. Mark Text will support code block operation such as copy, delete code block, code block language selection. The function of searching for emojis and the visibility of sidebar will be realized.
At the same time, they are looking for further contributions to continuously improve Mark Text. Mark Text is a hobby project created by @Jocs and later @fxha joined this awesome project. They both love this project but their time is also limited to maintain and develop Mark Text. In the future there should be more and more contributors until Mark Text becomes a stable but also a fast and more performant editor.
Figure 9: The issues posted by main contributors.
This documentation summarized Mark Text in many architectural views and perspectives, helping the reader to be able to understand and contribute to the project.
In the first section, the stakeholder analysis discussed the various classes of stakeholders involved in the project. Mark Text is mainly used by scientists and learners. It’s supported by two main developers and supported by the GitHub community.
The context view describes the relationships, dependencies, and interactions between the system and its environment (the people, systems, and external entities with which it interacts). This section examines Mark Text’s scope, its dependencies on others and the interaction with other parties.
The deployment view looks at parts of the system that are relevant once it has been built. It defines physical, computational, and software-based requirements for running the system.
The development view describes the architecture of a project from the viewpoint of the developers.
The functional view defines the architectural elements that deliver the function of the system being described.
The technical debt concept is related to the extra development work that is introduced when solutions that are easy to implement in the short run are used instead of applying the optimal ones that will keep the project maintainable in the long run.
Even though the documentation of the project was not enough and the analysis of the project’s architecture proved to be challenging, our team finally managed to understand the architecture of the system. We learned that real-world software does not always correspond to the ideal architectures that we discuss in theory, to reach the ideal effect, it must make some changes in many parts of the project. We learned that the community of GitHub played a vital role in the success of Mark Text. We expect to see the Mark Text project gain more and more contributors and users in a better future.
[1] MarkText https://github.com/marktext/marktext
[2] Babel doc https://babeljs.io/docs/en/
[3] Mark Text 新版本 - 千呼万唤始出来 https://cnodejs.org/topic/5d4bd48e697873456c6bbe4c
[4]electron-vue test https://simulatedgreg.gitbooks.io/electron-vue/cn/testing.html
[5] continuous-integration https://www.softwaretestinghelp.com/continuous-integration/
[6] technical-debt-and-qa https://www.softwaretestinghelp.com/technical-debt-and-qa/
[7] istanbul https://github.com/gotwarlost/istanbul