├── dist
└── .gitkeep
├── lib
├── index.js
├── actions
│ ├── PDFAction.js
│ └── EditorAction.js
├── MainContext.js
├── components
│ ├── MarkdownPreview.js
│ ├── PDFViewer.js
│ ├── MarkdownEditor.js
│ └── MarkdownToolbar.js
├── utils
│ └── FileUtils.js
├── stores
│ ├── PDFStore.js
│ └── EditorStore.js
└── App.js
├── .gitmodules
├── test
├── Ecma-262_5.1.pdf
└── es5.md
├── css
├── components
│ ├── _App.scss
│ ├── _PDFViewer.scss
│ ├── _MarkdownToolbar.scss
│ ├── _MarkdownEditor.scss
│ └── _MarkdownPreview.scss
├── index.scss
├── layout
│ └── _Applayout.scss
├── index.css.map
└── index.css
├── web.html
├── _travis
└── build.sh
├── .travis.yml
├── LICENSE
├── package.json
├── index.html
├── README.md
└── .gitignore
/dist/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | module.exports = require("./App");
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "pdfjs"]
2 | path = pdfjs
3 | url = https://github.com/mozilla/pdf.js.git
4 |
--------------------------------------------------------------------------------
/test/Ecma-262_5.1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azu/pdf-markdown-annotator/HEAD/test/Ecma-262_5.1.pdf
--------------------------------------------------------------------------------
/css/components/_App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0;
6 | border: none;
7 | }
--------------------------------------------------------------------------------
/css/components/_PDFViewer.scss:
--------------------------------------------------------------------------------
1 | .PDFViewer {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0;
6 | border: none;
7 | }
--------------------------------------------------------------------------------
/css/components/_MarkdownToolbar.scss:
--------------------------------------------------------------------------------
1 |
2 | .MemoToolbar {
3 | height: 1.2rem;
4 | background-color: white;
5 | .fa::before {
6 | margin-right: 0.5em;
7 | margin-left: 0.2em;
8 | }
9 | }
--------------------------------------------------------------------------------
/css/components/_MarkdownEditor.scss:
--------------------------------------------------------------------------------
1 | .MarkdownEditor, .MarkdownEditor > div {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0;
6 | border: none;
7 | }
8 |
9 | .MarkdownEditor .CodeMirror {
10 | height: 100%;
11 |
12 | }
13 |
14 | .MarkdownEditor .CodeMirror, .MarkdownEditor textarea {
15 | font-size: 16px;
16 | }
--------------------------------------------------------------------------------
/css/index.scss:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0;
6 | }
7 |
8 | * {
9 | box-sizing: border-box;
10 | }
11 |
12 | @import "./components/App";
13 | @import "./components/PDFViewer";
14 | @import "./components/MarkdownEditor";
15 | @import "./components/MarkdownToolbar";
16 | @import "./components/MarkdownPreview";
17 | @import "./layout/Applayout";
18 |
--------------------------------------------------------------------------------
/lib/actions/PDFAction.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | import { Action } from "material-flux"
4 | export var keys = {
5 | loadURL: Symbol("loadURL"),
6 | changeViewerPath: Symbol("changeViewerPath")
7 | };
8 | export default class PDFAction extends Action {
9 | load(url) {
10 | this.dispatch(keys.loadURL, url);
11 | }
12 |
13 | changeViewerPath(filePath) {
14 | this.dispatch(keys.changeViewerPath, filePath);
15 | }
16 | }
--------------------------------------------------------------------------------
/lib/MainContext.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | import {Context} from 'material-flux';
4 | import EditorAction from "./actions/EditorAction"
5 | import EditorStore from "./stores/EditorStore"
6 | import PDFAction from "./actions/PDFAction"
7 | import PDFStore from "./stores/PDFStore"
8 |
9 | export default class MainContext extends Context {
10 | constructor() {
11 | super();
12 | this.editorAction = new EditorAction(this);
13 | this.PDFAction = new PDFAction(this);
14 | this.PDFStore = new PDFStore(this);
15 | this.editorStore = new EditorStore(this);
16 | }
17 | }
--------------------------------------------------------------------------------
/web.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | web app
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
--------------------------------------------------------------------------------
/_travis/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [[ "$TRAVIS_TAG" ]]; then
4 | rm -rf build
5 | npm run dist
6 | cd build
7 | # ziped in build/
8 | zip -q pdf-markdown-annotator-osx32.zip -r pdf-markdown-annotator/osx32
9 | zip -q pdf-markdown-annotator-osx64.zip -r pdf-markdown-annotator/osx64
10 | zip -q pdf-markdown-annotator-win32.zip -r pdf-markdown-annotator/win32
11 | zip -q pdf-markdown-annotator-win64.zip -r pdf-markdown-annotator/win64
12 | zip -q pdf-markdown-annotator-linux32.zip -r pdf-markdown-annotator/linux32
13 | zip -q pdf-markdown-annotator-linux64.zip -r pdf-markdown-annotator/linux64
14 | cd ../
15 | echo "ziped!"
16 | else
17 | echo "Not Release"
18 | fi
--------------------------------------------------------------------------------
/css/layout/_Applayout.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | display: flex;
3 | }
4 |
5 | .PDFViewer-container {
6 | width: 50%;
7 | height: 100%;
8 | margin: 0;
9 | padding: 0;
10 | border: none;
11 | overflow: hidden;
12 | flex: 7;
13 | }
14 |
15 | .MarkdownEditor-container {
16 | width: 50%;
17 | height: 100%;
18 | margin: 0;
19 | padding: 0;
20 | border: none;
21 | overflow: hidden;
22 | flex: 3;
23 | }
24 |
25 | // MarkdownEditor flex layout
26 | .MarkdownEditor-container {
27 | display: flex;
28 | flex-flow: column;
29 | .MarkdownEditorToolbar {
30 | height: 1rem;
31 | }
32 | .MarkdownEditor {
33 | height: calc(100% - 1rem);
34 | }
35 | .MarkdownPreview {
36 | height: calc(100% - 1rem);
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | after_success:
4 | - npm install
5 | - "./_travis/build.sh"
6 | cache:
7 | directories:
8 | - node_modules
9 | deploy:
10 | provider: releases
11 | api_key:
12 | secure: KJsSpFlo/4KwGNzwLuezz4lj7gC1Sb9An4naKEOi0/UnbTatj9X/o3mS+4JIp92n+QEeqy2c6D5s4V1VJ0HexFHbbLd0vyeon4uTN1jTICqU7LGO/eatA+XZi52kJV7GWPJlSCEki19t+ovQBeZP6MLWRytTTXAQiLwQqfsFS2E=
13 | file:
14 | - "build/pdf-markdown-annotator-osx32.zip"
15 | - "build/pdf-markdown-annotator-osx64.zip"
16 | - "build/pdf-markdown-annotator-win32.zip"
17 | - "build/pdf-markdown-annotator-win64.zip"
18 | - "build/pdf-markdown-annotator-linux32.zip"
19 | - "build/pdf-markdown-annotator-linux64.zip"
20 | skip_cleanup: true
21 | on:
22 | repo: azu/pdf-markdown-annotator
23 | tags: true
--------------------------------------------------------------------------------
/lib/components/MarkdownPreview.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var React = require("react");
3 | var Markdown = require('react-remarkable');
4 | export default class MarkdownPreview extends React.Component {
5 | onClick(event) {
6 | var aTag = event.target;
7 | if (aTag.nodeName !== "A") {
8 | return;
9 | }
10 | var href = aTag.getAttribute("href");
11 | if (/\.pdf/.test(href)) {
12 | this.props.context.PDFAction.load(href);
13 | event.stopPropagation();
14 | event.preventDefault();
15 | }
16 | }
17 |
18 | render() {
19 | return (
20 |
25 | )
26 | }
27 | }
--------------------------------------------------------------------------------
/lib/utils/FileUtils.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | export default class FileUtils {
4 | static openSaveAs(saveAsFile) {
5 | var input = document.createElement("input");
6 | input.type = "file";
7 | input.setAttribute('nwsaveas', true);
8 | var listener = function (evt) {
9 | saveAsFile(this.value);
10 | input.removeEventListener("change", listener, false);
11 | };
12 | input.addEventListener("change", listener, false);
13 | input.click();
14 | }
15 |
16 | static openFile(openAsFile) {
17 | var input = document.createElement("input");
18 | input.type = "file";
19 | var listener = function (evt) {
20 | openAsFile(this.value);
21 | input.removeEventListener("change", listener, false);
22 | };
23 | input.addEventListener("change", listener, false);
24 | input.click();
25 | }
26 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 azu
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/lib/components/PDFViewer.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | var React = require("react");
4 | var path = require("path");
5 | export default class PDFViewer extends React.Component {
6 | componentDidMount() {
7 | this.iframe = React.findDOMNode(this);
8 | this.iframe.addEventListener("load", this._onPDFLoad.bind(this));
9 | }
10 |
11 | // TODO: https://github.com/mozilla/pdf.js/pull/5915
12 | _onPDFLoad(event) {
13 | // auto save per 5s
14 | setInterval(this._onAutoSave.bind(this), 5000);
15 | }
16 |
17 | _onAutoSave() {
18 | var url = this.iframe.contentWindow.PDFViewerApplication.url;
19 | localStorage.setItem("pdfFile-URL", url);
20 | }
21 |
22 | componentWillUnmount() {
23 | }
24 |
25 | render() {
26 | var pdfURL = this.props.pdfURL;
27 | var filePath = this.props.context.editorStore.getFilePath();
28 | var viewerPath = this.props.context.PDFStore.getViewerPath();
29 | var query = "";
30 | if (pdfURL && filePath) {
31 | var dirPath = path.dirname(filePath);
32 | query = "?file=" + path.resolve(dirPath, pdfURL);
33 | } else if (pdfURL) {
34 | query = "?file=" + pdfURL;
35 | }
36 | return (
37 |
38 | )
39 | }
40 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pdf-markdown-annotator",
3 | "repository": {
4 | "type": "git",
5 | "url": "https://github.com/azu/pdf-markdown-annotator.git"
6 | },
7 | "author": "azu",
8 | "email": "azuciao@gmail.com",
9 | "homepage": "https://github.com/azu/pdf-markdown-annotator",
10 | "license": "MIT",
11 | "bugs": {
12 | "url": "https://github.com/azu/pdf-markdown-annotator/issues"
13 | },
14 | "version": "1.0.12",
15 | "description": "pdf annotator + markdown editor",
16 | "main": "index.html",
17 | "directories": {
18 | "test": "test"
19 | },
20 | "scripts": {
21 | "build": "browserify -s bootstrap -t babelify lib/index.js -o dist/build.js",
22 | "dist": "nwbuild -v v0.12.1 -p 'win,osx,linux32,linux64' ./ -o ./build"
23 | },
24 | "keywords": [
25 | "markdown",
26 | "pdf",
27 | "annotation"
28 | ],
29 | "dependencies": {
30 | "codemirror": "^5.2.0",
31 | "font-awesome": "^4.3.0",
32 | "lodash.debounce": "^3.1.0",
33 | "material-flux": "^1.2.0",
34 | "node-webkit-winstate": "^1.1.0",
35 | "nw-normalize-menu": "^1.0.2",
36 | "pdfjs-dist": "^1.1.86",
37 | "react": "^0.13.2",
38 | "react-code-mirror": "^3.0.4",
39 | "react-remarkable": "^1.1.1"
40 | },
41 | "devDependencies": {
42 | "babel": "^5.1.13",
43 | "babelify": "^6.0.2",
44 | "browserify": "^9.0.8",
45 | "node-webkit-builder": "^1.0.11"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/actions/EditorAction.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | import { Action } from "material-flux"
4 | import FileUtils from "../utils/FileUtils"
5 |
6 | export var keys = {
7 | quote: Symbol("quote"),
8 | createNewFile: Symbol("createNewFile"),
9 | saveAsFile: Symbol("saveAsFile"),
10 | openFile: Symbol("openFile"),
11 | save: Symbol("save"),
12 | readonly: Symbol("readonly")
13 | };
14 | export default class EditorAction extends Action {
15 | save(text) {
16 | this.dispatch(keys.save, text);
17 | }
18 |
19 | /**
20 | * filePath is options, if filePath is null, open file dialog.
21 | * @param {string?} filePath save the text to the filePath.
22 | */
23 | saveAsFile(filePath) {
24 | if (filePath == null) {
25 | FileUtils.openSaveAs(this.saveAsFile.bind(this));
26 | } else {
27 | this.dispatch(keys.saveAsFile, filePath);
28 | }
29 | }
30 |
31 | createNewFile() {
32 | this.dispatch(keys.createNewFile);
33 | }
34 |
35 | changeReadonly(boolean){
36 | this.dispatch(keys.readonly, boolean);
37 | }
38 |
39 | openFile(filePath) {
40 | if (filePath == null) {
41 | FileUtils.openFile(this.openFile.bind(this));
42 | } else {
43 | this.dispatch(keys.openFile, filePath);
44 | }
45 | }
46 |
47 | quote(text) {
48 | this.dispatch(keys.quote, text);
49 | }
50 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
37 |
38 |
--------------------------------------------------------------------------------
/lib/stores/PDFStore.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | // LICENSE : MIT
4 | "use strict";
5 | import { Store } from "material-flux"
6 | import { keys } from "../actions/PDFAction"
7 | var path = require("path");
8 | export default class EditorStore extends Store {
9 | constructor(context) {
10 | super(context);
11 | this.state = {
12 | URL: "",
13 | viewerPath: path.join(__dirname, "..", "..", "pdfjs/web/viewer.html")
14 | };
15 | this.register(keys.loadURL, this.onLoadURL);
16 | this.register(keys.changeViewerPath, this.onChangeViewerPath);
17 |
18 |
19 | // initial load
20 | var filePath = localStorage.getItem("pdfFile-URL");
21 | this.onLoadURL(filePath);
22 | this.onChange(function () {
23 | if (this.state.URL) {
24 | localStorage.setItem("pdfFile-URL", this.state.URL);
25 | } else {
26 | localStorage.removeItem("pdfFile-URL");
27 | }
28 | });
29 | }
30 |
31 | getURL() {
32 | return this.state.URL;
33 | }
34 |
35 | getViewerPath() {
36 | return this.state.viewerPath;
37 | }
38 |
39 | onChangeViewerPath(filePath) {
40 | this.setState({
41 | viewerPath: filePath
42 | });
43 | }
44 |
45 | onLoadURL(URL) {
46 | if (URL == null) {
47 | return;
48 | }
49 | this.setState({
50 | URL: URL
51 | });
52 | }
53 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pdf-markdown-annotator [](https://travis-ci.org/azu/pdf-markdown-annotator)
2 |
3 |
4 | This [NW.js](http://nwjs.io/ "NW.js") app is that PDF Viewer and Markdown annotation/Note tools.
5 |
6 | 
7 |
8 | ## Installation
9 |
10 | - [Download latest binary](https://github.com/azu/pdf-markdown-annotator/releases/latest)
11 |
12 | OS X, Windows, Linux support.
13 |
14 | ## Feature
15 |
16 | - PDF Viewer using [pdf.js](https://github.com/mozilla/pdf.js)
17 | - Markdown memo using [CodeMirror](http://codemirror.net/)
18 | - Quote text from PDF
19 |
20 | 
21 |
22 | ## Usage
23 |
24 | - Open PDF file
25 | - Open Markdown file
26 | - write note & save
27 | - Automatically save
28 |
29 | ### On Browser
30 |
31 | pdf-markdown-annotator work on Browser too!
32 |
33 | ```
34 | npm run build
35 | # output dist/build.js
36 | ```
37 |
38 | ```html
39 |
40 |
50 | ```
51 |
52 |
53 | ## Contributing
54 |
55 | 1. Fork it!
56 | 2. Create your feature branch: `git checkout -b my-new-feature`
57 | 3. Commit your changes: `git commit -am 'Add some feature'`
58 | 4. Push to the branch: `git push origin my-new-feature`
59 | 5. Submit a pull request :D
60 |
61 | ## License
62 |
63 | MIT
64 |
65 | ## Thanks
66 |
67 | Inspired by [Highlights App for Mac](http://highlightsapp.net/ "Highlights App for Mac")
68 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### https://raw.github.com/github/gitignore/408c616ae0ad8f4b8101d8e876b9b67ac6b14059/Node.gitignore
2 |
3 | # Logs
4 | logs
5 | *.log
6 |
7 | # Runtime data
8 | pids
9 | *.pid
10 | *.seed
11 |
12 | # Directory for instrumented libs generated by jscoverage/JSCover
13 | lib-cov
14 |
15 | # Coverage directory used by tools like istanbul
16 | coverage
17 |
18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
19 | .grunt
20 |
21 | # node-waf configuration
22 | .lock-wscript
23 |
24 | # Compiled binary addons (http://nodejs.org/api/addons.html)
25 | build/Release
26 |
27 | # Dependency directory
28 | # Commenting this out is preferred by some people, see
29 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
30 | node_modules
31 |
32 |
33 | ### https://raw.github.com/github/gitignore/408c616ae0ad8f4b8101d8e876b9b67ac6b14059/Global/JetBrains.gitignore
34 |
35 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
36 |
37 | *.iml
38 |
39 | ## Directory-based project format:
40 | .idea/
41 | # if you remove the above rule, at least ignore the following:
42 |
43 | # User-specific stuff:
44 | # .idea/workspace.xml
45 | # .idea/tasks.xml
46 | # .idea/dictionaries
47 |
48 | # Sensitive or high-churn files:
49 | # .idea/dataSources.ids
50 | # .idea/dataSources.xml
51 | # .idea/sqlDataSources.xml
52 | # .idea/dynamic.xml
53 | # .idea/uiDesigner.xml
54 |
55 | # Gradle:
56 | # .idea/gradle.xml
57 | # .idea/libraries
58 |
59 | # Mongo Explorer plugin:
60 | # .idea/mongoSettings.xml
61 |
62 | ## File-based project format:
63 | *.ipr
64 | *.iws
65 |
66 | ## Plugin-specific files:
67 |
68 | # IntelliJ
69 | out/
70 |
71 | # mpeltonen/sbt-idea plugin
72 | .idea_modules/
73 |
74 | # JIRA plugin
75 | atlassian-ide-plugin.xml
76 |
77 | # Crashlytics plugin (for Android Studio and IntelliJ)
78 | com_crashlytics_export_strings.xml
79 | crashlytics.properties
80 | crashlytics-build.properties
81 |
82 |
83 |
84 | build.js
--------------------------------------------------------------------------------
/lib/App.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | var React = require("react");
4 | var PDFViewer = require("./components/PDFViewer");
5 | var MarkdownToolbar = require("./components/MarkdownToolbar");
6 | var MarkdownEditor = require("./components/MarkdownEditor");
7 | var MarkdownPreview = require("./components/MarkdownPreview");
8 | import MainContext from "./MainContext.js"
9 | var context = new MainContext();
10 | class App extends React.Component {
11 | constructor(props) {
12 | super(props);
13 | this.PDFStore = context.PDFStore;
14 | this.editorStore = context.editorStore;
15 | this.state = {
16 | readonly: this.editorStore.isReadonly(),
17 | pdfURL: this.PDFStore.getURL()
18 | };
19 | }
20 |
21 | componentDidMount() {
22 | this.PDFStore.onChange(this._PDFonChange.bind(this));
23 | this.editorStore.onChange(this._editorChange.bind(this));
24 | }
25 |
26 | _editorChange() {
27 | this.setState({
28 | readonly: this.editorStore.isReadonly()
29 | });
30 | }
31 |
32 | _PDFonChange() {
33 | this.setState({
34 | pdfURL: this.PDFStore.getURL()
35 | });
36 | }
37 |
38 | componentWillUnmount() {
39 | this.PDFStore.removeAllChangeListeners();
40 | this.editorStore.removeAllChangeListeners();
41 | }
42 |
43 | render() {
44 | // toggle by MarkdownToolbar
45 | var MarkdownComponent;
46 | if (this.state.readonly) {
47 | MarkdownComponent = ;
48 | } else {
49 | MarkdownComponent =
50 | }
51 | return (
52 |
53 |
56 |
57 |
58 | {MarkdownComponent}
59 |
60 |
61 | )
62 | }
63 | }
64 |
65 | /**
66 | * bootstrap function
67 | * optional: to pass object { pdfURL, markdownURL }
68 | */
69 | module.exports = function bootstrap({
70 | pdfURL,
71 | markdownURL,
72 | viewerPath
73 | } = {}) {
74 | if (viewerPath) {
75 | context.PDFAction.changeViewerPath(viewerPath);
76 | }
77 | if (pdfURL) {
78 | context.PDFAction.load(pdfURL);
79 | }
80 | if (markdownURL) {
81 | context.editorAction.openFile(markdownURL);
82 | context.editorAction.changeReadonly(true);
83 | }
84 |
85 | React.render(, document.body);
86 | };
87 |
--------------------------------------------------------------------------------
/lib/components/MarkdownEditor.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | var React = require("react");
4 | var ReactCodeMirror = require("react-code-mirror");
5 | require("codemirror/addon/mode/overlay.js");
6 | require("codemirror/mode/xml/xml.js");
7 | require("codemirror/mode/markdown/markdown.js");
8 | require("codemirror/mode/gfm/gfm.js");
9 | require("codemirror/mode/javascript/javascript.js");
10 | require("codemirror/mode/css/css.js");
11 | require("codemirror/mode/htmlmixed/htmlmixed.js");
12 | require("codemirror/mode/clike/clike.js");
13 | require("codemirror/mode/meta.js");
14 | require("codemirror/addon/edit/continuelist.js");
15 |
16 |
17 | function scrollToBottom(cm) {
18 | var line = cm.lineCount();
19 | cm.setCursor({line: line, ch: 0});
20 | var myHeight = cm.getScrollInfo().clientHeight;
21 | var coords = cm.charCoords({line: line, ch: 0}, "local");
22 | cm.scrollTo(null, (coords.top + coords.bottom - myHeight) / 2);
23 | }
24 | export default class MarkdownEditor extends React.Component {
25 | constructor(props) {
26 | super(props);
27 | this.editorStore = this.props.context.editorStore;
28 | var editorAction = this.props.context.editorAction;
29 | this.editorStore.on("quote", (quoteText)=> {
30 | setTimeout(()=> {
31 | scrollToBottom(this.editor);
32 | }, 64);
33 | });
34 | this.extraKeys = {
35 | "Cmd-S": ()=> {
36 | var filePath = this.editorStore.getFilePath();
37 | editorAction.saveAsFile(filePath);
38 | return false;
39 | },
40 | "Cmd-N": ()=> {
41 | editorAction.createNewFile();
42 | return false;
43 | },
44 | "Cmd-O": ()=> {
45 | editorAction.openFile();
46 | return false;
47 | },
48 | "Enter": "newlineAndIndentContinueMarkdownList"
49 | };
50 | this.debounceOnChange = this._codeMirrorOnChange.bind(this);
51 | }
52 |
53 | componentDidMount() {
54 | var nodes = React.findDOMNode(this);
55 | this.editor = nodes.querySelector(".CodeMirror").CodeMirror;
56 | }
57 |
58 | shouldComponentUpdate(nextProps, nextState) {
59 | return nextProps.source !== this.editor.value;
60 | }
61 |
62 | _codeMirrorOnChange(result) {
63 | var text = result.target.value;
64 | var action = this.props.context.editorAction;
65 | action.save(text);
66 | }
67 |
68 | render() {
69 | return
70 |
76 |
77 |
78 | }
79 | }
--------------------------------------------------------------------------------
/lib/components/MarkdownToolbar.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var React = require("react");
3 | var path = require("path");
4 | export default class MarkdownToolbar extends React.Component {
5 | onQuote() {
6 | // pdf.js instance
7 | var contentWindow = document.querySelector(".PDFViewer").contentWindow;
8 | var pdfViewerApplication = contentWindow.PDFViewerApplication;
9 | var pdfViewer = pdfViewerApplication.pdfViewer;
10 | var currentPage = pdfViewer.currentPageNumber;
11 | var url = pdfViewerApplication.url;
12 | var urlReg = /(^https?:|^file:)/;
13 | var { context } = this.props;
14 | if (!urlReg.test(url)) {
15 | var markdownFilePath = context.editorStore.getFilePath();
16 | if (markdownFilePath) {
17 | url = path.relative(path.dirname(markdownFilePath), url);
18 | }
19 | }
20 | var href = url + pdfViewer.location.pdfOpenParams;
21 | var selectedText = contentWindow.getSelection();
22 | var text = `## [Page ${currentPage}](${href})
23 | > ${selectedText}
24 |
25 | `;
26 | context.editorAction.quote(text);
27 | }
28 |
29 | onCreateNewFile() {
30 | var { context } = this.props;
31 | context.editorAction.createNewFile();
32 | }
33 |
34 | onOpen() {
35 | var { context } = this.props;
36 | context.editorAction.openFile();
37 | }
38 |
39 | onSave() {
40 | var { editorStore, editorAction } = this.props.context;
41 | var filePath = editorStore.getFilePath();
42 | editorAction.saveAsFile(filePath);
43 | }
44 |
45 | onChangeMode(isReadonly) {
46 | var { editorAction } = this.props.context;
47 | editorAction.changeReadonly(isReadonly);
48 | }
49 |
50 | render() {
51 | var { editorStore } = this.props.context;
52 | if (editorStore.isReadonly()) {
53 | return (
54 |
55 |
57 |
58 | )
59 | } else {
60 | return (
61 |
62 |
63 |
65 |
66 |
67 |
69 |
70 | )
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/lib/stores/EditorStore.js:
--------------------------------------------------------------------------------
1 | // LICENSE : MIT
2 | "use strict";
3 | import { Store } from "material-flux"
4 | import { keys } from "../actions/EditorAction"
5 |
6 |
7 | var fs = require("fs");
8 | function readFile(filePath, callback) {
9 | var urlReg = /(^https?:|^file:)/;
10 | if (urlReg.test(filePath) || typeof fs.readFile === "undefined") {
11 | var req = new XMLHttpRequest();
12 | req.open("GET", filePath, true);
13 | req.onload = function () {
14 | callback(null, req.responseText);
15 | };
16 | req.onerror = function () {
17 | callback(new Error(req.statusText));
18 | };
19 | req.send();
20 | } else {
21 | fs.readFile(filePath, callback);
22 | }
23 | }
24 | export default class EditorStore extends Store {
25 | constructor(context) {
26 | super(context);
27 | this.state = {
28 | filePath: null,
29 | text: "",
30 | quoteText: "",
31 | readonly: false
32 | };
33 | this.register(keys.quote, this.onQuote);
34 | this.register(keys.createNewFile, this.onCreateNewFile);
35 | this.register(keys.save, this.onSave);
36 | this.register(keys.saveAsFile, this.onSaveAsFile);
37 | this.register(keys.openFile, this.onOpenFile);
38 | this.register(keys.readonly, this.onReadonly);
39 |
40 |
41 | // initial load
42 | var filePath = localStorage.getItem("filePath");
43 | this.onOpenFile(filePath);
44 | // auto save per 5s
45 | setInterval(this._onAutoSave.bind(this), 5000);
46 | // save filePath persistent
47 | this.onChange(() => {
48 | if (this.state.filePath) {
49 | localStorage.setItem("filePath", this.state.filePath);
50 | } else {
51 | localStorage.removeItem("filePath");
52 | }
53 | });
54 | }
55 |
56 | _onAutoSave() {
57 | // disable when readonly mode
58 | if (this.state.readonly) {
59 | return;
60 | }
61 | if (this.state.filePath == null || this.state.text.length === 0) {
62 | return;
63 | }
64 | fs.writeFile(this.state.filePath, this.state.text, (error) => {
65 | var appName = require("../../package.json").name;
66 | if (error) {
67 | console.error(error);
68 | new Notification(appName, {
69 | body: `Fail saving ${this.state.filePath}`
70 | });
71 | }
72 | });
73 | }
74 |
75 | getFilePath() {
76 | return this.state.filePath;
77 | }
78 |
79 | getText() {
80 | return this.state.text;
81 | }
82 |
83 | getQuoteText() {
84 | return this.state.quoteText;
85 | }
86 |
87 | isReadonly() {
88 | return this.state.readonly;
89 | }
90 |
91 | onCreateNewFile() {
92 | this.setState({
93 | filePath: null,
94 | text: "",
95 | quoteText: ""
96 | });
97 | }
98 |
99 | onOpenFile(filePath) {
100 | if (filePath == null) {
101 | return;
102 | }
103 | var appName = require("../../package.json").name;
104 | readFile(filePath, (error, data) => {
105 | if (error) {
106 | console.error(error.stack);
107 | new Notification(appName, {
108 | body: `Fail opening ${filePath}`
109 | });
110 | return;
111 | }
112 | this.setState({
113 | text: String(data),
114 | filePath: filePath
115 | });
116 | });
117 | }
118 |
119 | onSaveAsFile(filePath) {
120 | fs.writeFile(filePath, this.state.text, (error) => {
121 | var appName = require("../../package.json").name;
122 | if (error) {
123 | console.error(error);
124 | new Notification(appName, {
125 | body: `Fail saving ${filePath}`
126 | });
127 | return;
128 | }
129 | this.setState({
130 | filePath: filePath
131 | });
132 | });
133 | }
134 |
135 | onSave(text) {
136 | if (text === this.state.text) {
137 | return;
138 | }
139 | this.setState({
140 | text: text
141 | });
142 | }
143 |
144 | onQuote(text) {
145 | if (text === this.state.quoteText) {
146 | return;
147 | }
148 | this.setState({
149 | text: this.state.text + "\n" + text,
150 | quoteText: text
151 | });
152 |
153 | this.emit("quote", text);
154 | }
155 |
156 | onReadonly(isReadonly) {
157 | if (typeof isReadonly === "undefined") {
158 | return;
159 | }
160 | this.setState({
161 | readonly: isReadonly
162 | });
163 | }
164 | }
--------------------------------------------------------------------------------
/css/index.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "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",
4 | "sources": ["index.scss","components/_App.scss","components/_PDFViewer.scss","components/_MarkdownEditor.scss","components/_MarkdownToolbar.scss","components/_MarkdownPreview.scss","layout/_Applayout.scss"],
5 | "names": [],
6 | "file": "index.css"
7 | }
--------------------------------------------------------------------------------
/test/es5.md:
--------------------------------------------------------------------------------
1 | # ECMAScript 5 Specメモ
2 |
3 | ## [Page 15](./Ecma-262_5.1.pdf#page=15)
4 |
5 | > ECMAScript does not use classes such as those in C++, Smalltalk,
6 | > or Java.
7 |
8 | ECMAScriptはクラスではない。ES6でも同様の記述
9 |
10 | ## [Page 15](./Ecma-262_5.1.pdf#page=15)
11 |
12 | > prototype-based inheritance and shared properties.
13 |
14 | 代わりにプロトタイプベースである
15 |
16 | ***
17 |
18 | ## [Page 17](./Ecma-262_5.1.pdf#page=17)
19 |
20 | > 4.3.6 native object object in an ECMAScript implementation whose
21 | > semantics are fully defined by this specification rather than by
22 | > the host environment NOTE Standard native objects are defined in
23 | > this specification. Some native objects are built-in; others may
24 | > be constructed during the course of execution of an ECMAScript
25 | > program. 4.3.7 built-in object object supplied by an ECMAScript
26 | > implementation, independent of the host environment, that is
27 | > present at the start of the execution of an ECMAScript program
28 | > NOTE Standard built-in objects are defined in this specification,
29 | > and an ECMAScript implementation may specify and define others.
30 | > Every built-in object is a native object. A built-in constructor
31 | > is a built-in object that is also a constructor. 4.3.8 host
32 | > object object supplied by the host environment to complete the
33 | > execution environment of ECMAScript NOTE Any object that is not
34 | > native is a host object.
35 |
36 | - ネイティブオブジェクト
37 | - ビルトインオブジェクト
38 | - ホストオブジェクト
39 |
40 | ネイティブはECMAScriptの仕様に書かれてるオブジェクトの事。
41 | ホストオブジェクトはDOM APIとかブラウザが提供してるもの。
42 | ビルトインオブジェクトも一種のネイティブオブジェクトだが、
43 | 実行時に提供される?
44 |
45 | ***
46 |
47 | ## [Page 20](./Ecma-262_5.1.pdf#page=20)
48 | > Productions of the lexical and RegExp grammars are distinguished by having two colons ―::‖ as separating punctuation. The lexical and RegExp grammars share some productions.
49 |
50 | 字句文法と正規表現文法の区切り文字は`::`
51 |
52 |
53 | ## [Page 20](./Ecma-262_5.1.pdf#page=20)
54 | > Productions of the numeric string grammar are distinguished by having three colons ―:::‖ aspunctuation.
55 |
56 | 数値文字列の区切り文字は`:::`
57 |
58 |
59 | ## [Page 20](./Ecma-262_5.1.pdf#page=20)
60 | > It defines a set of productions, starting from the goal symbol Program, that describe how sequences of tokens can form syntactically correct ECMAScript programs.
61 |
62 | 字句文法を繰り返し適応していって、
63 | これが目標記号まで辿りつけない場合がプログラムの構文エラーがある。 = Syntax Errorとなる
64 |
65 | 字句文法を繰り返す => 構文解析を一回 => 構文文法が生成される
66 |
67 | ## [Page 20](./Ecma-262_5.1.pdf#page=20)
68 | > Starting from a sentence consisting of a single distinguished nonterminal, called the goal symbol, a given context-free grammar specifies a language, namely, the (perhaps infinite) set of possible sequences of terminal symbols that can result from repeatedly replacing any nonterminal in the sequence with a right-hand side of a production for which the nonterminal is the left-hand side
69 |
70 | 目標記号 = 非終端記号
71 |
72 | 非終端記号は_斜体_で表現される via P22
73 |
74 |
75 | ## [Page 20](./Ecma-262_5.1.pdf#page=20)
76 | > Productions of the syntactic grammar are distinguished by having just one colon ―:‖ as punctuation.
77 |
78 | 構文文法の区切り文字は`:`
79 |
80 |
81 |
82 | ## [Page 21](./Ecma-262_5.1.pdf#page=21)
83 | > Productions of the JSON lexical grammar are distinguished by having two colons `::` as separating punctuation
84 |
85 | JSONの字句文法の区切り文字は`::`
86 | JSONの構文文法の区切り文字はECMAScriptの構文文法を流用するので`:`となる
87 |
88 | ## [Page 21](./Ecma-262_5.1.pdf#page=21)
89 |
90 | ```
91 | ArgumentList:
92 | AssignmentExpression
93 | ArgumentList , AssignmentExpression
94 | ```
95 |
96 | これはArgumentListが単体のAssignmentExpression **または** ArgumentList , AssignmentExpression となることを表現してる。
97 |
98 | ----
99 |
100 | これを短縮したopt記号を使った
101 |
102 | ```
103 | VariableDeclaration:
104 | Identifier Initialiser(opt)
105 | ```
106 |
107 | というのは以下の短縮形
108 |
109 | ```
110 | VariableDeclaration:
111 | Identifier
112 | Identifier Initialiser
113 | ```
114 |
115 | であるとか。
116 | ## [Page 22](./Ecma-262_5.1.pdf#page=22)
117 | > [lookahead set]
118 |
119 | 
120 |
121 | というのは 先読み setで指定された文字列は、直後の入力トークンでは含まれてないということを示す。
122 |
123 | つまり
124 |
125 | ```
126 | LookaheadExample::
127 | n [ lookahead ∉ {1,3,5,7,9} ] DecimalDigits
128 | ```
129 |
130 | というのは `n{0,2,4,6,8}` という感じになって、nの後に奇数含まない10進数の数字となる。
131 |
132 |
133 |
134 |
135 | ## [Page 24](./Ecma-262_5.1.pdf#page=24)
136 | > 12© Ecma International 2011In order to facilitate their use in multiple parts of this specification,some algorithms, called abstractoperations, are named and written in parameterised functional form so that they may be referenced by name from within other algorithms.
137 |
138 | ECMAScriptでは抽象演算と言われるアルゴリズムが定義されていて、色々なアルゴリズムが互いに参照してる。
139 | ただし、ここで書かれるアルゴリズムより効率的なものはもちろんあり、このアルゴリズムをそのまま使う必要は必ずしもない。
140 | アルゴリズムの再利用をしたいという目的。
141 |
142 |
143 |
144 | ## [Page 24](./Ecma-262_5.1.pdf#page=24)
145 | > such a floating-point number must be finite, and if it is +0or 0then the corresponding mathematical value is simply 0
146 |
147 | ES5では+-0は数学的な値は単に0とする
148 | ES6でも同じ記述。
149 |
150 |
151 |
152 | ## [Page 24](./Ecma-262_5.1.pdf#page=24)
153 | > If an algorithm is defined to ―throw an exception‖, execution of the algorithm is terminated and no result is returned.
154 |
155 | アルゴリズムが例外を投げるとき
156 |
157 | - アルゴリズムは終了
158 | - 結果は返さない
159 | - "if an exception was thrown..." と表現されるところまで飛ぶ
160 | - そこから続ける
161 | - 例外キャッチする処理がアルゴリズムにないならそこで終わり
162 |
163 |
164 |
165 | ## [Page 25](./Ecma-262_5.1.pdf#page=25)
166 | > If an actual source text is encoded in a form other than 16-bit code units it must be processed as if it was first converted to UTF-16
167 |
168 | かならず最初にUTF-16にしてから始める
169 |
170 | ## [Page 25](./Ecma-262_5.1.pdf#page=25)
171 | > Throughout the rest of this document, the phrase ―code unit‖ and the word ―character‖ will be used to refer to a 16-bit unsigned value used to represent a single 16-bit unit of text.
172 |
173 | ES5だとSourceCharacter:: any Unicode code unitだけど
174 | ES6だとSourceCharacter:: any Unicode code pointで、
175 | 10.1.1 Static Semantics: UTF16Encoding ( cp )でcode pointが決めてある。
176 | ## [Page 27](./Ecma-262_5.1.pdf#page=27)
177 | > Line Terminator Characters
178 |
179 | JSONがJSのサブセットじゃなくなってる問題の`\u2028`とかはES5だとどういう関係になってるんだろ?
180 |
181 | ---
182 | ## [Page 28](./Ecma-262_5.1.pdf#page=28)
183 | > Syntax
184 |
185 |
186 | グラマーは[ECMAScript Syntax Grammar 6th Edition / Draft](http://teramako.github.io/ECMAScript/ecma6th_syntax.html "ECMAScript Syntax Grammar 6th Edition / Draft")を使うと移動できるので見やすい
187 |
188 |
189 |
190 |
191 | ## [Page 29](./Ecma-262_5.1.pdf#page=29)
192 | > Unicode escape sequences are also permitted in an IdentifierName, where they contribute a single character to the IdentifierName, as computed by the CV of the UnicodeEscapeSequence(see 7.8.4).
193 |
194 | `\u0061 = 100` は `a= 100` と変換されてから解釈される。
195 | ## [Page 31](./Ecma-262_5.1.pdf#page=31)
196 | > FutureReservedWord
197 |
198 | ES6で代替ここにある将来の予約語は消化されて、ES6だとawait、asyncが代わりある。
199 |
200 |
201 |
202 | ## [Page 31](./Ecma-262_5.1.pdf#page=31)
203 | > DivPunctuator ::one of
204 |
205 | 正規表現と区別するために
206 | `DivPunctuator`というふうに除算演算子は分けてる = 目標記号
207 |
208 |
209 | ## [Page 36](./Ecma-262_5.1.pdf#page=36)
210 | > A regular expression literal is an input element that is converted to a RegExp object (see 15.10) each time the literal is evaluated. Two regular expression literals in a program evaluate to regular expression objects that never compare as ===to each other even if the two literals' contents are identical.
211 |
212 | ES5から`/ /` は常に新しい正規表現オブジェクトを作るようになった。
213 |
214 | [正規表現リテラルのes3からes5の間での変化 - ぶれすとつーる](http://nazomikan.hateblo.jp/entry/2014/03/12/020734 "正規表現リテラルのes3からes5の間での変化 - ぶれすとつーる")
215 |
216 |
217 |
218 |
219 | ## [Page 37](./Ecma-262_5.1.pdf#page=37)
220 | > An implementation may extend the regular expression constructor's grammar,
221 |
222 | 実装は正規表現コンストラクタのグラマーを拡張していいのか。
223 |
224 | ## [Page 42](./Ecma-262_5.1.pdf#page=42)
225 | > This procedurecorresponds exactly to the behaviour of the IEEE 754 ―round to nearest‖ mode
226 |
227 | 基本はIEEE 754互換の丸めモード。
228 |
229 | 1. 0.5未満
230 | - 切り下げ
231 | 2. 0.5より大きい
232 | - 切り上げ
233 | 3. 0.5の時
234 | - 偶数となる方へ丸め込み
235 |
236 |
237 | 0.5が1となるのをボウシするための、再近接偶数丸めモード(RNモード)という方法らしい
238 | ## [Page 42](./Ecma-262_5.1.pdf#page=42)
239 | > An Object is a collection of properties.Each property is either a named data property, a named accessor property, or an internal property
240 |
241 | - 名前付きデータプロパティ
242 | - 名前付きアクセサプロパティ
243 | - 内部プロパティ
244 |
245 | の3つ
246 |
247 | ES6だと
248 |
249 | - データプロパティ
250 | - アクセサプロパティ
251 |
252 | になってる。
253 |
254 | そして、OrdinaryオブジェクトとExoticオブジェクトという概念がでてくる。
255 |
256 | "内部プロパティ"という言い方がES6ではなくなっていて、internal slotsが代わりっぽい。
257 |
258 | ## [Page 44](./Ecma-262_5.1.pdf#page=44)
259 | > its [[Prototype]] depends on the implementation. Every [[Prototype]] chain must have finite length
260 |
261 | prototypeチェーンは有限の長さである。
262 |
263 | ## [Page 44](./Ecma-262_5.1.pdf#page=44)
264 | > This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object‘s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from falseto true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph
265 |
266 |
267 | `[[Extensible]]`をfalseからtrueにする物自体が仕様には存在していない。
268 | これは不変性を保つためである。
269 |
270 | この辺はES6だとSymbolやProxyHandlerなどによって大きく変わってる。
271 | ## [Page 53](./Ecma-262_5.1.pdf#page=53)
272 | > n the following algorithm, the term ―Reject‖ means ―If Throwis true, then throw a TypeErrorexception, otherwise return false‖.The algorithm contains steps that test various fields of the Property Descriptor Descfor specific values.
273 |
274 | "Reject"は例外フラグが立ってるならthrow TypeError、そうじゃないならfalseを返すという意味
275 | ## [Page 54](./Ecma-262_5.1.pdf#page=54)
276 | > Type Conversion and Testing
277 |
278 | JavaScriptの型変換の定義
279 |
280 | ## [Page 59](./Ecma-262_5.1.pdf#page=59)
281 | > The ToInt32 abstract operation is idempotent: if applied to a result that it produced, the second application leaves that value unchanged
282 |
283 | ToUnit16/32には同じ値を二度適応しても、同じになる冪等性がある
284 |
285 | ## [Page 62](./Ecma-262_5.1.pdf#page=62)
286 | > The SameValue Algorithm
287 |
288 | 値が同じかのチェックアルゴリズム
289 |
290 | `SameValue(x, y)`
291 |
292 | x == null なら trueになる
293 |
294 | ## [Page 62](Ecma-262_5.1.pdf#page=62&zoom=auto,-13,439)
295 | > There are three types of ECMAScript executable code:
296 |
297 | ES5だと
298 |
299 | - global
300 | - eval
301 | - Function
302 |
303 | の3つの実行可能なコードがある。
304 |
305 |
306 | ## [Page 63](Ecma-262_5.1.pdf#page=62&zoom=auto,-13,110)
307 | > Strict Mode Code
308 |
309 | strict modeも上の3つがそれぞれ対応がある。
310 |
311 | - global
312 | - eval
313 | - Function
314 |
315 |
316 | ## [Page 63](Ecma-262_5.1.pdf#page=63&zoom=auto,-13,558)
317 | > A Lexical Environment consists of an Environment Record and a possibly null reference to an outerLexical Environment. Usually a Lexical Environment is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a WithStatement, ora Catch clause of a TryStatementand a new Lexical Environment is created each time such code is evaluated.
318 |
319 | レキシカル環境。
320 | ES5だといわゆるFunctionスコープとか、catchで生まれるスコープのこと。
321 |
322 | レキシカル環境は内から外へとつながっていく感じ。
323 | ## [Page 63](Ecma-262_5.1.pdf#page=63&zoom=auto,-13,305)
324 | > 10.2.1 Environment Records
325 |
326 | と
327 |
328 | > 10.2.1.1Declarative Environment Records
329 |
330 | の違いは宣言的なEnvironment Recordsはimmutableなバインディングを提供する点。
331 | ## [Page 65](Ecma-262_5.1.pdf#page=65&zoom=auto,-13,813)
332 | > The behaviour of the concrete specification methods for Declarative Environment Records is defined by the following algorithms.
333 |
334 |
335 | 基本的にバインディングとはそのメソッドが呼び出された箇所のEnvironment Recordsを参照して、そこに対してバインディングを作ったり、消したり、そこから取得したりする操作。
336 |
337 | ## [Page 69](Ecma-262_5.1.pdf#page=69&zoom=auto,-13,454)
338 | > 10.3.1Identifier Resolution
339 |
340 | での識別子の解決がまさにそのLexicalEnviromentを使って、identifierの解決をしている。
341 |
342 | ## [Page 66](Ecma-262_5.1.pdf#page=66&zoom=auto,-13,487)
343 | > 10.2.1.2Object Environment Records
344 |
345 | `with`専用のバインディング環境
346 |
347 | ES6だとこれらに加えて、
348 | "8.1.1.5 Module Environment Records"がる
349 |
350 |
351 | ## [Page 72](Ecma-262_5.1.pdf#page=72&zoom=auto,-13,721)
352 | > Set the [[Class]] internal property of objto "Arguments"
353 |
354 | argumentsは`[[Class]]`の内部プロパティに保存されている。
355 | ## [Page 73](Ecma-262_5.1.pdf#page=72&zoom=auto,-13,82)
356 | > 14.Else, strictis true so
357 |
358 | strict modeではarguments.calleeとかが使えないのは、argument.cllee.callerに対して`thrower`という関数を設定しているため。
359 |
360 |
361 | ## [Page 75](Ecma-262_5.1.pdf#page=75&zoom=auto,-13,832)
362 | > Expressions
363 | > 11.1Primary Expressions
364 |
365 | 基本式!
366 |
367 |
368 | ## [Page 75](Ecma-262_5.1.pdf#page=75&zoom=auto,-13,832)
369 | > 11.1.1The thisKeyword
370 | > The thiskeyword evaluates to the value of the ThisBinding of the current execution context.
371 |
372 | `this`はその実行コンテキストの`ThisBinding`の値を見ている
373 | ## [Page 79](Ecma-262_5.1.pdf#page=79&zoom=auto,-13,399)
374 | > Properties are accessed by name, using either the dot notation:
375 |
376 | dot notationとbracket notationはMDNじゃなくて仕様にも乗ってたのか
377 |
378 | ## [Page 85](Ecma-262_5.1.pdf#page=85&zoom=auto,-13,423)
379 | > The result of a floating-point multiplication is governed by the rules of IEEE 754 binary double-precision arithmetic:
380 |
381 | NaNの場合どうなるかは書く演算子のところに書いてある。
382 |
383 | ## [Page 90](Ecma-262_5.1.pdf#page=90&zoom=auto,-13,372)
384 | > The comparison x< y, where xandyare values, produces true, false, or undefined(which indicates that at least one operand is NaN).
385 |
386 | 比較の結果はtrue, false, undefinedがあるのか
387 |
388 | ## 疑問
389 |
390 | (normal, empty, empty)
391 |
392 | というそれぞれが何なのかってどこに書いていてあるだろ?
393 |
394 | (関数, 戻り値, 関数の引数) みたいな感じだけど
395 |
396 | (type, value, args)
397 |
398 | ## [Page 113](Ecma-262_5.1.pdf#page=113&zoom=auto,-13,375)
399 | > NOTEThe processes for initiating the evaluation of a Programand for dealing with the result of such an evaluation are defined by an ECMAScript implementation and not by this specification
400 |
401 | `Program`の評価過程は実装依存?
402 |
403 | ## [Page 114](Ecma-262_5.1.pdf#page=114&zoom=auto,-13,553)
404 | > 15Standard Built-in ECMAScript Objects
405 |
406 | ECMAScriptオブジェクトについての定義
--------------------------------------------------------------------------------
/css/components/_MarkdownPreview.scss:
--------------------------------------------------------------------------------
1 | .MarkdownPreview {
2 | overflow: scroll;
3 | @font-face {
4 | font-family: octicons-anchor;
5 | src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
6 | }
7 |
8 | .markdown-body {
9 | -ms-text-size-adjust: 100%;
10 | -webkit-text-size-adjust: 100%;
11 | color: #333;
12 | overflow: hidden;
13 | font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
14 | font-size: 16px;
15 | line-height: 1.6;
16 | word-wrap: break-word;
17 | }
18 |
19 | .markdown-body a {
20 | background: transparent;
21 | }
22 |
23 | .markdown-body a:active,
24 | .markdown-body a:hover {
25 | outline: 0;
26 | }
27 |
28 | .markdown-body strong {
29 | font-weight: bold;
30 | }
31 |
32 | .markdown-body h1 {
33 | font-size: 2em;
34 | margin: 0.67em 0;
35 | }
36 |
37 | .markdown-body img {
38 | border: 0;
39 | }
40 |
41 | .markdown-body hr {
42 | box-sizing: content-box;
43 | height: 0;
44 | }
45 |
46 | .markdown-body pre {
47 | overflow: auto;
48 | }
49 |
50 | .markdown-body code,
51 | .markdown-body kbd,
52 | .markdown-body pre {
53 | font-family: monospace, monospace;
54 | font-size: 1em;
55 | }
56 |
57 | .markdown-body input {
58 | color: inherit;
59 | font: inherit;
60 | margin: 0;
61 | }
62 |
63 | .markdown-body html input[disabled] {
64 | cursor: default;
65 | }
66 |
67 | .markdown-body input {
68 | line-height: normal;
69 | }
70 |
71 | .markdown-body input[type="checkbox"] {
72 | box-sizing: border-box;
73 | padding: 0;
74 | }
75 |
76 | .markdown-body table {
77 | border-collapse: collapse;
78 | border-spacing: 0;
79 | }
80 |
81 | .markdown-body td,
82 | .markdown-body th {
83 | padding: 0;
84 | }
85 |
86 | .markdown-body * {
87 | box-sizing: border-box;
88 | }
89 |
90 | .markdown-body input {
91 | font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
92 | }
93 |
94 | .markdown-body a {
95 | color: #4183c4;
96 | text-decoration: none;
97 | }
98 |
99 | .markdown-body a:hover,
100 | .markdown-body a:active {
101 | text-decoration: underline;
102 | }
103 |
104 | .markdown-body hr {
105 | height: 0;
106 | margin: 15px 0;
107 | overflow: hidden;
108 | background: transparent;
109 | border: 0;
110 | border-bottom: 1px solid #ddd;
111 | }
112 |
113 | .markdown-body hr:before {
114 | display: table;
115 | content: "";
116 | }
117 |
118 | .markdown-body hr:after {
119 | display: table;
120 | clear: both;
121 | content: "";
122 | }
123 |
124 | .markdown-body h1,
125 | .markdown-body h2,
126 | .markdown-body h3,
127 | .markdown-body h4,
128 | .markdown-body h5,
129 | .markdown-body h6 {
130 | margin-top: 15px;
131 | margin-bottom: 15px;
132 | line-height: 1.1;
133 | }
134 |
135 | .markdown-body h1 {
136 | font-size: 30px;
137 | }
138 |
139 | .markdown-body h2 {
140 | font-size: 21px;
141 | }
142 |
143 | .markdown-body h3 {
144 | font-size: 16px;
145 | }
146 |
147 | .markdown-body h4 {
148 | font-size: 14px;
149 | }
150 |
151 | .markdown-body h5 {
152 | font-size: 12px;
153 | }
154 |
155 | .markdown-body h6 {
156 | font-size: 11px;
157 | }
158 |
159 | .markdown-body blockquote {
160 | margin: 0;
161 | }
162 |
163 | .markdown-body ul,
164 | .markdown-body ol {
165 | padding: 0;
166 | margin-top: 0;
167 | margin-bottom: 0;
168 | }
169 |
170 | .markdown-body ol ol,
171 | .markdown-body ul ol {
172 | list-style-type: lower-roman;
173 | }
174 |
175 | .markdown-body ul ul ol,
176 | .markdown-body ul ol ol,
177 | .markdown-body ol ul ol,
178 | .markdown-body ol ol ol {
179 | list-style-type: lower-alpha;
180 | }
181 |
182 | .markdown-body dd {
183 | margin-left: 0;
184 | }
185 |
186 | .markdown-body code {
187 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
188 | font-size: 12px;
189 | }
190 |
191 | .markdown-body pre {
192 | margin-top: 0;
193 | margin-bottom: 0;
194 | font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
195 | }
196 |
197 | .markdown-body .octicon {
198 | font: normal normal normal 16px/1 octicons-anchor;
199 | display: inline-block;
200 | text-decoration: none;
201 | text-rendering: auto;
202 | -webkit-font-smoothing: antialiased;
203 | -moz-osx-font-smoothing: grayscale;
204 | -webkit-user-select: none;
205 | -moz-user-select: none;
206 | -ms-user-select: none;
207 | user-select: none;
208 | }
209 |
210 | .markdown-body .octicon-link:before {
211 | content: '\f05c';
212 | }
213 |
214 | .markdown-body > *:first-child {
215 | margin-top: 0 !important;
216 | }
217 |
218 | .markdown-body > *:last-child {
219 | margin-bottom: 0 !important;
220 | }
221 |
222 | .markdown-body a:not([href]) {
223 | color: inherit;
224 | text-decoration: none;
225 | }
226 |
227 | .markdown-body .anchor {
228 | position: absolute;
229 | top: 0;
230 | left: 0;
231 | display: block;
232 | padding-right: 6px;
233 | padding-left: 30px;
234 | margin-left: -30px;
235 | }
236 |
237 | .markdown-body .anchor:focus {
238 | outline: none;
239 | }
240 |
241 | .markdown-body h1,
242 | .markdown-body h2,
243 | .markdown-body h3,
244 | .markdown-body h4,
245 | .markdown-body h5,
246 | .markdown-body h6 {
247 | position: relative;
248 | margin-top: 1em;
249 | margin-bottom: 16px;
250 | font-weight: bold;
251 | line-height: 1.4;
252 | }
253 |
254 | .markdown-body h1 .octicon-link,
255 | .markdown-body h2 .octicon-link,
256 | .markdown-body h3 .octicon-link,
257 | .markdown-body h4 .octicon-link,
258 | .markdown-body h5 .octicon-link,
259 | .markdown-body h6 .octicon-link {
260 | display: none;
261 | color: #000;
262 | vertical-align: middle;
263 | }
264 |
265 | .markdown-body h1:hover .anchor,
266 | .markdown-body h2:hover .anchor,
267 | .markdown-body h3:hover .anchor,
268 | .markdown-body h4:hover .anchor,
269 | .markdown-body h5:hover .anchor,
270 | .markdown-body h6:hover .anchor {
271 | padding-left: 8px;
272 | margin-left: -30px;
273 | text-decoration: none;
274 | }
275 |
276 | .markdown-body h1:hover .anchor .octicon-link,
277 | .markdown-body h2:hover .anchor .octicon-link,
278 | .markdown-body h3:hover .anchor .octicon-link,
279 | .markdown-body h4:hover .anchor .octicon-link,
280 | .markdown-body h5:hover .anchor .octicon-link,
281 | .markdown-body h6:hover .anchor .octicon-link {
282 | display: inline-block;
283 | }
284 |
285 | .markdown-body h1 {
286 | padding-bottom: 0.3em;
287 | font-size: 2.25em;
288 | line-height: 1.2;
289 | border-bottom: 1px solid #eee;
290 | }
291 |
292 | .markdown-body h1 .anchor {
293 | line-height: 1;
294 | }
295 |
296 | .markdown-body h2 {
297 | padding-bottom: 0.3em;
298 | font-size: 1.75em;
299 | line-height: 1.225;
300 | border-bottom: 1px solid #eee;
301 | }
302 |
303 | .markdown-body h2 .anchor {
304 | line-height: 1;
305 | }
306 |
307 | .markdown-body h3 {
308 | font-size: 1.5em;
309 | line-height: 1.43;
310 | }
311 |
312 | .markdown-body h3 .anchor {
313 | line-height: 1.2;
314 | }
315 |
316 | .markdown-body h4 {
317 | font-size: 1.25em;
318 | }
319 |
320 | .markdown-body h4 .anchor {
321 | line-height: 1.2;
322 | }
323 |
324 | .markdown-body h5 {
325 | font-size: 1em;
326 | }
327 |
328 | .markdown-body h5 .anchor {
329 | line-height: 1.1;
330 | }
331 |
332 | .markdown-body h6 {
333 | font-size: 1em;
334 | color: #777;
335 | }
336 |
337 | .markdown-body h6 .anchor {
338 | line-height: 1.1;
339 | }
340 |
341 | .markdown-body p,
342 | .markdown-body blockquote,
343 | .markdown-body ul,
344 | .markdown-body ol,
345 | .markdown-body dl,
346 | .markdown-body table,
347 | .markdown-body pre {
348 | margin-top: 0;
349 | margin-bottom: 16px;
350 | }
351 |
352 | .markdown-body hr {
353 | height: 4px;
354 | padding: 0;
355 | margin: 16px 0;
356 | background-color: #e7e7e7;
357 | border: 0 none;
358 | }
359 |
360 | .markdown-body ul,
361 | .markdown-body ol {
362 | padding-left: 2em;
363 | }
364 |
365 | .markdown-body ul ul,
366 | .markdown-body ul ol,
367 | .markdown-body ol ol,
368 | .markdown-body ol ul {
369 | margin-top: 0;
370 | margin-bottom: 0;
371 | }
372 |
373 | .markdown-body li > p {
374 | margin-top: 16px;
375 | }
376 |
377 | .markdown-body dl {
378 | padding: 0;
379 | }
380 |
381 | .markdown-body dl dt {
382 | padding: 0;
383 | margin-top: 16px;
384 | font-size: 1em;
385 | font-style: italic;
386 | font-weight: bold;
387 | }
388 |
389 | .markdown-body dl dd {
390 | padding: 0 16px;
391 | margin-bottom: 16px;
392 | }
393 |
394 | .markdown-body blockquote {
395 | padding: 0 15px;
396 | color: #777;
397 | border-left: 4px solid #ddd;
398 | }
399 |
400 | .markdown-body blockquote > :first-child {
401 | margin-top: 0;
402 | }
403 |
404 | .markdown-body blockquote > :last-child {
405 | margin-bottom: 0;
406 | }
407 |
408 | .markdown-body table {
409 | display: block;
410 | width: 100%;
411 | overflow: auto;
412 | word-break: normal;
413 | word-break: keep-all;
414 | }
415 |
416 | .markdown-body table th {
417 | font-weight: bold;
418 | }
419 |
420 | .markdown-body table th,
421 | .markdown-body table td {
422 | padding: 6px 13px;
423 | border: 1px solid #ddd;
424 | }
425 |
426 | .markdown-body table tr {
427 | background-color: #fff;
428 | border-top: 1px solid #ccc;
429 | }
430 |
431 | .markdown-body table tr:nth-child(2n) {
432 | background-color: #f8f8f8;
433 | }
434 |
435 | .markdown-body img {
436 | max-width: 100%;
437 | box-sizing: border-box;
438 | }
439 |
440 | .markdown-body code {
441 | padding: 0;
442 | padding-top: 0.2em;
443 | padding-bottom: 0.2em;
444 | margin: 0;
445 | font-size: 85%;
446 | background-color: rgba(0, 0, 0, 0.04);
447 | border-radius: 3px;
448 | }
449 |
450 | .markdown-body code:before,
451 | .markdown-body code:after {
452 | letter-spacing: -0.2em;
453 | content: "\00a0";
454 | }
455 |
456 | .markdown-body pre > code {
457 | padding: 0;
458 | margin: 0;
459 | font-size: 100%;
460 | word-break: normal;
461 | white-space: pre;
462 | background: transparent;
463 | border: 0;
464 | }
465 |
466 | .markdown-body .highlight {
467 | margin-bottom: 16px;
468 | }
469 |
470 | .markdown-body .highlight pre,
471 | .markdown-body pre {
472 | padding: 16px;
473 | overflow: auto;
474 | font-size: 85%;
475 | line-height: 1.45;
476 | background-color: #f7f7f7;
477 | border-radius: 3px;
478 | }
479 |
480 | .markdown-body .highlight pre {
481 | margin-bottom: 0;
482 | word-break: normal;
483 | }
484 |
485 | .markdown-body pre {
486 | word-wrap: normal;
487 | }
488 |
489 | .markdown-body pre code {
490 | display: inline;
491 | max-width: initial;
492 | padding: 0;
493 | margin: 0;
494 | overflow: initial;
495 | line-height: inherit;
496 | word-wrap: normal;
497 | background-color: transparent;
498 | border: 0;
499 | }
500 |
501 | .markdown-body pre code:before,
502 | .markdown-body pre code:after {
503 | content: normal;
504 | }
505 |
506 | .markdown-body kbd {
507 | display: inline-block;
508 | padding: 3px 5px;
509 | font-size: 11px;
510 | line-height: 10px;
511 | color: #555;
512 | vertical-align: middle;
513 | background-color: #fcfcfc;
514 | border: solid 1px #ccc;
515 | border-bottom-color: #bbb;
516 | border-radius: 3px;
517 | box-shadow: inset 0 -1px 0 #bbb;
518 | }
519 |
520 | .markdown-body .pl-c {
521 | color: #969896;
522 | }
523 |
524 | .markdown-body .pl-c1,
525 | .markdown-body .pl-s .pl-v {
526 | color: #0086b3;
527 | }
528 |
529 | .markdown-body .pl-e,
530 | .markdown-body .pl-en {
531 | color: #795da3;
532 | }
533 |
534 | .markdown-body .pl-s .pl-s1,
535 | .markdown-body .pl-smi {
536 | color: #333;
537 | }
538 |
539 | .markdown-body .pl-ent {
540 | color: #63a35c;
541 | }
542 |
543 | .markdown-body .pl-k {
544 | color: #a71d5d;
545 | }
546 |
547 | .markdown-body .pl-pds,
548 | .markdown-body .pl-s,
549 | .markdown-body .pl-s .pl-pse .pl-s1,
550 | .markdown-body .pl-sr,
551 | .markdown-body .pl-sr .pl-cce,
552 | .markdown-body .pl-sr .pl-sra,
553 | .markdown-body .pl-sr .pl-sre {
554 | color: #183691;
555 | }
556 |
557 | .markdown-body .pl-v {
558 | color: #ed6a43;
559 | }
560 |
561 | .markdown-body .pl-id {
562 | color: #b52a1d;
563 | }
564 |
565 | .markdown-body .pl-ii {
566 | background-color: #b52a1d;
567 | color: #f8f8f8;
568 | }
569 |
570 | .markdown-body .pl-sr .pl-cce {
571 | color: #63a35c;
572 | font-weight: bold;
573 | }
574 |
575 | .markdown-body .pl-ml {
576 | color: #693a17;
577 | }
578 |
579 | .markdown-body .pl-mh,
580 | .markdown-body .pl-mh .pl-en,
581 | .markdown-body .pl-ms {
582 | color: #1d3e81;
583 | font-weight: bold;
584 | }
585 |
586 | .markdown-body .pl-mq {
587 | color: #008080;
588 | }
589 |
590 | .markdown-body .pl-mi {
591 | color: #333;
592 | font-style: italic;
593 | }
594 |
595 | .markdown-body .pl-mb {
596 | color: #333;
597 | font-weight: bold;
598 | }
599 |
600 | .markdown-body .pl-md {
601 | background-color: #ffecec;
602 | color: #bd2c00;
603 | }
604 |
605 | .markdown-body .pl-mi1 {
606 | background-color: #eaffea;
607 | color: #55a532;
608 | }
609 |
610 | .markdown-body .pl-mdr {
611 | color: #795da3;
612 | font-weight: bold;
613 | }
614 |
615 | .markdown-body .pl-mo {
616 | color: #1d3e81;
617 | }
618 |
619 | .markdown-body kbd {
620 | display: inline-block;
621 | padding: 3px 5px;
622 | font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
623 | line-height: 10px;
624 | color: #555;
625 | vertical-align: middle;
626 | background-color: #fcfcfc;
627 | border: solid 1px #ccc;
628 | border-bottom-color: #bbb;
629 | border-radius: 3px;
630 | box-shadow: inset 0 -1px 0 #bbb;
631 | }
632 |
633 | .markdown-body .task-list-item {
634 | list-style-type: none;
635 | }
636 |
637 | .markdown-body .task-list-item + .task-list-item {
638 | margin-top: 3px;
639 | }
640 |
641 | .markdown-body .task-list-item input {
642 | margin: 0 0.35em 0.25em -1.6em;
643 | vertical-align: middle;
644 | }
645 |
646 | .markdown-body :checked + .radio-label {
647 | z-index: 1;
648 | position: relative;
649 | border-color: #4183c4;
650 | }
651 |
652 | }
--------------------------------------------------------------------------------
/css/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0; }
6 |
7 | * {
8 | box-sizing: border-box; }
9 |
10 | .App {
11 | width: 100%;
12 | height: 100%;
13 | margin: 0;
14 | padding: 0;
15 | border: none; }
16 |
17 | .PDFViewer {
18 | width: 100%;
19 | height: 100%;
20 | margin: 0;
21 | padding: 0;
22 | border: none; }
23 |
24 | .MarkdownEditor, .MarkdownEditor > div {
25 | width: 100%;
26 | height: 100%;
27 | margin: 0;
28 | padding: 0;
29 | border: none; }
30 |
31 | .MarkdownEditor .CodeMirror {
32 | height: 100%; }
33 |
34 | .MarkdownEditor .CodeMirror, .MarkdownEditor textarea {
35 | font-size: 16px; }
36 |
37 | .MemoToolbar {
38 | height: 1.2rem;
39 | background-color: white; }
40 | .MemoToolbar .fa::before {
41 | margin-right: 0.5em;
42 | margin-left: 0.2em; }
43 |
44 | .MarkdownPreview {
45 | overflow: scroll; }
46 | @font-face {
47 | .MarkdownPreview {
48 | font-family: octicons-anchor;
49 | src: url(data:font/woff;charset=utf-8;base64,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) format("woff"); } }
50 | .MarkdownPreview .markdown-body {
51 | -ms-text-size-adjust: 100%;
52 | -webkit-text-size-adjust: 100%;
53 | color: #333;
54 | overflow: hidden;
55 | font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
56 | font-size: 16px;
57 | line-height: 1.6;
58 | word-wrap: break-word; }
59 | .MarkdownPreview .markdown-body a {
60 | background: transparent; }
61 | .MarkdownPreview .markdown-body a:active,
62 | .MarkdownPreview .markdown-body a:hover {
63 | outline: 0; }
64 | .MarkdownPreview .markdown-body strong {
65 | font-weight: bold; }
66 | .MarkdownPreview .markdown-body h1 {
67 | font-size: 2em;
68 | margin: 0.67em 0; }
69 | .MarkdownPreview .markdown-body img {
70 | border: 0; }
71 | .MarkdownPreview .markdown-body hr {
72 | box-sizing: content-box;
73 | height: 0; }
74 | .MarkdownPreview .markdown-body pre {
75 | overflow: auto; }
76 | .MarkdownPreview .markdown-body code,
77 | .MarkdownPreview .markdown-body kbd,
78 | .MarkdownPreview .markdown-body pre {
79 | font-family: monospace, monospace;
80 | font-size: 1em; }
81 | .MarkdownPreview .markdown-body input {
82 | color: inherit;
83 | font: inherit;
84 | margin: 0; }
85 | .MarkdownPreview .markdown-body html input[disabled] {
86 | cursor: default; }
87 | .MarkdownPreview .markdown-body input {
88 | line-height: normal; }
89 | .MarkdownPreview .markdown-body input[type="checkbox"] {
90 | box-sizing: border-box;
91 | padding: 0; }
92 | .MarkdownPreview .markdown-body table {
93 | border-collapse: collapse;
94 | border-spacing: 0; }
95 | .MarkdownPreview .markdown-body td,
96 | .MarkdownPreview .markdown-body th {
97 | padding: 0; }
98 | .MarkdownPreview .markdown-body * {
99 | box-sizing: border-box; }
100 | .MarkdownPreview .markdown-body input {
101 | font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; }
102 | .MarkdownPreview .markdown-body a {
103 | color: #4183c4;
104 | text-decoration: none; }
105 | .MarkdownPreview .markdown-body a:hover,
106 | .MarkdownPreview .markdown-body a:active {
107 | text-decoration: underline; }
108 | .MarkdownPreview .markdown-body hr {
109 | height: 0;
110 | margin: 15px 0;
111 | overflow: hidden;
112 | background: transparent;
113 | border: 0;
114 | border-bottom: 1px solid #ddd; }
115 | .MarkdownPreview .markdown-body hr:before {
116 | display: table;
117 | content: ""; }
118 | .MarkdownPreview .markdown-body hr:after {
119 | display: table;
120 | clear: both;
121 | content: ""; }
122 | .MarkdownPreview .markdown-body h1,
123 | .MarkdownPreview .markdown-body h2,
124 | .MarkdownPreview .markdown-body h3,
125 | .MarkdownPreview .markdown-body h4,
126 | .MarkdownPreview .markdown-body h5,
127 | .MarkdownPreview .markdown-body h6 {
128 | margin-top: 15px;
129 | margin-bottom: 15px;
130 | line-height: 1.1; }
131 | .MarkdownPreview .markdown-body h1 {
132 | font-size: 30px; }
133 | .MarkdownPreview .markdown-body h2 {
134 | font-size: 21px; }
135 | .MarkdownPreview .markdown-body h3 {
136 | font-size: 16px; }
137 | .MarkdownPreview .markdown-body h4 {
138 | font-size: 14px; }
139 | .MarkdownPreview .markdown-body h5 {
140 | font-size: 12px; }
141 | .MarkdownPreview .markdown-body h6 {
142 | font-size: 11px; }
143 | .MarkdownPreview .markdown-body blockquote {
144 | margin: 0; }
145 | .MarkdownPreview .markdown-body ul,
146 | .MarkdownPreview .markdown-body ol {
147 | padding: 0;
148 | margin-top: 0;
149 | margin-bottom: 0; }
150 | .MarkdownPreview .markdown-body ol ol,
151 | .MarkdownPreview .markdown-body ul ol {
152 | list-style-type: lower-roman; }
153 | .MarkdownPreview .markdown-body ul ul ol,
154 | .MarkdownPreview .markdown-body ul ol ol,
155 | .MarkdownPreview .markdown-body ol ul ol,
156 | .MarkdownPreview .markdown-body ol ol ol {
157 | list-style-type: lower-alpha; }
158 | .MarkdownPreview .markdown-body dd {
159 | margin-left: 0; }
160 | .MarkdownPreview .markdown-body code {
161 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
162 | font-size: 12px; }
163 | .MarkdownPreview .markdown-body pre {
164 | margin-top: 0;
165 | margin-bottom: 0;
166 | font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; }
167 | .MarkdownPreview .markdown-body .octicon {
168 | font: normal normal normal 16px/1 octicons-anchor;
169 | display: inline-block;
170 | text-decoration: none;
171 | text-rendering: auto;
172 | -webkit-font-smoothing: antialiased;
173 | -moz-osx-font-smoothing: grayscale;
174 | -webkit-user-select: none;
175 | -moz-user-select: none;
176 | -ms-user-select: none;
177 | user-select: none; }
178 | .MarkdownPreview .markdown-body .octicon-link:before {
179 | content: '\f05c'; }
180 | .MarkdownPreview .markdown-body > *:first-child {
181 | margin-top: 0 !important; }
182 | .MarkdownPreview .markdown-body > *:last-child {
183 | margin-bottom: 0 !important; }
184 | .MarkdownPreview .markdown-body a:not([href]) {
185 | color: inherit;
186 | text-decoration: none; }
187 | .MarkdownPreview .markdown-body .anchor {
188 | position: absolute;
189 | top: 0;
190 | left: 0;
191 | display: block;
192 | padding-right: 6px;
193 | padding-left: 30px;
194 | margin-left: -30px; }
195 | .MarkdownPreview .markdown-body .anchor:focus {
196 | outline: none; }
197 | .MarkdownPreview .markdown-body h1,
198 | .MarkdownPreview .markdown-body h2,
199 | .MarkdownPreview .markdown-body h3,
200 | .MarkdownPreview .markdown-body h4,
201 | .MarkdownPreview .markdown-body h5,
202 | .MarkdownPreview .markdown-body h6 {
203 | position: relative;
204 | margin-top: 1em;
205 | margin-bottom: 16px;
206 | font-weight: bold;
207 | line-height: 1.4; }
208 | .MarkdownPreview .markdown-body h1 .octicon-link,
209 | .MarkdownPreview .markdown-body h2 .octicon-link,
210 | .MarkdownPreview .markdown-body h3 .octicon-link,
211 | .MarkdownPreview .markdown-body h4 .octicon-link,
212 | .MarkdownPreview .markdown-body h5 .octicon-link,
213 | .MarkdownPreview .markdown-body h6 .octicon-link {
214 | display: none;
215 | color: #000;
216 | vertical-align: middle; }
217 | .MarkdownPreview .markdown-body h1:hover .anchor,
218 | .MarkdownPreview .markdown-body h2:hover .anchor,
219 | .MarkdownPreview .markdown-body h3:hover .anchor,
220 | .MarkdownPreview .markdown-body h4:hover .anchor,
221 | .MarkdownPreview .markdown-body h5:hover .anchor,
222 | .MarkdownPreview .markdown-body h6:hover .anchor {
223 | padding-left: 8px;
224 | margin-left: -30px;
225 | text-decoration: none; }
226 | .MarkdownPreview .markdown-body h1:hover .anchor .octicon-link,
227 | .MarkdownPreview .markdown-body h2:hover .anchor .octicon-link,
228 | .MarkdownPreview .markdown-body h3:hover .anchor .octicon-link,
229 | .MarkdownPreview .markdown-body h4:hover .anchor .octicon-link,
230 | .MarkdownPreview .markdown-body h5:hover .anchor .octicon-link,
231 | .MarkdownPreview .markdown-body h6:hover .anchor .octicon-link {
232 | display: inline-block; }
233 | .MarkdownPreview .markdown-body h1 {
234 | padding-bottom: 0.3em;
235 | font-size: 2.25em;
236 | line-height: 1.2;
237 | border-bottom: 1px solid #eee; }
238 | .MarkdownPreview .markdown-body h1 .anchor {
239 | line-height: 1; }
240 | .MarkdownPreview .markdown-body h2 {
241 | padding-bottom: 0.3em;
242 | font-size: 1.75em;
243 | line-height: 1.225;
244 | border-bottom: 1px solid #eee; }
245 | .MarkdownPreview .markdown-body h2 .anchor {
246 | line-height: 1; }
247 | .MarkdownPreview .markdown-body h3 {
248 | font-size: 1.5em;
249 | line-height: 1.43; }
250 | .MarkdownPreview .markdown-body h3 .anchor {
251 | line-height: 1.2; }
252 | .MarkdownPreview .markdown-body h4 {
253 | font-size: 1.25em; }
254 | .MarkdownPreview .markdown-body h4 .anchor {
255 | line-height: 1.2; }
256 | .MarkdownPreview .markdown-body h5 {
257 | font-size: 1em; }
258 | .MarkdownPreview .markdown-body h5 .anchor {
259 | line-height: 1.1; }
260 | .MarkdownPreview .markdown-body h6 {
261 | font-size: 1em;
262 | color: #777; }
263 | .MarkdownPreview .markdown-body h6 .anchor {
264 | line-height: 1.1; }
265 | .MarkdownPreview .markdown-body p,
266 | .MarkdownPreview .markdown-body blockquote,
267 | .MarkdownPreview .markdown-body ul,
268 | .MarkdownPreview .markdown-body ol,
269 | .MarkdownPreview .markdown-body dl,
270 | .MarkdownPreview .markdown-body table,
271 | .MarkdownPreview .markdown-body pre {
272 | margin-top: 0;
273 | margin-bottom: 16px; }
274 | .MarkdownPreview .markdown-body hr {
275 | height: 4px;
276 | padding: 0;
277 | margin: 16px 0;
278 | background-color: #e7e7e7;
279 | border: 0 none; }
280 | .MarkdownPreview .markdown-body ul,
281 | .MarkdownPreview .markdown-body ol {
282 | padding-left: 2em; }
283 | .MarkdownPreview .markdown-body ul ul,
284 | .MarkdownPreview .markdown-body ul ol,
285 | .MarkdownPreview .markdown-body ol ol,
286 | .MarkdownPreview .markdown-body ol ul {
287 | margin-top: 0;
288 | margin-bottom: 0; }
289 | .MarkdownPreview .markdown-body li > p {
290 | margin-top: 16px; }
291 | .MarkdownPreview .markdown-body dl {
292 | padding: 0; }
293 | .MarkdownPreview .markdown-body dl dt {
294 | padding: 0;
295 | margin-top: 16px;
296 | font-size: 1em;
297 | font-style: italic;
298 | font-weight: bold; }
299 | .MarkdownPreview .markdown-body dl dd {
300 | padding: 0 16px;
301 | margin-bottom: 16px; }
302 | .MarkdownPreview .markdown-body blockquote {
303 | padding: 0 15px;
304 | color: #777;
305 | border-left: 4px solid #ddd; }
306 | .MarkdownPreview .markdown-body blockquote > :first-child {
307 | margin-top: 0; }
308 | .MarkdownPreview .markdown-body blockquote > :last-child {
309 | margin-bottom: 0; }
310 | .MarkdownPreview .markdown-body table {
311 | display: block;
312 | width: 100%;
313 | overflow: auto;
314 | word-break: normal;
315 | word-break: keep-all; }
316 | .MarkdownPreview .markdown-body table th {
317 | font-weight: bold; }
318 | .MarkdownPreview .markdown-body table th,
319 | .MarkdownPreview .markdown-body table td {
320 | padding: 6px 13px;
321 | border: 1px solid #ddd; }
322 | .MarkdownPreview .markdown-body table tr {
323 | background-color: #fff;
324 | border-top: 1px solid #ccc; }
325 | .MarkdownPreview .markdown-body table tr:nth-child(2n) {
326 | background-color: #f8f8f8; }
327 | .MarkdownPreview .markdown-body img {
328 | max-width: 100%;
329 | box-sizing: border-box; }
330 | .MarkdownPreview .markdown-body code {
331 | padding: 0;
332 | padding-top: 0.2em;
333 | padding-bottom: 0.2em;
334 | margin: 0;
335 | font-size: 85%;
336 | background-color: rgba(0, 0, 0, 0.04);
337 | border-radius: 3px; }
338 | .MarkdownPreview .markdown-body code:before,
339 | .MarkdownPreview .markdown-body code:after {
340 | letter-spacing: -0.2em;
341 | content: "\00a0"; }
342 | .MarkdownPreview .markdown-body pre > code {
343 | padding: 0;
344 | margin: 0;
345 | font-size: 100%;
346 | word-break: normal;
347 | white-space: pre;
348 | background: transparent;
349 | border: 0; }
350 | .MarkdownPreview .markdown-body .highlight {
351 | margin-bottom: 16px; }
352 | .MarkdownPreview .markdown-body .highlight pre,
353 | .MarkdownPreview .markdown-body pre {
354 | padding: 16px;
355 | overflow: auto;
356 | font-size: 85%;
357 | line-height: 1.45;
358 | background-color: #f7f7f7;
359 | border-radius: 3px; }
360 | .MarkdownPreview .markdown-body .highlight pre {
361 | margin-bottom: 0;
362 | word-break: normal; }
363 | .MarkdownPreview .markdown-body pre {
364 | word-wrap: normal; }
365 | .MarkdownPreview .markdown-body pre code {
366 | display: inline;
367 | max-width: initial;
368 | padding: 0;
369 | margin: 0;
370 | overflow: initial;
371 | line-height: inherit;
372 | word-wrap: normal;
373 | background-color: transparent;
374 | border: 0; }
375 | .MarkdownPreview .markdown-body pre code:before,
376 | .MarkdownPreview .markdown-body pre code:after {
377 | content: normal; }
378 | .MarkdownPreview .markdown-body kbd {
379 | display: inline-block;
380 | padding: 3px 5px;
381 | font-size: 11px;
382 | line-height: 10px;
383 | color: #555;
384 | vertical-align: middle;
385 | background-color: #fcfcfc;
386 | border: solid 1px #ccc;
387 | border-bottom-color: #bbb;
388 | border-radius: 3px;
389 | box-shadow: inset 0 -1px 0 #bbb; }
390 | .MarkdownPreview .markdown-body .pl-c {
391 | color: #969896; }
392 | .MarkdownPreview .markdown-body .pl-c1,
393 | .MarkdownPreview .markdown-body .pl-s .pl-v {
394 | color: #0086b3; }
395 | .MarkdownPreview .markdown-body .pl-e,
396 | .MarkdownPreview .markdown-body .pl-en {
397 | color: #795da3; }
398 | .MarkdownPreview .markdown-body .pl-s .pl-s1,
399 | .MarkdownPreview .markdown-body .pl-smi {
400 | color: #333; }
401 | .MarkdownPreview .markdown-body .pl-ent {
402 | color: #63a35c; }
403 | .MarkdownPreview .markdown-body .pl-k {
404 | color: #a71d5d; }
405 | .MarkdownPreview .markdown-body .pl-pds,
406 | .MarkdownPreview .markdown-body .pl-s,
407 | .MarkdownPreview .markdown-body .pl-s .pl-pse .pl-s1,
408 | .MarkdownPreview .markdown-body .pl-sr,
409 | .MarkdownPreview .markdown-body .pl-sr .pl-cce,
410 | .MarkdownPreview .markdown-body .pl-sr .pl-sra,
411 | .MarkdownPreview .markdown-body .pl-sr .pl-sre {
412 | color: #183691; }
413 | .MarkdownPreview .markdown-body .pl-v {
414 | color: #ed6a43; }
415 | .MarkdownPreview .markdown-body .pl-id {
416 | color: #b52a1d; }
417 | .MarkdownPreview .markdown-body .pl-ii {
418 | background-color: #b52a1d;
419 | color: #f8f8f8; }
420 | .MarkdownPreview .markdown-body .pl-sr .pl-cce {
421 | color: #63a35c;
422 | font-weight: bold; }
423 | .MarkdownPreview .markdown-body .pl-ml {
424 | color: #693a17; }
425 | .MarkdownPreview .markdown-body .pl-mh,
426 | .MarkdownPreview .markdown-body .pl-mh .pl-en,
427 | .MarkdownPreview .markdown-body .pl-ms {
428 | color: #1d3e81;
429 | font-weight: bold; }
430 | .MarkdownPreview .markdown-body .pl-mq {
431 | color: #008080; }
432 | .MarkdownPreview .markdown-body .pl-mi {
433 | color: #333;
434 | font-style: italic; }
435 | .MarkdownPreview .markdown-body .pl-mb {
436 | color: #333;
437 | font-weight: bold; }
438 | .MarkdownPreview .markdown-body .pl-md {
439 | background-color: #ffecec;
440 | color: #bd2c00; }
441 | .MarkdownPreview .markdown-body .pl-mi1 {
442 | background-color: #eaffea;
443 | color: #55a532; }
444 | .MarkdownPreview .markdown-body .pl-mdr {
445 | color: #795da3;
446 | font-weight: bold; }
447 | .MarkdownPreview .markdown-body .pl-mo {
448 | color: #1d3e81; }
449 | .MarkdownPreview .markdown-body kbd {
450 | display: inline-block;
451 | padding: 3px 5px;
452 | font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
453 | line-height: 10px;
454 | color: #555;
455 | vertical-align: middle;
456 | background-color: #fcfcfc;
457 | border: solid 1px #ccc;
458 | border-bottom-color: #bbb;
459 | border-radius: 3px;
460 | box-shadow: inset 0 -1px 0 #bbb; }
461 | .MarkdownPreview .markdown-body .task-list-item {
462 | list-style-type: none; }
463 | .MarkdownPreview .markdown-body .task-list-item + .task-list-item {
464 | margin-top: 3px; }
465 | .MarkdownPreview .markdown-body .task-list-item input {
466 | margin: 0 0.35em 0.25em -1.6em;
467 | vertical-align: middle; }
468 | .MarkdownPreview .markdown-body :checked + .radio-label {
469 | z-index: 1;
470 | position: relative;
471 | border-color: #4183c4; }
472 |
473 | .App {
474 | display: flex; }
475 |
476 | .PDFViewer-container {
477 | width: 50%;
478 | height: 100%;
479 | margin: 0;
480 | padding: 0;
481 | border: none;
482 | overflow: hidden;
483 | flex: 7; }
484 |
485 | .MarkdownEditor-container {
486 | width: 50%;
487 | height: 100%;
488 | margin: 0;
489 | padding: 0;
490 | border: none;
491 | overflow: hidden;
492 | flex: 3; }
493 |
494 | .MarkdownEditor-container {
495 | display: flex;
496 | flex-flow: column; }
497 | .MarkdownEditor-container .MarkdownEditorToolbar {
498 | height: 1rem; }
499 | .MarkdownEditor-container .MarkdownEditor {
500 | height: calc(100% - 1rem); }
501 | .MarkdownEditor-container .MarkdownPreview {
502 | height: calc(100% - 1rem); }
503 |
504 | /*# sourceMappingURL=index.css.map */
505 |
--------------------------------------------------------------------------------