Skip to content

Commit 40e92b1

Browse files
committed
Add logic for parsing unity rich text to output styled console messages to release template
Code basis comes from develop template, but here only styling for the console is done
1 parent dbb0bba commit 40e92b1

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

Assets/WebGLTemplates/Release/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
</head>
5858

5959
<body>
60+
<script src="./pretty-console.js"></script>
6061
<canvas id="unity-canvas"></canvas>
6162
<div id="unity-loading-bar">
6263
<div id="unity-progress-bar">
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/// Processes all unity log messages and converts unity rich text to css styled console messages
2+
/// from https://github.com/JohannesDeml/UnityWebGL-LoadingTest
3+
4+
function setupConsoleLogPipe() {
5+
// Store actual console log functions
6+
let defaultConsoleLog = console.log;
7+
let defaultConsoleInfo = console.info;
8+
let defaultConsoleDebug = console.debug;
9+
let defaultConsoleWarn = console.warn;
10+
let defaultConsoleError = console.error;
11+
12+
// Overwrite log functions to parse and pipe to debug html console
13+
console.log = (message) => { parseMessageAndLog(message, defaultConsoleLog); };
14+
console.info = (message) => { parseMessageAndLog(message, defaultConsoleInfo); };
15+
console.debug = (message) => { parseMessageAndLog(message, defaultConsoleDebug); };
16+
console.warn = (message) => { parseMessageAndLog(message, defaultConsoleWarn); };
17+
console.error = (message) => { parseMessageAndLog(message, defaultConsoleError); };
18+
19+
20+
parseMessageAndLog = (message, consoleLogFunction) => {
21+
let styledTextParts = parseUnityRichText(message);
22+
let consoleText = '';
23+
let consoleStyle = [];
24+
styledTextParts.forEach(textPart => {
25+
consoleText += textPart.toConsoleTextString();
26+
consoleStyle.push(textPart.toConsoleStyleString());
27+
});
28+
consoleLogFunction(consoleText, ...consoleStyle);
29+
};
30+
}
31+
32+
class StyledTextPart {
33+
constructor(text, styles) {
34+
this.text = text;
35+
this.styles = styles;
36+
}
37+
38+
toHTML() {
39+
if(this.styles.length > 0) {
40+
return `<span style="${this.styles.join(';')}">${this.text}</span>`;
41+
}
42+
return this.text;
43+
}
44+
45+
toConsoleStyleString() {
46+
if(this.styles.length > 0) {
47+
return this.styles.join(';');
48+
}
49+
return 'color:inherit';
50+
}
51+
52+
toConsoleTextString() {
53+
return `%c${this.text}`;
54+
}
55+
}
56+
57+
function parseUnityRichText(message) {
58+
// Mapping for unity tags to css style tags
59+
const tagMap = {
60+
'color': {startTag: '<color=', closeTag: '</color>', styleTag: 'color:', postfix: '', hasParameter: true},
61+
'size': {startTag: '<size=', closeTag: '</size>', styleTag: 'font-size:', postfix: 'px', hasParameter: true},
62+
'bold': {startTag: '<b', closeTag: '</b>', styleTag: 'font-weight:', styleValue: 'bold', hasParameter: false},
63+
'italic': {startTag: '<i', closeTag: '</i>', styleTag: 'font-style:', styleValue: 'italic', hasParameter: false}
64+
};
65+
66+
let index = 0;
67+
const styledTextParts = [];
68+
69+
// Stack of applied styles, so we can also nest styling
70+
let styleStack = [];
71+
// next start index for each tag
72+
let nextStartIndex = [];
73+
// next end index for each tag
74+
let nextEndIndex = [];
75+
Object.keys(tagMap).forEach(key => {
76+
nextStartIndex[key] = message.indexOf(tagMap[key].startTag, index);
77+
nextEndIndex[key] = message.indexOf(tagMap[key].closeTag, index);
78+
});
79+
80+
while (index < message.length) {
81+
let nextTagFound = false;
82+
let nextKey;
83+
let fromArray = [];
84+
let nextIndex = message.length;
85+
86+
// find the next tag start or end
87+
Object.keys(tagMap).forEach(key => {
88+
if(nextStartIndex[key] >= 0 && nextStartIndex[key] < nextIndex) {
89+
nextIndex = nextStartIndex[key];
90+
nextKey = key;
91+
fromArray = nextStartIndex;
92+
nextTagFound = true;
93+
}
94+
95+
if(nextEndIndex[key] >= 0 && nextEndIndex[key] < nextIndex) {
96+
nextIndex = nextEndIndex[key];
97+
nextKey = key;
98+
fromArray = nextEndIndex;
99+
nextTagFound = true;
100+
}
101+
});
102+
103+
// write the text in before the next tag to our style text part array
104+
if(nextIndex > index) {
105+
let messageToNextTag = message.substring(index, nextIndex);
106+
let styles = [...styleStack];
107+
styledTextParts.push(new StyledTextPart(messageToNextTag, styles));
108+
}
109+
110+
// end if no more tags exist
111+
if(nextTagFound === false) {
112+
index = message.length;
113+
break;
114+
}
115+
116+
// Process start tag
117+
if(fromArray === nextStartIndex) {
118+
nextStartIndex[nextKey] = message.indexOf(tagMap[nextKey].startTag, nextIndex+1);
119+
let closeTagIndex = message.indexOf('>', nextIndex+1);
120+
let styleValue;
121+
if(tagMap[nextKey].hasParameter) {
122+
styleValue = message.substring(nextIndex + tagMap[nextKey].startTag.length, closeTagIndex);
123+
styleValue+=tagMap[nextKey].postfix;
124+
} else {
125+
styleValue = tagMap[nextKey].styleValue;
126+
}
127+
styleStack.push(`${tagMap[nextKey].styleTag}${styleValue}`);
128+
index = closeTagIndex+1;
129+
}
130+
// process end tag
131+
else if(fromArray === nextEndIndex) {
132+
nextEndIndex[nextKey] = message.indexOf(tagMap[nextKey].closeTag, nextIndex+1);
133+
let closeTagIndex = message.indexOf('>', nextIndex+1);
134+
styleStack.pop();
135+
index = closeTagIndex+1;
136+
}
137+
}
138+
return styledTextParts;
139+
}
140+
141+
setupConsoleLogPipe();

0 commit comments

Comments
 (0)