I have a problem that I can not answer. I write an BBCODE editor with switch between a WYSIWYG editor and code editor.
The visual editor is built from a drag and drop blocs system (picture, text, ...)
In the visual editor, when an user drag a new text bloc, the content is automatically written between [text][/text]
tags.
In the code editor, user can write free text without [text][/text]
tags.
To be able to switch between the two editors, free text need to be added between [text][/text]
tags in code editor.
Example :
I write text and bbcode in code editor :
Cum haec taliaque sollicitas eius aures everberarent expositas semper eius modi
rumoribus et patentes.
[img]https://foo.com/fighters.png[/img]
Denique Antiochensis ordinis vertices sub uno elogio iussit occidi ideo efferatus,
quod ei celebrari vilitatem intempestivam urgenti, cum inpenderet inopia
[img]https://foo.com/fighters1.png[/img]
[img]https://foo.com/fighters2.png[/img]
Utque proeliorum periti rectores [i]primo catervas[/i] densas opponunt et fortes,
deinde leves armaturas, post iaculatores ultimasque subsidiales acies, si fors
adegerit
If i switch to visual editor, the free text need to be added between [text][/text]
like this:
[text]Cum haec taliaque sollicitas eius aures everberarent expositas semper eius modi
rumoribus et patentes.[/text]
[img]https://foo.com/fighters.png[/img]
[text]Denique Antiochensis ordinis vertices sub uno elogio iussit occidi ideo efferatus,
quod ei celebrari vilitatem intempestivam urgenti, cum inpenderet inopia[/text]
[img]https://foo.com/fighters1.png[/img]
[img]https://foo.com/fighters2.png[/img]
[text]Utque proeliorum periti rectores [i]primo catervas[/i] densas opponunt et fortes,
deinde leves armaturas, post iaculatores ultimasque subsidiales acies, si fors
adegerit[/text]
I think there are two ways:
- Split text and bbcode with loops, and rebuild code with another loops.
- Use a regex to get free text and replace it.
What the best way ? Do you think that possible to add the tags from a regex ?
Thank you,
Thomas
Answer
Try with this:
const regex = /(\[(img|\w{4,})\][\s\S]*?\[\/\2\])(\n?)|([\s\S]+?)(\n?)(?=$|\[(?:img|\w{4,})\])/gi;
let str = `
Cum haec taliaque sollicitas eius aures everberarent expositas semper eius modi
rumoribus et patentes.
[image]https://foo.com/fighters.png[/image]
Denique Antiochensis ordinis vertices sub uno elogio iussit occidi ideo efferatus,
quod ei celebrari vilitatem intempestivam urgenti, cum inpenderet inopia
[image]https://foo.com/fighters1.png[/image]
[image]https://foo.com/fighters2.png[/image]
Utque proeliorum periti rectores [i]primo catervas[/i] densas opponunt et fortes,
deinde leves armaturas, post iaculatores ultimasque subsidiales acies, si fors
adegerit`;
let m;
let outstr = '';
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) { regex.lastIndex++; }
// The result can be accessed through the `m`-variable.
// m[1] == structure tags
// m[4] == text content
// m[3] nad m[5] are new lines (if present)
if (typeof m[1] != 'undefined') {
outstr += m[1] + m[3];
}
else {
outstr += '[text]' + m[4] + '[/text]' + m[5];
}
}
console.log(outstr);
On the regex, you use the first capturing group to get rid of the structural tags. And the second group for the rest of the data. If the first group has data then it means we found an structural tag. We just accumlate it. If not, then it means it is text. So we accumulate it with the new [text]
tags
Finally, on 3rd and 5th capturing group you have the new lines (if present)
The second capturing group is used for making the opening and closing tag equal.
Regex explained:
# First option: an structural tag ([image]...[/image]
( # First capturing group
\[ # Literal '['
(img|\w{4,}) # img tag or tag with 4 or more letters (all structural tags)
\] # Literal ']'
[\s\S]*? # Any character 0 or more times, ungreedy
\[\/\2\] # Closing tag. Word = same as opening tag
)(\n?) # a new line may appear. Save it on third capturing group
# Second option: other text
| ([\s\S]+?) # Any character 1 or more times, ungreedy. Third capturing group
(\n?) # A new line may appear, Don't want it on the previous group
(?= # Lookahead. The following must appear (but we don't match it)
$ # Either end of line
| \[(?:img|\w{4,})\] # or some opening structural tag
)
No comments:
Post a Comment