admin管理员组文章数量:1302273
Recently, I was trying to convert Minecraft MOTD into Plain HTML. A Minecraft MOTD is basic text, with Minecraft Color Codes to represent color changes.
Example: "§d§lThe Nexus§8: §6§oO_O §a§l[MUTATION MONDAY]"
Translated: <span style='color:pink'><b>The Nexus</b></span><span style='color:gray'>:</span>...
So on... So basically, there are color codes, which change the color of the text onwards, and formatting codes, which change the formatting of the text onwards.
Now, because the Minecraft Color Codes do not state where the color codes end, I don't know exactly how I could translate this into HTML.
I did manage halfway, by replacing all color codes with </span><span style='color:newcolor'>
and replacing all formatting codes with </var><var style='text-decoration:blah'>
This did not work however, because when you have a color code straight before a formatting code, it bees <span></var><var></span>
.
So the question is, how would I do this? Finding where the color codes end and so on.
Color Codes for Minecraft is available here: /
Since my code is too big, I have it posted on JSFiddle.
My code so far: / (First one's fine, second one's messed up..)
Recently, I was trying to convert Minecraft MOTD into Plain HTML. A Minecraft MOTD is basic text, with Minecraft Color Codes to represent color changes.
Example: "§d§lThe Nexus§8: §6§oO_O §a§l[MUTATION MONDAY]"
Translated: <span style='color:pink'><b>The Nexus</b></span><span style='color:gray'>:</span>...
So on... So basically, there are color codes, which change the color of the text onwards, and formatting codes, which change the formatting of the text onwards.
Now, because the Minecraft Color Codes do not state where the color codes end, I don't know exactly how I could translate this into HTML.
I did manage halfway, by replacing all color codes with </span><span style='color:newcolor'>
and replacing all formatting codes with </var><var style='text-decoration:blah'>
This did not work however, because when you have a color code straight before a formatting code, it bees <span></var><var></span>
.
So the question is, how would I do this? Finding where the color codes end and so on.
Color Codes for Minecraft is available here: http://ess.khhq/mc/
Since my code is too big, I have it posted on JSFiddle.
My code so far: https://jsfiddle/thwe0yek/1/ (First one's fine, second one's messed up..)
Share edited May 18, 2015 at 21:04 FoxInFlame asked May 18, 2015 at 20:51 FoxInFlameFoxInFlame 99012 silver badges21 bronze badges 4- Isn't this a question for CodeGolf? – Dinei Commented May 18, 2015 at 20:59
- I didn't think so. But maybe... – FoxInFlame Commented May 18, 2015 at 21:03
- show us the rest of the "translated" markup for the example coded text. also, you can just use tag opens, you don't need to close the tag to get it to show up: the browser will make sense of what you meant and it should actually look ok with just openeings, as the colors will over-rule previous ones and they will all end at once. ugly over-nested markup, but it should look ok on the screen. – dandavis Commented May 18, 2015 at 21:07
- @dandavis Your method works, but I really want a clear mark-up, and I think that the answer from AlfonsoGarnett is the best. Thank you though, for your answer, and I might use it later on! – FoxInFlame Commented May 19, 2015 at 7:13
1 Answer
Reset to default 10Here's a way to do it.
A brief explanation of how this works:
- It looks for all codes in the string with a regex that matches them (see the very first line in the
parseStyle
function) - It pushes the indexes of where those codes are in the string into an array, and replaces each code with a double
\x00
(null char), in order to handle repetition of codes in later parts of the string (see the firstfor
loop). - It splits the string into parts, in accordance to the start of one code and the start of another, so that each part can be styled individually, with its own rules.
- Also in the second loop, the strings are sent to the
applyCode
function, which applies the codes given to it (through an array), with the help of thestyleMap
. This function creates aspan
element for each string it is given. If it finds thek
rule, it will also apply theobfuscate
function. - The
obfuscate
function takes a string, gets its length, and generates a random character for every character in the string. It does this in an interval, char by char. The range of characters it chooses can be modified by changing therandInt
values in thereplaceRand
function. - Finally, the script returns an object with two properties: one is
parsed
which returns a DOM element with the 'obfuscators' running, and the other israw
, which returns the span elements as a HTML string (it's justparsed
's innerHTML).
To use it, just call mineParse(string)
, for instance:
var result = mineParse('§6Hello');
document.body.appendChild(result.parsed);
This now supports converting newlines to <br>
tags, the §r
reset code, and multiple codes applied in any order.
I'm sure the script can be further simplified, though. Also, I'm sure it has bugs, you can modify it as you wish.
http://jsfiddle/fku9gsax/12/
(function () {
'use strict';
var currId = 0,
obfuscators = {},
alreadyParsed = [],
styleMap = {
'§0': 'color:#000000',
'§1': 'color:#0000AA',
'§2': 'color:#00AA00',
'§3': 'color:#00AAAA',
'§4': 'color:#AA0000',
'§5': 'color:#AA00AA',
'§6': 'color:#FFAA00',
'§7': 'color:#AAAAAA',
'§8': 'color:#555555',
'§9': 'color:#5555FF',
'§a': 'color:#55FF55',
'§b': 'color:#55FFFF',
'§c': 'color:#FF5555',
'§d': 'color:#FF55FF',
'§e': 'color:#FFFF55',
'§f': 'color:#FFFFFF',
'§l': 'font-weight:bold',
'§m': 'text-decoration:line-through',
'§n': 'text-decoration:underline',
'§o': 'font-style:italic'
};
function obfuscate(elem, string) {
var multiMagic,
currNode,
listLen,
nodeI;
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function replaceRand(string, i) {
var randChar = String.fromCharCode(randInt(64, 95));
return string.substr(0, i) + randChar + string.substr(i + 1, string.length);
}
function initMagic(el, str) {
var i = 0,
obsStr = str || el.innerHTML,
strLen = obsStr.length;
if(!strLen) return;
obfuscators[currId].push(
window.setInterval(function () {
if (i >= strLen) i = 0;
obsStr = replaceRand(obsStr, i);
el.innerHTML = obsStr;
i++;
}, 0)
);
}
if (string.indexOf('<br>') > -1) {
elem.innerHTML = string;
listLen = elem.childNodes.length;
for (nodeI = 0; nodeI < listLen; nodeI++) {
currNode = elem.childNodes[nodeI];
if (currNode.nodeType === 3) {
multiMagic = document.createElement('span');
multiMagic.innerHTML = currNode.nodeValue;
elem.replaceChild(multiMagic, currNode);
initMagic(multiMagic);
}
}
} else {
initMagic(elem, string);
}
}
function applyCode(string, codes) {
var elem = document.createElement('span'),
obfuscated = false;
string = string.replace(/\x00/g, '');
codes.forEach(function (code) {
elem.style.cssText += styleMap[code] + ';';
if (code === '§k') {
obfuscate(elem, string);
obfuscated = true;
}
});
if (!obfuscated) elem.innerHTML = string;
return elem;
}
function parseStyle(string) {
var finalPre = document.createElement('pre'),
codes = string.match(/§.{1}/g) || [],
codesLen = codes.length,
indexes = [],
indexDelta,
apply = [],
strSlice,
i;
if (!obfuscators[currId]) obfuscators[currId] = [];
string = string.replace(/\n|\\n/g, '<br>');
for (i = 0; i < codesLen; i++) {
indexes.push(string.indexOf(codes[i]));
string = string.replace(codes[i], '\x00\x00');
}
if (indexes[0] !== 0) {
finalPre.appendChild(applyCode(string.substring(0, indexes[0]), []));
}
for (i = 0; i < codesLen; i++) {
indexDelta = indexes[i + 1] - indexes[i];
if (indexDelta === 2) {
while (indexDelta === 2) {
apply.push(codes[i]);
i++;
indexDelta = indexes[i + 1] - indexes[i];
}
apply.push(codes[i]);
} else {
apply.push(codes[i]);
}
if (apply.lastIndexOf('§r') > -1) {
apply = apply.slice(apply.lastIndexOf('§r') + 1);
}
strSlice = string.substring(indexes[i], indexes[i + 1]);
finalPre.appendChild(applyCode(strSlice, apply));
}
return finalPre;
}
function clearObfuscators(id) {
obfuscators[id].forEach(function (interval) {
clearInterval(interval);
});
alreadyParsed[id] = [];
obfuscators[id] = [];
}
window.mineParse = function initParser(input) {
var parsed,
i = currId;
if (i > 0) {
while (i--) {
if (alreadyParsed[i].nodeType) {
if (!document.contains(alreadyParsed[i])) {
clearObfuscators(i);
}
}
}
}
parsed = parseStyle(input);
alreadyParsed.push(parsed);
currId++;
return {
parsed: parsed,
raw: parsed.innerHTML
};
};
}());
@media (max-width: 850px) {
div#inBetween {
width: 100%;
box-sizing: border-box;
padding: 0.05em;
}
#inBetween:before {
display: inline-block;
font-family:'FontAwesome';
content:"\f107";
animation: bounceDown 2s infinite;
}
}
@media (min-width: 850px) {
#inBetween:before {
display: inline-block;
font-family:'FontAwesome';
content:"\f105";
animation: bounceRight 2s infinite;
}
}
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
button::-moz-focus-inner {
border: 0;
}
body {
text-align: center;
background: #050A0E;
font-family:'Open Sans', sans-serif;
overflow-x: hidden;
}
#mainContainer {
padding: 5em 0 5em 0;
}
h1 {
font-weight: bold;
color: #5EB4E7;
text-shadow: 0 0 50px #5EB4E7;
padding: 1em;
margin: 0;
animation: fadeIn 2s ease-in-out;
}
#inputContainer, #outputContainer {
display: inline-block;
padding: 1em;
width: 20em;
height: 21em;
background: #152E3D;
box-shadow: 0 0 4px #5EB4E7;
vertical-align: middle;
animation: scaleIn 1s ease-in-out;
}
#inBetween {
display: inline-block;
vertical-align: middle;
color: #5EB4E7;
font-size: 4em;
padding: 0.5em;
animation: scaleIn 1s ease-in-out;
}
#outputContainer {
display: inline-block;
padding: 1em;
vertical-align: top;
border-radius: 0 5px 5px 0;
}
#inputContainer {
border-radius: 5px 0 0 5px;
}
#input {
box-sizing: border-box;
padding: 1em;
width: 20em;
max-width: 20em;
height: 20em;
max-height: 20em;
}
#output {
background: rgba(255, 255, 255, 0.97);
text-align: left;
animation: bounceInRight 1s;
}
#output pre {
margin-top: 0;
padding: 1em;
border: 4px solid #050A0E;
overflow: auto;
max-height: 20em;
animation: bounceInRight 0.5s;
}
#input, #parse, #parse:active, #parse:focus {
padding: 1em;
width: 20em;
background: #050A0E;
color: #5EB4E7;
outline: 0;
outline-style: none;
outline-width: 0;
box-shadow: none;
border: none;
}
#parse {
transition: all 225ms ease-in-out;
border-radius: 0 0 5px 5px;
}
#parse:hover {
color: rgba(255, 255, 255, 0.8);
background: #5EB4E7;
cursor: pointer;
box-shadow: 0 0 25px #5EB4E7;
}
.containerLabel {
position: relative;
top: -0.5em;
left: -1.5em;
color: #5EB4E7;
text-align: left;
margin-left: 1.5em;
font-size: 80%;
font-weight: bold;
opacity: 0.85;
margin-bottom: 0.25em;
text-shadow: 0 0 40px #5EB4E7;
}
.bounceInRight {
animation: bounceInRight 1s;
}
@keyframes bounceRight {
0%, 20%, 50%, 80%, 100% {
transform: translateX(0);
}
40% {
transform: translateX(-10px);
}
60% {
transform: translateX(-5px);
}
}
@keyframes bounceDown {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
@keyframes bounceInRight {
0% {
opacity: 0;
transform: translateX(2000px);
}
60% {
opacity: 1;
transform: translateX(-30px);
}
80% {
transform: translateX(10px);
}
100% {
transform: translateX(0);
}
}
@keyframes flipInY {
0% {
transform: perspective(400px) rotateY(90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotateY(-10deg);
}
70% {
transform: perspective(400px) rotateY(10deg);
}
100% {
transform: perspective(400px) rotateY(0deg);
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1
}
}
@keyframes scaleIn {
0% {
transform: scale(0);
}
80% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
<link rel="stylesheet" href="style/style.css">
<script src="js/mine-parse.js"></script>
<link href='http://fonts.googleapis./css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn./font-awesome/4.3.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare./ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="mainContainer">
<h1> <i class="fa fa-code"></i> MineParse </h1>
<div id="inputContainer">
<div class="containerLabel">
<i class="fa fa-pencil-square"></i>
Input
</div>
<textarea id="input">
§nMinecraft Formatting
§r§00 §11 §22 §33
§44 §55 §66 §77
§88 §99 §aa §bb
§cc §dd §ee §ff
§r§0k §kMinecraft
§rl §lMinecraft
§rm §mMinecraft
§rn §nMinecraft
§ro §oMinecraft
§rr §rMinecraft
</textarea>
<button id="parse">
<i class="fa fa-angle-right"></i>
Parse
</button>
</div>
<div id="inBetween"></div>
<div id="outputContainer">
<div class="containerLabel">
<i class="fa fa-eye"></i>
Output <span id="parseTime"></span>
</div>
<div id="output"></div>
</div>
<script>
(function () {
'use strict';
var input = document.getElementById('input'),
output = document.getElementById('output'),
parseBtn = document.getElementById('parse'),
parseTime = document.getElementById('parseTime'),
outputContainer = document.getElementById('outputContainer'),
scrollInterval;
parseBtn.onclick = function () {
var scrollY = window.pageYOffset,
outputY = outputContainer.offsetTop,
parseStart = Date.now(),
result = mineParse(input.value);
parseTime.innerHTML = '~ ' + ((Date.now() - parseStart) / 1000) + ' seconds';
clearInterval(scrollInterval);
output.innerHTML = '';
if (window.innerWidth < 850) {
scrollInterval = setInterval(function () {
scrollY += 5;
window.scrollTo(0, scrollY);
if (scrollY >= outputY) {
window.scrollTo(0, outputY);
clearInterval(scrollInterval);
}
}, 0);
}
output.appendChild(result.parsed);
};
}());
</script>
本文标签: javascriptTranslating Minecraft Color Codes into HTMLStack Overflow
版权声明:本文标题:javascript - Translating Minecraft Color Codes into HTML - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741703671a2393436.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论