Simple code styling tool

Seeking guidance to create a basic syntax highlighter using JavaScript or ClojureScript. While aware of existing projects like Codemirror and rainbow.js, I'm interested in understanding how they are constructed and looking for a simple example.

Do these projects rely on language parsing (using tools like PEG.js)? Ideally, I'd prefer language parsing over regex, but once a language is defined, how can it be converted into a syntax highlighter? Re-parsing the entire text and applying formatting after every keypress seems inefficient. What's the best way to achieve this efficiently? Tracking cursor position and considering surrounding characters, possibly using a state machine?

Any assistance would be highly appreciated! Thank you.

Answer №1

Initially, this question may not align well with the typical queries on StackOverflow. The site generally caters to inquiries that are precise and revolve around actual code.

Ideally, I am interested in parsing the language using a method other than regex.

Before delving into code, it's crucial to grasp how a language parser operates. Avoid relying solely on regular expressions, as they're tailored for regular languages while JavaScript isn't one.

The process of language parsing comprises two main phases: lexical analysis and token parsing. Breaking down text into tokens simplifies the parsing task compared to directly parsing the text. Despite JS introducing minor complexities due to lexical ambiguities stemming from the use of / for division, comments, and regular expressions, these challenges are surmountable.

Create a lexer followed by a parser to tackle your parsing needs. However, a lexer alone might suffice for your requirements.

It's essential to handle correct parsing of potentially flawed JS code, considering that users typically input incomplete or erroneous programs during typing. Implementing effective error recovery mechanisms in your lexer and parser is pivotal for ensuring a seamless user experience.

Is it necessary to reparse the entire text and apply formatting after every keystroke?

Performance considerations hinge on the efficiency of your parser and the size of the file being processed.

In developing the Roslyn syntax highlighter, our team encountered scenarios involving files with extensive line counts still undergoing edits. Due to performance constraints, we refrain from re-parsing the complete file post each keypress. Instead, we leverage an immutable parse tree for swift traversal to identify the impacted token. Subsequently, we determine the parse nodes requiring re-evaluation, initiating re-lexing and re-parsing exclusively on those nodes. This approach enables us to construct a new immutable parse tree incorporating unaltered segments from the prior tree.

Furthermore, syntax coloring operations are confined to portions of the file visible to the user.

It's worth noting that alongside syntactic evaluations between keystrokes, Roslyn extends its capabilities to encompass semantic analyses, marking a distinct facet of its functionality.

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

Differences in Cross-Browser Styling for ListView Item Templates

I'm following up on my previous query regarding ListView's ItemTemplate table styling. I am still working on achieving the desired look for the ItemTemplate: ______________________________________________ | |___________Title_______ ...

Script tag in NextJS

After numerous attempts, I am still struggling with a specific task on this website. The challenge is to insert a script tag that will embed a contact form and newsletter sign-up form, among others, on specific pages of the site. For instance, the contact ...

Comparable user interface on par with what we find on Windows Phone 7

I'm quite impressed with the innovative interface experience of Windows Phone 7. It stands out compared to other interfaces, whether on mobile devices, desktops, or the web. Despite its uniqueness, it remains highly usable. Overall, a great step in th ...

I'm encountering an issue with my React 18 application using TypeScript: the module './App' cannot be found

Encountering an issue while attempting to update to react 18. I'm curious if this problem is related to my file types. I am using Typescript, so do both the app and index files need to have a .tsx extension? Both the app and index files are located ...

Sending information from a parent component to a child component in Vue.js and then showcasing the data

Hey there! I'm new to vue.js and I'm struggling to figure out why my data is not being passed to the child component. I've tried a few different approaches, but none seem to be working as expected. It feels like I'm really close, but so ...

Controller Not Deserializing Ajax File Upload in MVC 5

There seems to be an issue with deserializing the data sent using the multipart/form-data type within an MVC 5 project. Despite appearing valid in Fiddler, the data is not being mapped into the controller method. While debugging, it is evident that all par ...

