1 | // *****************************************************************************
|
2 | // Copyright (C) 2017 TypeFox and others.
|
3 | //
|
4 | // This program and the accompanying materials are made available under the
|
5 | // terms of the Eclipse Public License v. 2.0 which is available at
|
6 | // http://www.eclipse.org/legal/epl-2.0.
|
7 | //
|
8 | // This Source Code may also be made available under the following Secondary
|
9 | // Licenses when the conditions for such availability set forth in the Eclipse
|
10 | // Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
11 | // with the GNU Classpath Exception which is available at
|
12 | // https://www.gnu.org/software/classpath/license.html.
|
13 | //
|
14 | // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
15 | // *****************************************************************************
|
16 | import { injectable } from 'inversify';
|
17 | import { isObject, isString } from '../common';
|
18 |
|
19 | export interface LabelIcon {
|
20 | name: string;
|
21 | animation?: string;
|
22 | }
|
23 |
|
24 | export namespace LabelIcon {
|
25 | export function is(val: unknown): val is LabelIcon {
|
26 | return isObject<LabelIcon>(val) && isString(val.name);
|
27 | }
|
28 | }
|
29 |
|
30 | export type LabelPart = string | LabelIcon;
|
31 |
|
32 | ()
|
33 | export class LabelParser {
|
34 |
|
35 | /**
|
36 | * Returns an array with parts of the given text.
|
37 | * These parts are of type LabelPart which can be either a string or a LabelIcon.
|
38 | * For splitting up the giving text the parser follows this rule:
|
39 | * The text gets parsed for the following pattern: $(iconName~iconAnimation).
|
40 | * If the parser finds such pattern a new LabelIcon object
|
41 | * { name: 'iconName', animation: 'iconAnimation'} is added to the returned array.
|
42 | * iconName can be for instance the name of an icon of e.g. FontAwesome and the (optional) iconAnimation
|
43 | * the name of an animation class which must be supported by the particular icon toolkit.
|
44 | *
|
45 | * Every string before, between or after such icon patterns gets also added to the array
|
46 | * before, between or after the related LabelIcon.
|
47 | *
|
48 | * @param text - the label text to parse
|
49 | */
|
50 | parse(text: string): LabelPart[] {
|
51 | const parserArray: LabelPart[] = [];
|
52 | let arrPointer = 0;
|
53 | let potentialIcon = '';
|
54 |
|
55 | for (let idx = 0; idx < text.length; idx++) {
|
56 | const char = text.charAt(idx);
|
57 | parserArray[arrPointer] = parserArray[arrPointer] || '';
|
58 | if (potentialIcon === '') {
|
59 | if (char === '$') {
|
60 | potentialIcon += char;
|
61 | } else {
|
62 | parserArray[arrPointer] += char;
|
63 | }
|
64 | } else if (potentialIcon === '$') {
|
65 | if (char === '(') {
|
66 | potentialIcon += char;
|
67 | } else {
|
68 | parserArray[arrPointer] += potentialIcon + char;
|
69 | potentialIcon = '';
|
70 | }
|
71 | } else {
|
72 | if (char === ')') {
|
73 | const iconClassArr = potentialIcon.substring(2, potentialIcon.length).split('~');
|
74 | if (parserArray[arrPointer] !== '') {
|
75 | arrPointer++;
|
76 | }
|
77 | parserArray[arrPointer] = { name: iconClassArr[0], animation: iconClassArr[1] };
|
78 | arrPointer++;
|
79 | potentialIcon = '';
|
80 | } else {
|
81 | potentialIcon += char;
|
82 | }
|
83 | }
|
84 | }
|
85 |
|
86 | if (potentialIcon !== '') {
|
87 | parserArray[arrPointer] += potentialIcon;
|
88 | }
|
89 |
|
90 | return parserArray;
|
91 | }
|
92 |
|
93 | }
|