Skip to content
This repository was archived by the owner on Nov 15, 2019. It is now read-only.

Commit e266f83

Browse files
Added bold/italic/strikethrough support
1 parent dd11151 commit e266f83

File tree

11 files changed

+201
-28
lines changed

11 files changed

+201
-28
lines changed

.todo

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
☐ Make a boilerplate out of this project (+React Router +Redux)
33
☐ Add automatic `Check for Updates...`
44
☐ Add `Print...` support
5-
Mark (Bold, Italic, Strikethrough etc...)
6-
☐ http://codemirror.net/doc/manual.html#markText
7-
☐ https://gist.github.com/tovic/f1f21602e6b682ad78d6140f505e14f3
5+
Font: support for nested styles (_foo *nested* bar_)
6+
☐ Font: toggle should work like Svelto.Editor's implementation
7+
☐ Multi-cursor is broken

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Autosaving sticky note with support for multiple notes, find/replace, programmer
1212
- Supports multiple notes without needing multiple windows
1313
- Auto-saves your notes
1414
- To-Do functionalities built-in
15+
- Links support
16+
- Bold/italic/strikethrough support
1517
- Multiple cursors
1618
- Find and Replace
1719
- Programmers shortcuts
@@ -33,6 +35,9 @@ Autosaving sticky note with support for multiple notes, find/replace, programmer
3335
- <kbd>Cmd+Enter</kbd> - Toggle a todo checkbox
3436
- <kbd>Alt+D</kbd> - Toggle a todo check mark
3537
- <kbd>Alt+C</kbd> - Toggle a todo cancel mark
38+
- <kbd>Cmd+B</kbd> - Toggle bold
39+
- <kbd>Cmd+I</kbd> - Toggle italic
40+
- <kbd>Cmd+S</kbd> - Toggle strikethrough
3641
- <kbd>Cmd+1/9</kbd> - Select the 1st/9th note
3742
- <kbd>Alt+Cmd+Left</kbd> - Select the previous note
3843
- <kbd>Alt+Cmd+Left</kbd> - Select the next note

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "noty",
33
"productName": "Noty",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"description": "Autosaving sticky note with support for multiple notes, find/replace, programmers shortcuts and more.",
66
"main": "dist/main.js",
77
"scripts": {

src/main/utils.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const Utils = {
4343
note: app.getName (),
4444
notes: [{
4545
title: app.getName (),
46-
content: 'Welcome to Noty\n\nSince we are using the FiraCode font you can type many glyphs like: -> ->> => ==> ~> ~~> ~~> |> <| <>\n\nWe support To-Do lists by default:\n ✔ Read the readme\n ☐ Star the repository\n ☐ Share with friends\n\nAnd multiple notes, try clicking the title to switch note.'
46+
content: 'Welcome to Noty\n\nSince we are using the FiraCode font you can type many glyphs like: -> ->> => ==> ~~> <-< <=< |> <| <>\n\nWe support To-Do lists by default:\n ✔ Read the readme\n ☐ Star the repository\n ☐ Share with friends\n\nLinks: www.example.com\n\nFont styles: *Bold*, _Italic_ and ~Strikethrough~\n\nAnd multiple notes, try clicking the title to switch note.'
4747
}, {
4848
title: 'Another note',
4949
content: 'Pretty cool, huh?'
@@ -139,6 +139,26 @@ const Utils = {
139139
}
140140
]
141141
},
142+
{
143+
label: 'Font',
144+
submenu: [
145+
{
146+
label: 'Bold',
147+
accelerator: 'cmd+b',
148+
click: () => win.webContents.send ( 'note-font-bold' )
149+
},
150+
{
151+
label: 'Italic',
152+
accelerator: 'cmd+i',
153+
click: () => win.webContents.send ( 'note-font-italic' )
154+
},
155+
{
156+
label: 'Strikethrough',
157+
accelerator: 'cmd+s',
158+
click: () => win.webContents.send ( 'note-font-strikethrough' )
159+
}
160+
]
161+
},
142162
{
143163
label: 'View',
144164
submenu: [

src/ui/app/index.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as _ from 'lodash';
55
import * as React from 'react';
66
import {remote, ipcRenderer as ipc} from 'electron';
77
import Code from 'ui/code';
8+
import Font from 'ui/code/font';
89
import Titlebar from 'ui/titlebar';
910
import 'ui/template/index.scss';
1011
import './index.html';
@@ -42,6 +43,9 @@ class App extends React.Component<any, any> {
4243
ipc.on ( 'note-select', this.noteSelect.bind ( this ) );
4344
ipc.on ( 'note-select-previous', this.noteSelectPrevious.bind ( this ) );
4445
ipc.on ( 'note-select-right', this.noteSelectNext.bind ( this ) );
46+
ipc.on ( 'note-font-bold', this.noteFontBold.bind ( this ) );
47+
ipc.on ( 'note-font-italic', this.noteFontItalic.bind ( this ) );
48+
ipc.on ( 'note-font-strikethrough', this.noteFontStrikethrough.bind ( this ) );
4549
ipc.on ( 'app-focus', () => this.changeFocused ( true ) );
4650
ipc.on ( 'app-blur', () => this.changeFocused ( false ) );
4751

@@ -55,6 +59,9 @@ class App extends React.Component<any, any> {
5559
ipc.removeAllListeners ( 'note-select' );
5660
ipc.removeAllListeners ( 'note-select-previous' );
5761
ipc.removeAllListeners ( 'note-select-right' );
62+
ipc.removeAllListeners ( 'note-font-bold' );
63+
ipc.removeAllListeners ( 'note-font-italic' );
64+
ipc.removeAllListeners ( 'note-font-strikethrough' );
5865
ipc.removeAllListeners ( 'app-focus' );
5966
ipc.removeAllListeners ( 'app-blur' );
6067

@@ -208,6 +215,24 @@ class App extends React.Component<any, any> {
208215

209216
}
210217

218+
noteFontBold () {
219+
220+
Font.toggleBold ( this.editor );
221+
222+
}
223+
224+
noteFontItalic () {
225+
226+
Font.toggleItalic ( this.editor );
227+
228+
}
229+
230+
noteFontStrikethrough () {
231+
232+
Font.toggleStrikethrough ( this.editor );
233+
234+
}
235+
211236
/* CHANGE */
212237

213238
changeFocused ( focused ) {

src/ui/code/font.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
/* IMPORT */
3+
4+
import * as _ from 'lodash';
5+
6+
/* FONT */
7+
8+
const Font = {
9+
10+
boldRe: /(\*)(.+)(\*)/,
11+
italicRe: /(_)(.+)(_)/,
12+
strikethroughRe: /(~)(.+)(~)/,
13+
boldItalicRe: /(\*_)(.+)(_\*)|(_\*)(.+)(\*_)/,
14+
boldStrikethroughRe: /(\*~)(.+)(~\*)|(~\*)(.+)(\*~)/,
15+
italicStrikethroughRe: /(_~)(.+)(~_)|(~_)(.+)(_~)/,
16+
boldItalicStrikethroughRe: /(\*_~)(.+)(~_\*)|(\*~_)(.+)(_~\*)|(_\*~)(.+)(~\*_)|(_~\*)(.+)(\*~_)|(~_\*)(.+)(\*_~)|(~\*_)(.+)(_\*~)/,
17+
18+
getTokens () {
19+
20+
const repeat = ( arr, times ) => _.concat ( [], ..._.range ( times ).map ( () => _.cloneDeep ( arr ) ) ),
21+
makeTokens = ( classNames, times = 1 ) => {
22+
const tokens = [`${classNames} font-token`, classNames, `${classNames} font-token`];
23+
return repeat ( tokens, times );
24+
};
25+
26+
return {
27+
start: [
28+
{ regex: Font.boldItalicStrikethroughRe, token: makeTokens ( 'bold italic strikethrough', 6 ) },
29+
{ regex: Font.boldItalicRe, token: makeTokens ( 'bold italic', 2 ) },
30+
{ regex: Font.boldStrikethroughRe, token: makeTokens ( 'bold strikethrough', 2 ) },
31+
{ regex: Font.italicStrikethroughRe, token: makeTokens ( 'italic strikethrough', 2 ) },
32+
{ regex: Font.boldRe, token: makeTokens ( 'bold' ) },
33+
{ regex: Font.italicRe, token: makeTokens ( 'italic' ) },
34+
{ regex: Font.strikethroughRe, token: makeTokens ( 'strikethrough' ) }
35+
]
36+
};
37+
38+
},
39+
40+
toggleToken ( cm, prefix, suffix = prefix, content = '' ) {
41+
42+
cm.doc.replaceSelections ( cm.doc.getSelections ().map ( selection => {
43+
44+
const hasToken = selection.slice ( 0, prefix.length ) === prefix && selection.slice ( - suffix.length ) === suffix;
45+
46+
return hasToken ? selection.slice ( prefix.length, - suffix.length ) : `${prefix}${selection || content}${suffix}`;
47+
48+
}), 'around' );
49+
50+
},
51+
52+
toggleBold ( cm ) {
53+
54+
Font.toggleToken ( cm, '*', '*', 'Bold' );
55+
56+
},
57+
58+
toggleItalic ( cm ) {
59+
60+
Font.toggleToken ( cm, '_', '_', 'Italic' );
61+
62+
},
63+
64+
toggleStrikethrough ( cm ) {
65+
66+
Font.toggleToken ( cm, '~', '~', 'Strikethrough' );
67+
68+
}
69+
70+
};
71+
72+
/* EXPORT */
73+
74+
export default Font;

src/ui/code/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import './tokens';
88
import * as React from 'react';
99
import CodeMirror from 'react-codemirror2';
1010
import addSelection from './add_selection';
11+
import Font from './font';
1112
import Todo from './todo';
1213

1314
/* OPTIONS */
@@ -39,6 +40,9 @@ const options = {
3940
'Cmd-Enter': Todo.toggleCheckbox,
4041
'Alt-D': Todo.toggleCheckmark,
4142
'Alt-C': Todo.toggleCancelmark,
43+
'Cmd-B': Font.toggleBold,
44+
'Cmd-I': Font.toggleItalic,
45+
'Cmd-S': Font.toggleStrikethrough,
4246
'F2': false,
4347
'Cmd-M': false,
4448
'Cmd-LeftClick': false

src/ui/code/link.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
/* IMPORT */
3+
4+
import * as $ from 'jquery';
5+
import * as open from 'open';
6+
7+
/* LINK */
8+
9+
const Link = {
10+
11+
re: /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9]\.[^\s]{2,})/,
12+
13+
getTokens () {
14+
15+
return {
16+
start: [
17+
{ regex: Link.re, token: 'link' }
18+
]
19+
};
20+
21+
},
22+
23+
onClick () {
24+
25+
$(document).off ( 'click' );
26+
$(document).on ( 'click', '.cm-link', event => {
27+
if ( !event.metaKey ) return;
28+
let url = $(event.target).text ();
29+
if ( !/^https?:\/\//i.test ( url ) ) {
30+
url = `http://${url}`;
31+
}
32+
open ( url );
33+
});
34+
35+
}
36+
37+
}
38+
39+
/* INIT */
40+
41+
Link.onClick ();
42+
43+
/* EXPORT */
44+
45+
export default Link;

src/ui/code/tokens.ts

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,13 @@
22
/* IMPORT */
33

44
import '../../../node_modules/codemirror/addon/mode/simple.js';
5-
import * as $ from 'jquery';
65
import * as CodeMirror from 'codemirror';
7-
import * as open from 'open';
6+
import merge from 'conf-merge';
7+
import Link from './link';
8+
import Font from './font';
89

910
/* TOKENS */
1011

11-
const linkRe = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9]\.[^\s]{2,})/;
12+
const mode = merge ( {}, Link.getTokens (), Font.getTokens () );
1213

13-
CodeMirror.defineSimpleMode ( 'noty-tokens', {
14-
start: [
15-
{
16-
regex: linkRe,
17-
token: 'link'
18-
}
19-
]
20-
});
21-
22-
/* HANDLERS */
23-
24-
$(document).off ( 'click' );
25-
$(document).on ( 'click', '.cm-link', event => {
26-
if ( !event.metaKey ) return;
27-
let url = $(event.target).text ();
28-
if ( !/^https?:\/\//i.test ( url ) ) {
29-
url = `http://${url}`;
30-
}
31-
open ( url );
32-
});
14+
CodeMirror.defineSimpleMode ( 'custom-mode', mode );

src/ui/template/codemirror.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,22 @@
106106

107107
}
108108

109+
.cm-bold {
110+
font-weight: bold;
111+
}
112+
113+
.cm-italic {
114+
font-style: italic;
115+
}
116+
117+
.cm-strikethrough {
118+
text-decoration: line-through;
119+
}
120+
121+
.cm-font-token {
122+
opacity: $font-token-opacity;
123+
}
124+
109125
}
110126

111127
}

0 commit comments

Comments
 (0)