-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathskype-copy-paste-formatter.js
203 lines (169 loc) · 6.23 KB
/
skype-copy-paste-formatter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// Copyright https://www.RedDragonWebDesign.com/
// Permission required to use or copy code. All rights reserved.
"use strict";
class SkypeCopyPasteFormatter {
unformattedText = "";
formattedText = "";
username1 = ""; // name from "Your Username" text box
username2 = ""; // name extracted from log, interlocutor username
line1Username = ""; // named determined by Line 1 Username radio button choice
lines = {};
linesWithKnownUsernameCount = 0;
getFormattedText(unformattedText, username1, line1Username) {
this.unformattedText = unformattedText;
let alreadyFormatted = this.unformattedText.trim().startsWith('[[');
if ( alreadyFormatted ) {
return this.unformattedText;
}
this._removeFancyPunctuation();
this.username1 = username1 ? username1 : '???';
this.currentUsername = "";
this._makeLinesObject();
this.line1Username = (line1Username == 'you') ? this.username1 : this.username2;
this._fixUsernameOnFirstLines();
this.formattedText = this._convertLinesObjectToString();
return this.formattedText;
}
_removeFancyPunctuation() {
// I spotted some fancy quotes in a Skype message. I was unable to duplicate, but let's replace some common MS Office fancy characters just in case.
let fancyPunctuation = {
'“': '"',
'”': '"',
'‘': '\'',
'’': '\'',
'¼': '1/4',
'½': '1/2',
'¾': '3/4',
'–': '-',
'—': '--',
'…': '...',
};
for ( let rule in fancyPunctuation ) {
this.unformattedText = this._globalReplace(this.unformattedText, rule, fancyPunctuation[rule]);
}
}
// https://stackoverflow.com/a/542260/3480193
_globalReplace(original, searchTxt, replaceTxt) {
const regex = new RegExp(searchTxt, 'g');
return original.replace(regex, replaceTxt) ;
}
/** The first couple of lines don't have a username yet. Replace it with this.line1Username */
_fixUsernameOnFirstLines() {
for ( let key in this.lines ) {
let username = this.lines[key]['username'];
if ( ! username ) {
this.lines[key]['username'] = this.line1Username;
} else {
break;
}
}
}
/** Makes this.lines. Also deletes blank lines, and marks lines that are times/usernames. */
_makeLinesObject() {
let lines = this.unformattedText;
this.lines = {};
let currentUsername = "";
// Split in a couple different spots:
// - newline character
// - the pattern Text text text.Text text text. (split at the period)
// - the pattern Text text text?Text text text. (split at the question mark)
// - the pattern Text text text!Text text text. (split at the exclamation mark)
lines = lines.split(/(?<=(?:\.|\?|!))(?=[A-Z])/).join("\n").split("\n");
// Split this pattern into 3 lines: Word word word.Username, 5:52AMWord word word.
// Using [A-Za-z ]+ as the RegEx for now, although usernames can contain more characters than this, and the user can nickname a person whatever they want, so there may be some edge cases.
// https://www.google.com/search?q=skype+username+characters
lines = lines.join("\n").replace(/(?<=\n[A-Za-z ]+, \d{1,2}:\d{2} (A|P)M)(?=[A-Z])/g, "\n").split("\n");
this._findOtherUsername(lines);
for ( let key in lines ) {
let value = lines[key];
let isTime = false;
// if line contains a time (which is how we know username is changing)
if ( value.search(/^((.*), )?\d{1,2}:\d{2} (AM|PM)$/m) !== -1 ) {
isTime = true;
this.linesWithKnownUsernameCount++;
if ( value.search(/^(.*), \d{1,2}:\d{2} (AM|PM)$/m) !== -1 ) {
currentUsername = this.username2;
} else {
currentUsername = this.username1;
}
}
// delete blank lines & delete times
if ( value && ! isTime ) {
this.lines[key] = {
"username": currentUsername,
"text": value,
};
}
}
}
_findOtherUsername(lines) {
for ( let key in lines ) {
let value = lines[key];
var myRegexp = /^(.*), \d{1,2}:\d{2} (AM|PM)$/m;
var match = myRegexp.exec(value);
if ( match ) {
this.username2 = match[1];
}
}
}
_convertLinesObjectToString() {
let s = "";
for ( let key in this.lines ) {
s += '[[' + this.lines[key]['username'] + "]] " + this.lines[key]['text'].trim() + "\n";
}
return s.trim();
// for debugging:
// return JSON.stringify(this.lines).replace(/\},"/g, "\"\n\"");
}
}
// Uncomment the below line before running tests.
// Comment it when done, to prevent errors in browser.
// module.exports = SkypeCopyPasteFormatter;
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
function setValueAndUpdateUndoStack(textarea, text) {
// Must select all, so that the old text is deleted.
textarea.focus();
textarea.select();
// https://stackoverflow.com/a/55174561/3480193
if ( ! document.execCommand('insertText', false, text) ) {
textarea.setRangeText(text);
}
// TODO: unselect all
// I tried a bunch of code. Couldn't get it to work.
}
window.addEventListener('DOMContentLoaded', (e) => {
let username = document.getElementById('username');
let line1UsernameYou = document.querySelector('[name="line-1-username"][value="you"]');
let line1UsernameOtherPerson = document.querySelector('[name="line-1-username"][value="other-person"]');
let log = document.getElementById('log');
let format = document.getElementById('format');
let cookieUsername = getCookie('username');
if ( cookieUsername ) {
username.value = cookieUsername;
}
let cookieLine1Username = getCookie('line1Username');
if ( cookieLine1Username == 'you' ) {
line1UsernameYou.checked = true;
line1UsernameOtherPerson.checked = false;
} else if ( cookieLine1Username == 'other-person' ) {
line1UsernameYou.checked = false;
line1UsernameOtherPerson.checked = true;
}
format.addEventListener('click', function(e) {
// This needs to be refreshed every time, because the checked element may change.
let line1Username = document.querySelector('[name="line-1-username"]:checked');
let formatter = new SkypeCopyPasteFormatter();
let newText = formatter.getFormattedText(
log.value,
username.value,
line1Username.value
);
setValueAndUpdateUndoStack(log, newText);
document.cookie = 'username=' + username.value;
document.cookie = 'line1Username=' + line1Username.value;
});
});