|
@@ -22,59 +22,42 @@
|
22
|
22
|
|
23
|
23
|
package com.dmdirc.ui.messages;
|
24
|
24
|
|
|
25
|
+import static com.google.common.base.Preconditions.checkArgument;
|
|
26
|
+
|
25
|
27
|
import com.dmdirc.interfaces.Connection;
|
26
|
28
|
import com.dmdirc.interfaces.config.AggregateConfigProvider;
|
27
|
29
|
import com.dmdirc.interfaces.config.ConfigChangeListener;
|
28
|
30
|
import com.dmdirc.util.colours.Colour;
|
29
|
|
-
|
30
|
31
|
import java.util.Locale;
|
31
|
32
|
import java.util.regex.Pattern;
|
32
|
|
-
|
33
|
33
|
import javax.annotation.Nullable;
|
34
|
34
|
|
35
|
|
-import static com.google.common.base.Preconditions.checkArgument;
|
36
|
|
-
|
37
|
35
|
/**
|
38
|
36
|
* The styliser applies IRC styles to text. Styles are indicated by various control codes which are
|
39
|
37
|
* a de-facto IRC standard.
|
40
|
38
|
*/
|
41
|
39
|
public class Styliser implements ConfigChangeListener {
|
42
|
40
|
|
43
|
|
- /** The character used for marking up bold text. */
|
44
|
|
- public static final char CODE_BOLD = 2;
|
45
|
|
- /** The character used for marking up coloured text. */
|
46
|
|
- public static final char CODE_COLOUR = 3;
|
47
|
|
- /** The character used for marking up coloured text (using hex). */
|
48
|
|
- public static final char CODE_HEXCOLOUR = 4;
|
49
|
41
|
/** Character used to indicate hyperlinks. */
|
50
|
42
|
public static final char CODE_HYPERLINK = 5;
|
51
|
43
|
/** Character used to indicate channel links. */
|
52
|
44
|
public static final char CODE_CHANNEL = 6;
|
53
|
45
|
/** Character used to indicate smilies. */
|
54
|
46
|
public static final char CODE_SMILIE = 7;
|
55
|
|
- /** The character used for stopping all formatting. */
|
56
|
|
- public static final char CODE_STOP = 15;
|
57
|
47
|
/** Character used to indicate nickname links. */
|
58
|
48
|
public static final char CODE_NICKNAME = 16;
|
59
|
|
- /** The character used for marking up fixed pitch text. */
|
60
|
|
- public static final char CODE_FIXED = 17;
|
61
|
|
- /** The character used for negating control codes. */
|
62
|
|
- public static final char CODE_NEGATE = 18;
|
63
|
49
|
/** The character used for tooltips. */
|
64
|
50
|
public static final char CODE_TOOLTIP = 19;
|
65
|
|
- /** The character used for marking up italic text. */
|
66
|
|
- public static final char CODE_ITALIC = 29;
|
67
|
|
- /** The character used for marking up underlined text. */
|
68
|
|
- public static final char CODE_UNDERLINE = 31;
|
69
|
51
|
/** Internal chars. */
|
70
|
52
|
private static final String INTERNAL_CHARS = String.valueOf(CODE_HYPERLINK)
|
71
|
53
|
+ CODE_NICKNAME + CODE_CHANNEL + CODE_SMILIE + CODE_TOOLTIP;
|
72
|
54
|
/** Characters used for hyperlinks. */
|
73
|
55
|
private static final String HYPERLINK_CHARS = Character.toString(CODE_HYPERLINK) + CODE_CHANNEL;
|
74
|
56
|
/** Regexp to match characters which shouldn't be used in channel links. */
|
75
|
|
- private static final String RESERVED_CHARS = "[^\\s" + CODE_BOLD + CODE_COLOUR
|
76
|
|
- + CODE_STOP + CODE_HEXCOLOUR + CODE_FIXED + CODE_ITALIC
|
77
|
|
- + CODE_UNDERLINE + CODE_CHANNEL + CODE_NICKNAME + CODE_NEGATE + "\",]";
|
|
57
|
+ private static final String RESERVED_CHARS = "[^\\s" + IRCControlCodes.BOLD + IRCControlCodes.COLOUR
|
|
58
|
+ + IRCControlCodes.STOP + IRCControlCodes.COLOUR_HEX + IRCControlCodes.FIXED + IRCControlCodes.ITALIC
|
|
59
|
+ + IRCControlCodes.UNDERLINE + CODE_CHANNEL + CODE_NICKNAME + IRCControlCodes.NEGATE
|
|
60
|
+ + "\",]";
|
78
|
61
|
/** Defines all characters treated as trailing punctuation that are illegal in URLs. */
|
79
|
62
|
private static final String URL_PUNCT_ILLEGAL = "\"";
|
80
|
63
|
/** Defines all characters treated as trailing punctuation that're legal in URLs. */
|
|
@@ -87,7 +70,7 @@ public class Styliser implements ConfigChangeListener {
|
87
|
70
|
private static final String URL_CHARS = '[' + URL_PUNCT_LEGAL + URL_NOPUNCT
|
88
|
71
|
+ "]*[" + URL_NOPUNCT + "]+[" + URL_PUNCT_LEGAL + URL_NOPUNCT + "]*";
|
89
|
72
|
/** The regular expression to use for marking up URLs. */
|
90
|
|
- private static final String URL_REGEXP = "(?i)((?>(?<!" + CODE_HEXCOLOUR
|
|
73
|
+ private static final String URL_REGEXP = "(?i)((?>(?<!" + IRCControlCodes.COLOUR_HEX
|
91
|
74
|
+ "[a-f0-9]{5})[a-f]|[g-z+])+://" + URL_CHARS
|
92
|
75
|
+ "|(?<![a-z0-9:/])www\\." + URL_CHARS + ')';
|
93
|
76
|
/** Regular expression for intelligent handling of closing brackets. */
|
|
@@ -191,18 +174,6 @@ public class Styliser implements ConfigChangeListener {
|
191
|
174
|
}
|
192
|
175
|
}
|
193
|
176
|
|
194
|
|
- /**
|
195
|
|
- * Stylises the specified string.
|
196
|
|
- *
|
197
|
|
- * @param strings The line to be stylised
|
198
|
|
- *
|
199
|
|
- * @return StyledDocument for the inputted strings
|
200
|
|
- */
|
201
|
|
- public <T> T getStyledString(final String[] strings, final StyledMessageMaker<T> maker) {
|
202
|
|
- addStyledString(maker, strings);
|
203
|
|
- return maker.getStyledMessage();
|
204
|
|
- }
|
205
|
|
-
|
206
|
177
|
/**
|
207
|
178
|
* Retrieves the styled String contained within the unstyled offsets specified. That is, the
|
208
|
179
|
* <code>from</code> and <code>to</code> arguments correspond to indexes in an unstyled version
|
|
@@ -293,7 +264,7 @@ public class Styliser implements ConfigChangeListener {
|
293
|
264
|
*
|
294
|
265
|
* @since 0.6.3m1
|
295
|
266
|
*/
|
296
|
|
- public String doSmilies(final String string) {
|
|
267
|
+ private String doSmilies(final String string) {
|
297
|
268
|
// TODO: Check if they're enabled.
|
298
|
269
|
// TODO: Store the list instead of building it every line
|
299
|
270
|
|
|
@@ -320,11 +291,11 @@ public class Styliser implements ConfigChangeListener {
|
320
|
291
|
* @return a copy of the input with control codes removed
|
321
|
292
|
*/
|
322
|
293
|
public static String stipControlCodes(final String input) {
|
323
|
|
- return input.replaceAll("[" + CODE_BOLD + CODE_CHANNEL + CODE_FIXED
|
324
|
|
- + CODE_HYPERLINK + CODE_ITALIC + CODE_NEGATE + CODE_NICKNAME
|
325
|
|
- + CODE_SMILIE + CODE_STOP + CODE_UNDERLINE + "]|"
|
326
|
|
- + CODE_HEXCOLOUR + "([A-Za-z0-9]{6}(,[A-Za-z0-9]{6})?)?|"
|
327
|
|
- + CODE_COLOUR + "([0-9]{1,2}(,[0-9]{1,2})?)?", "")
|
|
294
|
+ return input.replaceAll("[" + IRCControlCodes.BOLD + CODE_CHANNEL + IRCControlCodes.FIXED
|
|
295
|
+ + CODE_HYPERLINK + IRCControlCodes.ITALIC + IRCControlCodes.NEGATE + CODE_NICKNAME
|
|
296
|
+ + CODE_SMILIE + IRCControlCodes.STOP + IRCControlCodes.UNDERLINE + "]|"
|
|
297
|
+ + IRCControlCodes.COLOUR_HEX + "([A-Za-z0-9]{6}(,[A-Za-z0-9]{6})?)?|"
|
|
298
|
+ + IRCControlCodes.COLOUR + "([0-9]{1,2}(,[0-9]{1,2})?)?", "")
|
328
|
299
|
.replaceAll(CODE_TOOLTIP + ".*?" + CODE_TOOLTIP + "(.*?)" + CODE_TOOLTIP, "$1");
|
329
|
300
|
}
|
330
|
301
|
|
|
@@ -337,9 +308,9 @@ public class Styliser implements ConfigChangeListener {
|
337
|
308
|
*
|
338
|
309
|
* @since 0.6.5
|
339
|
310
|
*/
|
340
|
|
- public static String stipInternalControlCodes(final String input) {
|
|
311
|
+ private static String stipInternalControlCodes(final String input) {
|
341
|
312
|
return input.replaceAll("[" + CODE_CHANNEL + CODE_HYPERLINK + CODE_NICKNAME
|
342
|
|
- + CODE_SMILIE + CODE_STOP + CODE_UNDERLINE + ']', "")
|
|
313
|
+ + CODE_SMILIE + IRCControlCodes.STOP + IRCControlCodes.UNDERLINE + ']', "")
|
343
|
314
|
.replaceAll(CODE_TOOLTIP + ".*?" + CODE_TOOLTIP + "(.*?)"
|
344
|
315
|
+ CODE_TOOLTIP, "$1");
|
345
|
316
|
}
|
|
@@ -356,18 +327,18 @@ public class Styliser implements ConfigChangeListener {
|
356
|
327
|
public static String readUntilControl(final String input) {
|
357
|
328
|
int pos = input.length();
|
358
|
329
|
|
359
|
|
- pos = checkChar(pos, input.indexOf(CODE_BOLD));
|
360
|
|
- pos = checkChar(pos, input.indexOf(CODE_UNDERLINE));
|
361
|
|
- pos = checkChar(pos, input.indexOf(CODE_STOP));
|
362
|
|
- pos = checkChar(pos, input.indexOf(CODE_COLOUR));
|
363
|
|
- pos = checkChar(pos, input.indexOf(CODE_HEXCOLOUR));
|
364
|
|
- pos = checkChar(pos, input.indexOf(CODE_ITALIC));
|
365
|
|
- pos = checkChar(pos, input.indexOf(CODE_FIXED));
|
|
330
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.BOLD));
|
|
331
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.UNDERLINE));
|
|
332
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.STOP));
|
|
333
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.COLOUR));
|
|
334
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.COLOUR_HEX));
|
|
335
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.ITALIC));
|
|
336
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.FIXED));
|
366
|
337
|
pos = checkChar(pos, input.indexOf(CODE_HYPERLINK));
|
367
|
338
|
pos = checkChar(pos, input.indexOf(CODE_NICKNAME));
|
368
|
339
|
pos = checkChar(pos, input.indexOf(CODE_CHANNEL));
|
369
|
340
|
pos = checkChar(pos, input.indexOf(CODE_SMILIE));
|
370
|
|
- pos = checkChar(pos, input.indexOf(CODE_NEGATE));
|
|
341
|
+ pos = checkChar(pos, input.indexOf(IRCControlCodes.NEGATE));
|
371
|
342
|
pos = checkChar(pos, input.indexOf(CODE_TOOLTIP));
|
372
|
343
|
|
373
|
344
|
return input.substring(0, pos);
|
|
@@ -404,7 +375,7 @@ public class Styliser implements ConfigChangeListener {
|
404
|
375
|
final boolean isNegated = state.isNegated;
|
405
|
376
|
|
406
|
377
|
// Bold
|
407
|
|
- if (string.charAt(0) == CODE_BOLD) {
|
|
378
|
+ if (string.charAt(0) == IRCControlCodes.BOLD) {
|
408
|
379
|
if (!isNegated) {
|
409
|
380
|
maker.toggleBold();
|
410
|
381
|
}
|
|
@@ -413,7 +384,7 @@ public class Styliser implements ConfigChangeListener {
|
413
|
384
|
}
|
414
|
385
|
|
415
|
386
|
// Underline
|
416
|
|
- if (string.charAt(0) == CODE_UNDERLINE) {
|
|
387
|
+ if (string.charAt(0) == IRCControlCodes.UNDERLINE) {
|
417
|
388
|
if (!isNegated) {
|
418
|
389
|
maker.toggleUnderline();
|
419
|
390
|
}
|
|
@@ -422,7 +393,7 @@ public class Styliser implements ConfigChangeListener {
|
422
|
393
|
}
|
423
|
394
|
|
424
|
395
|
// Italic
|
425
|
|
- if (string.charAt(0) == CODE_ITALIC) {
|
|
396
|
+ if (string.charAt(0) == IRCControlCodes.ITALIC) {
|
426
|
397
|
if (!isNegated) {
|
427
|
398
|
maker.toggleItalic();
|
428
|
399
|
}
|
|
@@ -475,7 +446,7 @@ public class Styliser implements ConfigChangeListener {
|
475
|
446
|
}
|
476
|
447
|
|
477
|
448
|
// Fixed pitch
|
478
|
|
- if (string.charAt(0) == CODE_FIXED) {
|
|
449
|
+ if (string.charAt(0) == IRCControlCodes.FIXED) {
|
479
|
450
|
if (!isNegated) {
|
480
|
451
|
maker.toggleFixedWidth();
|
481
|
452
|
}
|
|
@@ -484,7 +455,7 @@ public class Styliser implements ConfigChangeListener {
|
484
|
455
|
}
|
485
|
456
|
|
486
|
457
|
// Stop formatting
|
487
|
|
- if (string.charAt(0) == CODE_STOP) {
|
|
458
|
+ if (string.charAt(0) == IRCControlCodes.STOP) {
|
488
|
459
|
if (!isNegated) {
|
489
|
460
|
maker.resetAllStyles();
|
490
|
461
|
}
|
|
@@ -493,7 +464,7 @@ public class Styliser implements ConfigChangeListener {
|
493
|
464
|
}
|
494
|
465
|
|
495
|
466
|
// Colours
|
496
|
|
- if (string.charAt(0) == CODE_COLOUR) {
|
|
467
|
+ if (string.charAt(0) == IRCControlCodes.COLOUR) {
|
497
|
468
|
int count = 1;
|
498
|
469
|
// This isn't too nice!
|
499
|
470
|
if (string.length() > count && isInt(string.charAt(count))) {
|
|
@@ -542,7 +513,7 @@ public class Styliser implements ConfigChangeListener {
|
542
|
513
|
}
|
543
|
514
|
|
544
|
515
|
// Hex colours
|
545
|
|
- if (string.charAt(0) == CODE_HEXCOLOUR) {
|
|
516
|
+ if (string.charAt(0) == IRCControlCodes.COLOUR_HEX) {
|
546
|
517
|
int count = 1;
|
547
|
518
|
if (hasHexString(string, 1)) {
|
548
|
519
|
if (!isNegated) {
|
|
@@ -583,7 +554,7 @@ public class Styliser implements ConfigChangeListener {
|
583
|
554
|
}
|
584
|
555
|
|
585
|
556
|
// Control code negation
|
586
|
|
- if (string.charAt(0) == CODE_NEGATE) {
|
|
557
|
+ if (string.charAt(0) == IRCControlCodes.NEGATE) {
|
587
|
558
|
state.isNegated = !state.isNegated;
|
588
|
559
|
return 1;
|
589
|
560
|
}
|
|
@@ -692,10 +663,10 @@ public class Styliser implements ConfigChangeListener {
|
692
|
663
|
|
693
|
664
|
private static class StyliserState {
|
694
|
665
|
|
695
|
|
- public boolean isNegated;
|
696
|
|
- public boolean isInLink;
|
697
|
|
- public boolean isInSmilie;
|
698
|
|
- public boolean isInToolTip;
|
|
666
|
+ boolean isNegated;
|
|
667
|
+ boolean isInLink;
|
|
668
|
+ boolean isInSmilie;
|
|
669
|
+ boolean isInToolTip;
|
699
|
670
|
|
700
|
671
|
}
|
701
|
672
|
|