Include certain tags to the content within the text apart from using bbcode tags

I need help with a project involving a BBCODE editor that can switch between a WYSIWYG editor and a code editor.

The visual editor is designed with a drag-and-drop block system for elements like pictures and text.

In the visual editor, when a user drags a new text block, the content is automatically placed between [text][/text] tags.

In the code editor, users can freely write text without [text][/text] tags.

To seamlessly switch between the two editors, free text needs to be enclosed in [text][/text] tags in the code editor.

For example:

If I write text and bbcode in the 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 the visual editor, the free text must be enclosed in [text][/text] tags 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'm considering two approaches:

  • Splitting text and bbcode using loops, then reconstructing the code with another set of loops.
  • Using regex to extract free text and replace it accordingly.

Which method do you think is better? Is it feasible to add the tags using regex?

Thank you, Thomas

Answer №1

Give this a shot:

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) {
    if (m.index === regex.lastIndex) { regex.lastIndex++; }

   
    if (typeof m[1] != 'undefined') {
        outstr += m[1] + m[3];
    }
    else {
        outstr += '[text]' + m[4] + '[/text]' + m[5];
    }
}
console.log(outstr);

The regex uses the first capturing group to handle structural tags and the second group for remaining data. If the first group has data, it's an opening or closing tag which is accumulated. If not, it's text content wrapped in [text] tags.

Capturing groups 3 and 5 account for new lines when present.

The second capturing group ensures matching opening and closing tags.

See demo on regex101

Regex breakdown:

   # First option: Structural tag ([image]...[/image]
   ( # Capture group one
     \[ # Literal '['
       (img|\w{4,}) # img tag or tag with 4+ letters (all structural tags)
     \] # Literal ']'
     [\s\S]*? # Any character 0+ times, ungreedy
     \[\/\2\] # Closing tag. Word matches opening tag
   )(\n?) # Optional new line as third capture group

   # Second option: Other text
 | ([\s\S]+?) # Any character 1+ times, ungreedy. Fourth capture group
   (\n?)      # Optional new line, not included in previous group
   (?=         # Lookahead. Following condition must be met (not matched)
        $       # End of line 
      | \[(?:img|\w{4,})\] # Opening structural tag
   )
 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

streaming an HTML5 video directly from memory source

After retrieving multiple encrypted data using ajax queries and performing necessary manipulations to turn them into a valid video, I find myself at a standstill. The binary of the video is now stored in memory, but I am unsure how to display it. To confi ...

Transfer the chosen language from the uib-dropdown language selector to the $scope variable

Here is a HTML template that allows the user to select a language: <div class="btn-group" uib-dropdown> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" uib-dropdown-toggle> ...

Switching Profiles in XPages

In my Xpages project, I have two different user profiles set up. I am currently attempting to develop a function that would allow me to easily switch between these two profiles. However, I am unsure of the steps needed to accomplish this task. ...

The React.js Mui Collapse component exclusively triggers animation during the transition while closing, without any animation when expanding

Whenever I implement the Collapse component from Mui library in my projects, I face an issue where the transition animation only works when closing the component (when in={false}). However, when opening the component, there is a delay before the animation ...

What is causing this code to malfunction in AngularJS version 1.2?

Check out this code snippet I wrote using Angular 1.2: http://jsfiddle.net/VmkQy/1/ <div ng-app="app"> Title is: <span my-directive data-title="Test title">{{ title }}</span> </div> angular.module('app', []) .dir ...

When running through Selenium web driver, JS produces inaccurate results

Currently, I am utilizing JavaScript to determine the number of classes of a specific type. However, when I run the JS code in Webdriver, it provides me with an incorrect value. Surprisingly, when I execute the same JavaScript on the Firebug console, it gi ...

Implementing an object as a filter in an NG-repeat function

I've created multiple select dropdowns that are populated from a JSON file containing categories. My goal is to use the selections made by users in the dropdowns to filter a list of apps generated using ng-repeat. In my Plunker example http://plnkr. ...

Using Bootstrap4 to merge rows into a single column or apply rowspan in Bootstrap

Hey there, I have a specific requirement that I need help with. Check out the image here. I want to enable the LCM information box when the LCM checkbox is checked. Below is my code: <div class="panel-body "> <div class="c ...

Tips for implementing the handleClick method within a class component, as opposed to using the export default function syntax in

Hey there! I'm a beginner in React and I'm trying to incorporate Material UI into my project. I came across the documentation for the menu section like this, but I'm facing some challenges with writing my code. Specifically, I'm struggl ...

Tips for preventing the inner surface from appearing transparent in WebGL

I am working with the code snippet provided below. The issue I am currently facing is that one side of the partial sphere is non-transparent, while the other side remains transparent. How should I modify the code to make both sides non-transparent? Thank y ...

The error "Unable to create an instance of mssql.Schema" indicates that the

Seeking assistance from experienced ReactJS developers to address the issue outlined below. The code provided is based on a tutorial I was following. Despite numerous attempts, I have been unable to resolve the issue. Here is the code snippet from User.js ...

The Vue.js application is failing to toggle the integrated code

I am new to using Vue and I am trying to create a vertical navigation bar. When the menu icon is clicked, the navbar should toggle. Here is my menu icon code: <button type="button" id="sidebarCollapse" class="btn btn-info [collapsed?'': ...

Using React Native's stylesheet to apply multiple values in a CSS statement

Here's a scenario to help clarify my question: Imagine I want to add margin to an element in the following way: const myView = () => <View style={styles.viewStyle}></View> const styles = StyleSheet.create({ viewStyle: { margin: ...

How can I dynamically show the corresponding name for a given ID in Django without the need to refresh or submit the form?

I need to dynamically display a user's name above the input box where they enter their Employee number on a form without refreshing the page. After entering the Employee number and moving to the next field, the user should see their name displayed on ...

Vuex data fails to update upon browser reload in Nuxt SSR

After explaining the bug, I discovered something interesting; Component codes async fetch(){ await this.$store.dispatch('bots/getBots') }, computed: { ...mapState('bots', ['bots']) }, Store codes export const state = () ...

Tips for ensuring a webpage loads at a specific resolution

I recently created a website on my computer with a screen resolution of 1920x1020. However, when I view it on other machines with a 1366x768 resolution, the website appears distorted. Is there a way to set a fixed resolution for my website to ensure it l ...

Receive characteristics in component specification

Is there a way to pass the native attributes of an img element to a custom image component without explicitly defining each one, like alt, and have them all be applied to the img tag? Here is an example of what I mean: @Component({ selector: 'image ...

PHP is returning an empty response during an AJAX request

I am facing an issue with my AJAX request where I am trying to return a simple echo, but for some reason, it's not working this time. Even after stripping down the code to its bare essentials, the response is still blank. Javascript function getUs ...

Checking authentication globally using Vue.js

In the main blade file, I have the following code snippet: <script> window.App = {!! json_encode([ 'csrfToken' => csrf_token(), 'user' => Auth::user(), 'signedIn' => Auth::check() ...

A Complication Arises with Browser Functionality When Embedding an Iframe within

I am experiencing a peculiar problem while embedding an iframe with a specific src inside an absolutely positioned div. Here's the basic structure of the webpage: .container { position: relative; overflow: hidden; width: 100%; heigh ...