Sunday, March 31, 2019

javascript - Add tags to the text outside of bbcode tags



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.



Demo on regex101



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

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...