Having trouble capturing screenshots with PuppeteerJS?

I've encountered an issue while working with Puppeteer to capture screenshots from a provided URL. The code I have below doesn't seem to be functioning properly. It keeps showing the error message: [0] Error: Protocol error (Emulation.setDeviceM ...

Unusual SASS results observed while utilizing extends functionality

Having issues with my SASS files: _android.scss: $width: 111px; @import 'child'; .android .child { @extend %child; } _ios.scss: $width: 999px; @import 'child'; .ios .child { @extend %child; } _child.scss: %child { wi ...

Errors related to Typescript are causing issues with the stock installation of Next.js

Whenever I use typescript with create-next-app, my tsx files are filled with numerous "Problems" messages. These errors only appear in Visual Studio Code and do not affect the build process. I have tried uninstalling vscode, removing all extensions, and ...

Securing my private key on a webpage from potential exposure by mandrillapp

After successfully creating and adding the key in Mandrill, I am able to send emails from my JavaScript page hosted at this link: However, I am facing an issue where my Mandrill key is publicly visible (in the contact_me.js file). I attempted to restrict ...

Having trouble importing the named export `{module}` from a non-ECMAScript module with TipTap and Nuxt?

I'm using TipTap with Nuxt and running into some issues that I can't seem to resolve. Despite following suggestions from the repository's issues, I keep encountering these specific errors: ERROR in /Volumes/Projects/nuxt/candy-hub-lerna/no ...

NextJs Link component does not refresh scripts

While using the <Link> tag in NextJs for page navigation, I encountered an issue where my scripts do not rerun after switching pages. The scripts only run on the initial page load or when I manually reload the page. This behavior is different when us ...

A guide on implementing the stencilFunc method in Three.js

Is it possible to utilize stencilFunc and stencilOp functions within Three.js? I attempted to incorporate code for a stencil test but encountered issues. var scene = new THREE.Scene(); var renderer = new THREE.WebGLRenderer({ antialias: true, st ...

What is the method for displaying Facebook comments alongside the WordPress comments count?

I am currently using a template theme that initially had WordPress comments enabled on the website. By implementing the Facebook Comments plugin, I have successfully replaced Wordpress comments with Facebook Comments. **However, there seems to be an issue ...

There seems to be a glitch in the functionality of annotations when using annotator.js

Currently, I am utilizing annotator.js to store the range in mysql. The following code fragment is being used for highlighting text within my file: <script src="/js/pdfjs/annotator.js"></script> <script> $(function(){ var annotation ...

Ways to verify the occurrence of a successful event following the execution of a save() operation on a model

Below is the snippet of code I am using to store extra properties in a model (specifically, the answer model) selectMedia: => # Post media to server @options.answer.id = @options.answer.get('_id') @options.answer.url = "/v1/answers/#{@o ...

What is the best way to create a Table with a Scroll feature and a fixed Header using CSS code, ensuring it looks sleek and functional across all devices, including smartphones?

I needed a CSS code for my Asp.Net Core Code that would apply to multiple tables. The desired style should include a fixed table header with a scrollable body, ensuring alignment between rows and columns. Despite trying various alternatives, I couldn' ...

The "scrollTop" function seems to be malfunctioning in Firefox but works perfectly fine in Chrome. Is there a way to fix this issue?

Issue with scrollTop in Firefox jQuery(window).scroll(function(){ var NextScroll = jQuery(this).scrollTop(); if (NextScroll >= 800){ jQuery('#logomacchia').addClass("maccancello"); } else { jQuery('#logomacch ...

Node.JS guide on handling geonames city information

While unconventional, I wanted to share my solution since there is a lack of information on how to accomplish this task on the stack. After searching for an easy-to-use Node.JS module to process geonames data into a mongo database, I found very few project ...

Playwright failing to execute GraphQL tests due to TypeScript configuration problems

I'm facing an issue with my repo where I am running tests using Playwright against a graphQL URL. Despite configuring the tests, there is an error indicating that the environment variable defining the environment cannot be found. The repository in qu ...