A JavaScript program to output different languages with code.color
(or span.color
, haven't decided yet) classes for syntax highlighting. This is a manual process, as opposed to using PrismJS.
If you would like to see an example, check my Pre tag formatter in CodePen.
This project is for personal use so I had to add
js/input.js
in the HTML file because I am using Live Server and you need HTTPS for modules. I just want the code to add to my blog posts.
- At this point, you have to paste your code to the variables in backticks in
js/input.js
. - Those strings are brought into
js/script.js
as a variable and then split. - Depending on the language you are working on, uncomment
convertCode(arr)
after the comment/* CHOOSE THE LANGUAGE YOU WANT TO CONVERT: */
for the language you want.convertCode(arr)
converts reserved characters (< > ' " &
) to HTML entities
- Also unccoment the appropriate
createClass(input, arr)
line under/* CHOOSE THE LANGUAGE YOU WANT TO OUTPUT: */
- Then save
script.js
and copy the code under Code to copy for dark code block. - Paste that code between the comments under the
pre
block in the HTML file so theli
tags break to a new line. Then remove the opening and closingli
tags. - Finally, cut and paste the remaining code into your
pre
block.
NOTE: I added data-
attributes to indicate each line number to make it easier to see each new line among all the code tags.
You will need to TAB the entire code block to be indented in from your pre
tag. You may also have to use the SPACEBAR key for nested/indented lines.
The code in the pre
tag will look funky but you should not have to touch it after pasting it other than for indentation. I have noticed some exceptions though, so you may need to adjust some of the code
tags, but I've only seen that with long lines.
- Paste your code into
js/input.js
and save - Uncomment to 2 functions for the language you want.
- Open
index.html
and copy the code - Paste the code into a blank area in
index.html
so that the<li>
tags break to a new line - Remove all opening and closing
li
tags - Cut and paste that code into your
pre
tag - Adjust the spacing if necessary with the TAB and SPACEBAR keys.
- When it looks good, copy the entire
pre
block into your blog post.
NOTE: If you only want the code that has the reserved characters converted to HTML entities, then that Code to copy is at the bottom of index.html
.
HTML:
index.html
: has an example for a dark code block on a light background and a light code block on a dark background. It also has examples for each language, and styling forcode
,kbd
, andvar
tags. It also has brief notes similar to above.dark.html
has a light background and a darkpre
ode block.light.html
has a dark background and a lightpre
ode block.
CSS: css/style.css
has the styling for index.html
, css/dark.css
for dark.html
, css/light.css
for light.html
JavaScript: js/script.js
is for index.html
, js/dark.js
is for dark.html
, js/light.js
is for light.html
js/script.js
: I use textContent
to output the code
tags to the DOM, but in that forEach
I also have innerHTML
commented out. Turn that one on to see the coloring for your code to make sure it looks good. That method is really helpful!
I am using regualr expressions to wrap parts of a language in code tags with a color class. Here is a list of the languages I will be covering and ones I am done:
- HTML
- CSS (except HTML selectors AND Classes)
- SASS/SCSS (except HTML selectors AND Classes)
- JavaScript (except numbers AND template literals)
- JSON
- PHP (with a few exceptions)
- JSX and Astro
- Markdown (except unordered lists, blockquotes and diff blocks)
I have different colors for both a dark code block and a light code block, even though I personally will only be using the dark code block colors. I will be tweaking those colors as I go.
I added the colors to an array which is used to output the code tags with the appropriate color class.
Other languages/syntax I want to cover: Git and Git Bash, NPM commands, SQL, React/JSX and Astro, YAML, and Apache.
NOTE: All languages use the same color for anything in single quotes, double quotes, and backticks.
HTML: All good!
CSS:
- I removed the check for double-quotes (Regex:
dblQuotes
,"
), so make sure your quotes are only single-quotes, e.g.url
,content
,@import
and/or some font families. Feel free to add that RegEx back tocssRegEx
. - The multi-line comment type
/* */
works, but//
does not output for some reason so only use the 1st one. - I can't seem to escape
//
so using web urls like Google fonts also creates a problem so don't use them until I fix that. - I can match and replace variable names in
var()
but not the declaration. - My regular expression for Classes and Ids (
.#
) works but it also selects file or URLs with a.
in it. So either don't use@import
,url
, etc., or remove the period and add it back as the last step. It also breaks for pseudo-classes likenth-child
. - HTML tag selectors have to be done manually until I figure the RegEx to select only them. Use Emmet wrap with abbreviation and add the appropriate
code.color
class..
That's some serious issues for CSS, and I have not tested out all the various combinators, pseudo-classes, pseudo-selectors, and other edge cases.
JSON: All good!
SASS:
- All the same issues as with CSS.
- Since there are a lot more unique syntax for SASS, I have only tested the most common. I'm going to need help testing all the syntax and figuring out the regular expressions.
JavaScript:
- I have a selected list of keywords - the ones I use. Here is the complete list. Also, I had to put
typeof
beforeof
because my RegEx skills are intermediate at best:
// I left off null and undefined
const jsKeywords =
/(?<=\(?)(typeof|as|assert|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|of|package|private|protected|public|return|set|static|super|switch|throw|try|var|void|whilewith|yield)(?=\s)/g;
- Single quotes and double quotes are fine
- Template literals: I am putting the code in a template literal so adding a template literal inside is not easy (see example in
input.js
). I had to use a simple RegEx and it has to be a single line template literal. - I can't seem to select numbers without an extreme number of empty code tags.
PHP:
- Having problems grabbing
$
as a prefix tothis
- Having problems grabbing custom classes instances
- For some reason comments are not geing grabbed???
- I also have a reduced number of keywords. Add more if you do not see ones you use:
const phpKeywords =
/(?<=\(?)(while|new|array|echo|endwhile|else|elseif|class|function|return|break|catch|continue|default|endfor|endforeach|enum|eval|exit|extends|final|finally|foreach|instanceof|insteadof|match|namespace|require|static|switch|throw|try)(?=\s)/g;
Markdown:
- The foolwoing are good: Headings, Images, links, footnotes, HTML tags, and ordered lists
- Blockquotes issue: you can alphanumeric (
\w
) characters but not other characters. This one may have to manually havecode.green
is you have quotes inside or any other non word char. My RegEx works in regexr.com but not in my JavaScript. - I had to remove the
-
for unordered lists because it is grabbing other dashes - Diff blocks: I was not able to select the
-
for the changes/old code line. I was able to in regexr.com but not in this app. I'll have to manually add red. - Outputting backticks will require some creativity when it comes to inline code. Language blocks can be simulated by using the language in question then adding backticks above and below the code block.
I only have regular expressions for languages that I use. If you would like to contribute to this repo for additional languages (or improve mine), then open an issue or fork the repo and create a Pull Request. Hopefully, you are good with regular expressions. Although, feel free to suggest any changes.
- RegEx for Markdown blockquotes - see issue #2
- RegEx for Markdown unordered lists - see issue #3
- RegEx capture groups issue - see issue #4
- RegEx for CSS classes - see issue #5
NOTE: I just updated the styles for my WordPress theme and my pre code blocks did not wrap but instead stretched out on a single line:
.code-block
with a property ofoverflow: auto;
did not take effect- I had to add a
div
tag around thepre
block with a class ofpre-container
and withwidth: 100%;
That seems ridiculous but that is what I needed to do. Take that into account if you are using these codeblocks on a WordPress site.
I noticed that I missed updating a few codeblocks in my markdown article so I started to add the new code. Things got messed up again. My solution was to manually redo every code block and remove empty span.color
tags and to make sure there were no line breaks for the opening code
tags.
What a PITA!
Let's see how a new blog article looks with my new classes and CSS. Here are the articles I updated that used my CSS from this project:
- Learn JavaScript: String and Array Methods (online inline
code
examples) - Markdown Cheat Sheet for Beginners
- WordPress Recent Posts using a Custom Query