Github project

No chi-chi syntax highlighter for Vue.js 3 (and 2).

  • Easy to use
  • Easy to customize
  • Very light weight
  • Support multiple languages
  • Support both reading and editing
  • Built-in copy to clipboard button
  • Built-in light and dark modes

Supported languages

  • XML
  • HTML
  • HTML Vue JS Template
  • Pug
  • JavaScript
  • JSON
  • CSS
  • PHP
  • MySQL
  • No support for mixed nested languages

demo - try it!

/**
 * I can syntax-highlight your JavaScript code.
 * Try to type some code!
 */

import Vue from 'vue'

const radius = 25 // Radius in pixels.
console.log(2 * Math.Pi * radius)
/** * I can syntax-highlight your JavaScript code. * Try to type some code! */ import Vue from 'vue' const radius = 25 // Radius in pixels. console.log(2 * Math.Pi * radius)

Installation

You have two options: NPM or <script> tag.

Via NPM

npm i simple-syntax-highlighter # Vue 3
npm i simple-syntax-highlighter # Vue 3
or
npm i simple-syntax-highlighter@legacy # Vue 2
npm i simple-syntax-highlighter@legacy # Vue 2

Edit a Vue 3 example on Codepen://codepen.io/antoniandre/pen/jOqgoKR

Then import the component and use it:

// In your VueJS component.
import SshPre from 'simple-syntax-highlighter'
import 'simple-syntax-highlighter/dist/sshpre.css'
...

export default {
  components: { SshPre },
  ...
}
// In your VueJS component. import SshPre from 'simple-syntax-highlighter' import 'simple-syntax-highlighter/dist/sshpre.css' ... export default { components: { SshPre }, ... }

In some cases, like in Vite or vue-cli, you may need to preserve the white spaces in the project (if you see all the ssh-pre contents on a single line).
Here is how to preserve white spaces in Vite. Add this in your vite.config.js file:

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          whitespace: 'preserve'
        }
      }
    })
  ],
  ...
export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { whitespace: 'preserve' } } }) ], ...

Or in Vue CLI, add this in your vue.config.js file:

module.exports = {
  chainWebpack: config => {
    // Preserve white spaces for ssh-pre component.
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.whitespace = 'preserve'
        return options
      })
  }
}
module.exports = { chainWebpack: config => { // Preserve white spaces for ssh-pre component. config.module .rule('vue') .use('vue-loader') .loader('vue-loader') .tap(options => { options.compilerOptions.whitespace = 'preserve' return options }) } }

Via <script> tag

Include the Simple Syntax Highlighter script in your document <head> as follows:

<head>
  ...
  <script src="https://unpkg.com/vue"></script>
  <script src="https://unpkg.com/simple-syntax-highlighter"></script>
  <link href="https://unpkg.com/simple-syntax-highlighter/dist/vuecal.css" rel="stylesheet">
</head>
<head> ... <script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/simple-syntax-highlighter"></script> <link href="https://unpkg.com/simple-syntax-highlighter/dist/vuecal.css" rel="stylesheet"> </head>

How to use

Once included in your project, use as follows.

For any other language than HTML

<ssh-pre language="js" label="Javascript">
  const i = 3;
  // Some more Javascript content.
</ssh-pre>
<ssh-pre language="js" label="Javascript"> const i = 3; // Some more Javascript content. </ssh-pre>
renders as:
const i = 3;
// Some more Javascript content.
const i = 3; // Some more Javascript content.

For XML based languages

To use XML/HTML-like languages: you must escape the chevrons: &lt; for < and &gt; for >.
If you want to display an & character, you need to escape it with: &amp;amp;.

<ssh-pre language="html" label="HTML Vue Template">
  &lt;html lang="en"&gt;
    &lt;head&gt;
      &lt;title&gt;Title&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      Some content.
    &lt;/body&gt;
  &lt;/html&gt;
</ssh-pre>
<ssh-pre language="html" label="HTML Vue Template"> &lt;html lang="en"&gt; &lt;head&gt; &lt;title&gt;Title&lt;/title&gt; &lt;/head&gt; &lt;body&gt; Some content. &lt;/body&gt; &lt;/html&gt; </ssh-pre>
renders as:
<html lang="en">
  <head>
    <title>Title</title>
  </head>
  <body>
    Some content.
  </body>
</html>
<html lang="en"> <head> <title>Title</title> </head> <body> Some content. </body> </html>

Options

  • copy-button{Boolean}Default: false

    Allow copying this ssh-pre box content to the clipboard.

  • dark{Boolean}Default: false

    Switches this ssh-pre box to a dark theme.

  • editable{Boolean}Default: false

    Make this ssh-pre box editable and syntax-highlight as you type.

  • label{String}Default: ''

    A label to show on the top right of the ssh-pre box. If empty no label will show up.

  • language{String}Default: ''

    One of the supported programming languages to syntax highlight.

  • reactive (prior v.3.0 & 1.6.0){Boolean}Default: false

    Makes this ssh-pre box reactive to variable changes (not needed from version 3+ or 1.6+).

Copy button

With the option copy-button, you can add a button that allows copying the content to the clipboard.

The button content can be customized through the copy-button slot.

Default
<body>
  <div id="app"></div>
</body>
<body> <div id="app"></div> </body>
Custom button content
<body>
  <div id="app"></div>
</body>
<body> <div id="app"></div> </body>

On copy button press, the copied event is emitted containing the copied text.
Here is how to use the copy-button slot and the copied event.

<ssh-pre language="html-vue" copy-button @copied="onCopiedDoSomething">
  <template #copy-button>
    <i class="icon mdi mdi-content-copy"></i>
  </template>
  ...
</ssh-pre>
<ssh-pre language="html-vue" copy-button @copied="onCopiedDoSomething"> <template #copy-button> <i class="icon mdi mdi-content-copy"></i> </template> ... </ssh-pre>

Examples of rendering with different languages

javascript

/**
 * This is a
 * multiline comment.
 */
import Vue from 'vue'
import router from './router'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import '@fortawesome/fontawesome-free/css/all.css'
import './styles/index.scss'

Vue.use(Vuetify, {
  iconfont: 'fa',
  theme: {
    primary: '#1b4',
    secondary: '#666',
    maintext: '#999',
    lightgrey: '#eee'
  }
})

new Vue({ // eslint-disable-line no-new
  el: '#app',
  router,
  template: require('./template.pug'),
  data: () => ({
    offsetTop: 0,
    goTopHidden: true
  }),
  methods: {
    onScroll (e) {
      this.offsetTop = window.pageYOffset || document.documentElement.scrollTop

      this.goTopHidden = this.offsetTop < 200
    }
  }
})
/** * This is a * multiline comment. */ import Vue from 'vue' import router from './router' import Vuetify from 'vuetify' import 'vuetify/dist/vuetify.min.css' import '@fortawesome/fontawesome-free/css/all.css' import './styles/index.scss' Vue.use(Vuetify, { iconfont: 'fa', theme: { primary: '#1b4', secondary: '#666', maintext: '#999', lightgrey: '#eee' } }) new Vue({ // eslint-disable-line no-new el: '#app', router, template: require('./template.pug'), data: () => ({ offsetTop: 0, goTopHidden: true }), methods: { onScroll (e) { this.offsetTop = window.pageYOffset || document.documentElement.scrollTop this.goTopHidden = this.offsetTop < 200 } } })

CSS

:root {
  --primary-color: green;
}

pre.ssh-pre {
  position: relative;
  padding: 0.5em;
  margin: 2.5em 0 2em;
  border: 1px solid rgba(0, 0, 0, 0.06);
  background-color: rgba(0, 0, 0, 0.025);
  border-radius: 4px;
  display: block;
  white-space: pre-wrap;
  word-break: break-word;
}

.ssh-pre[data-label]:before {
  content: attr(data-label);
  position: absolute;
  bottom: 100%;
  right: 1em;
  padding: 0.1em 0.5em;
  background-color: #f8f8f8;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-bottom: none;
  border-radius: 3px;
  margin-bottom: -1px;
  font-size: 11px;
}

/* Syntax highlighting */
.ssh-pre .txt {color: #333;}
.ssh-pre .comment {font-style: italic;color: #aaa;}
.ssh-pre .comment * {color: inherit !important;}
.ssh-pre .quote {color: #c11;}
.ssh-pre .quote * {color: inherit !important;}
.ssh-pre .number {color: #c11;}
.ssh-pre .boolean {color: #c11;}
.ssh-pre .keyword {color: #33c;font-weight: bold;}
.ssh-pre .this {color: #c6d;font-weight: bold;}
.ssh-pre .punctuation {color: #99f;}
.ssh-pre .dollar,
.ssh-pre .special {color: #f63;}
.ssh-pre .variable {color: #29e;}
.ssh-pre .obj-attr {color: #0bc;}

.ssh-pre[data-type="shell"] .keyword {color: #ff5252;}
.ssh-pre[data-type="shell"] .param {color: #f63;}

.ssh-pre[data-type="html"] .doctype {color: #02027e;}
.ssh-pre[data-type="html"] .tag-name {color: #11c;}
.ssh-pre[data-type="html"] .attribute {color: #f63;}

.ssh-pre[data-type="html-vue"] .doctype {color: #02027e;}
.ssh-pre[data-type="html-vue"] .tag-name {color: #42b983;}
.ssh-pre[data-type="html-vue"] .punctuation {color: #128953;}
.ssh-pre[data-type="html-vue"] .attribute {color: #ff5252;}

.ssh-pre[data-type="xml"] .doctype {color: #02027e;}
.ssh-pre[data-type="xml"] .tag-name {color: #11c;}
.ssh-pre[data-type="xml"] .attribute {color: #f93;}

.ssh-pre[data-type="css"] .selector {color: #f0d;}
.ssh-pre[data-type="css"] .class-id {color: #f0d;}
.ssh-pre[data-type="css"] .pseudo {color: #f35;}
.ssh-pre[data-type="css"] .keyword {color: #f5f;}
.ssh-pre[data-type="css"] .vendor {color: #0c8;}
.ssh-pre[data-type="css"] .keyword {color: #c06;}
.ssh-pre[data-type="css"] .attribute {color: #70d;}
.ssh-pre[data-type="css"] .keyword {color: #e28;}
.ssh-pre[data-type="css"] .vendor {color: #0c8;}
.ssh-pre[data-type="css"] .value {color: #c11;}
.ssh-pre[data-type="css"] .value.vendor {color: #0c8;}
.ssh-pre[data-type="css"] .color {background: #eee;padding: 0px 3px;border: 1px solid rgba(0,0,0,.1);border-radius: 3px;}
.ssh-pre[data-type="css"] .unit {color: #0bc;}
.ssh-pre[data-type="css"] .important {color: #f00;font-weight: bold;}

.ssh-pre[data-type="sql"] .var-type {color: #f63;font-weight: bold;}
:root { --primary-color: green; } pre.ssh-pre { position: relative; padding: 0.5em; margin: 2.5em 0 2em; border: 1px solid rgba(0, 0, 0, 0.06); background-color: rgba(0, 0, 0, 0.025); border-radius: 4px; display: block; white-space: pre-wrap; word-break: break-word; } .ssh-pre[data-label]:before { content: attr(data-label); position: absolute; bottom: 100%; right: 1em; padding: 0.1em 0.5em; background-color: #f8f8f8; border: 1px solid rgba(0, 0, 0, 0.06); border-bottom: none; border-radius: 3px; margin-bottom: -1px; font-size: 11px; } /* Syntax highlighting */ .ssh-pre .txt {color: #333;} .ssh-pre .comment {font-style: italic;color: #aaa;} .ssh-pre .comment * {color: inherit !important;} .ssh-pre .quote {color: #c11;} .ssh-pre .quote * {color: inherit !important;} .ssh-pre .number {color: #c11;} .ssh-pre .boolean {color: #c11;} .ssh-pre .keyword {color: #33c;font-weight: bold;} .ssh-pre .this {color: #c6d;font-weight: bold;} .ssh-pre .punctuation {color: #99f;} .ssh-pre .dollar, .ssh-pre .special {color: #f63;} .ssh-pre .variable {color: #29e;} .ssh-pre .obj-attr {color: #0bc;} .ssh-pre[data-type="shell"] .keyword {color: #ff5252;} .ssh-pre[data-type="shell"] .param {color: #f63;} .ssh-pre[data-type="html"] .doctype {color: #02027e;} .ssh-pre[data-type="html"] .tag-name {color: #11c;} .ssh-pre[data-type="html"] .attribute {color: #f63;} .ssh-pre[data-type="html-vue"] .doctype {color: #02027e;} .ssh-pre[data-type="html-vue"] .tag-name {color: #42b983;} .ssh-pre[data-type="html-vue"] .punctuation {color: #128953;} .ssh-pre[data-type="html-vue"] .attribute {color: #ff5252;} .ssh-pre[data-type="xml"] .doctype {color: #02027e;} .ssh-pre[data-type="xml"] .tag-name {color: #11c;} .ssh-pre[data-type="xml"] .attribute {color: #f93;} .ssh-pre[data-type="css"] .selector {color: #f0d;} .ssh-pre[data-type="css"] .class-id {color: #f0d;} .ssh-pre[data-type="css"] .pseudo {color: #f35;} .ssh-pre[data-type="css"] .keyword {color: #f5f;} .ssh-pre[data-type="css"] .vendor {color: #0c8;} .ssh-pre[data-type="css"] .keyword {color: #c06;} .ssh-pre[data-type="css"] .attribute {color: #70d;} .ssh-pre[data-type="css"] .keyword {color: #e28;} .ssh-pre[data-type="css"] .vendor {color: #0c8;} .ssh-pre[data-type="css"] .value {color: #c11;} .ssh-pre[data-type="css"] .value.vendor {color: #0c8;} .ssh-pre[data-type="css"] .color {background: #eee;padding: 0px 3px;border: 1px solid rgba(0,0,0,.1);border-radius: 3px;} .ssh-pre[data-type="css"] .unit {color: #0bc;} .ssh-pre[data-type="css"] .important {color: #f00;font-weight: bold;} .ssh-pre[data-type="sql"] .var-type {color: #f63;font-weight: bold;}

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta http-equiv="Content-language" content="en">
  <meta name="description" content="Some description.">
  <meta name="keywords" content="Some keywords.">
  <title>Title</title>
  <!-- <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet"> -->
</head>
<body>
  <a name="top"></a>
  <div id="app"></div>
</body>
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="Content-language" content="en"> <meta name="description" content="Some description."> <meta name="keywords" content="Some keywords."> <title>Title</title> <!-- <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet"> --> </head> <body> <a name="top"></a> <div id="app"></div> </body> </html>

Pug

Important: to put parenthesis inside quotes, you have to escape them with: &amp;#40; for ( and &amp;#41; for ).

//- This is pug.
div.mb3.title3.black Github project

w-flex.mb5(align-center shrink)
  w-icon.mr4.lightgrey(size="40") mdi mdi-github
  a(href="https://github.com/antoniandre/simple-syntax-highlighter" target="_blank")
    | //github.com/antoniandre/simple-syntax-highlighter

h2
  a(href="#notes") Notes
  a#notes.anchor
p
  | This is a lightweight yet efficient and reactive Vue JS syntax highlighter.
  | It reads the source code you give it and highlights it, for Humans.
h3 Supported languages
ul
  li XML
  li HTML
  li HTML Vue JS Template
  li Pug
  li Javascript
  li JSON
  li CSS
  li PHP
  li MySQL
  li No support for nested languages

h2
  a(href="#installation") Installation
  a#installation.anchor
p You have two options: NPM or <script> tag.
h3.mt8 Via NPM
ssh-pre(language="shell" label="Shell") npm i simple-syntax-highlighter

h2
  a(href="#how-to-use") How to use
  a#how-to-use.anchor
p Once included in your project, use as follows.
//- This is pug. div.mb3.title3.black Github project w-flex.mb5(align-center shrink) w-icon.mr4.lightgrey(size="40") mdi mdi-github a(href="https://github.com/antoniandre/simple-syntax-highlighter" target="_blank") | //github.com/antoniandre/simple-syntax-highlighter h2 a(href="#notes") Notes a#notes.anchor p | This is a lightweight yet efficient and reactive Vue JS syntax highlighter. |
It reads the source code you give it and highlights it, for Humans. h3 Supported languages ul li XML li HTML li HTML Vue JS Template li Pug li Javascript li JSON li CSS li PHP li MySQL li No support for nested languages h2 a(href="#installation") Installation a#installation.anchor p You have two options: NPM or <script> tag. h3.mt8 Via NPM ssh-pre(language="shell" label="Shell") npm i simple-syntax-highlighter h2 a(href="#how-to-use") How to use a#how-to-use.anchor p Once included in your project, use as follows.

JSON

{
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": ""
  },
  "devDependencies": {
    "vue": "^2.5.16",
    "vue-loader": "^13.7.2",
    "vuetify": "^1.1.1"
  },
  "repository": {
  },
  "dependencies": {},
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "last 5 version",
    "ie 9",
    "iOS >= 9"
  ]
}
{ "name": "", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "" }, "devDependencies": { "vue": "^2.5.16", "vue-loader": "^13.7.2", "vuetify": "^1.1.1" }, "repository": { }, "dependencies": {}, "postcss": { "plugins": { "autoprefixer": {} } }, "browserslist": [ "last 5 version", "ie 9", "iOS >= 9" ] }

PHP

<?php

require_once __DIR__ . '/../autoload.php';
$config = parse_ini_file('config.ini');

if (!empty($_POST["session"]))
{
    unset($_SESSION);
    session_id($_POST["session"]);
}

header('Content-type: application/json');

try
{
    if (empty($_POST["user"]))
    {
        throw new Exception("Bad Request:user", 400);
    }

    if (empty($_POST["session"]))
    {
        throw new Exception("Bad Request:session", 400);
    }

    if (!$isLoggedIn)
    {
        throw new Exception("Cannot login.");
    }

    echo json_encode(true);
}
catch (Exception $e)
{
    if ($e->getCode() === 0)
    {
        header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
    }

    else
    {
        header($_SERVER['SERVER_PROTOCOL'] . ' ' . $e->getCode() . ' ' . $e->getMessage(), true, $e->getCode());
    }

    error_log('There was an error here');

    echo json_encode([
        'exception' => [
            'code' => $e->getCode(),
            'message' => $e->getMessage()
        ]
    ]);
}
finally
{
    // Something.
}

?>
<?php require_once __DIR__ . '/../autoload.php'; $config = parse_ini_file('config.ini'); if (!empty($_POST["session"])) { unset($_SESSION); session_id($_POST["session"]); } header('Content-type: application/json'); try { if (empty($_POST["user"])) { throw new Exception("Bad Request:user", 400); } if (empty($_POST["session"])) { throw new Exception("Bad Request:session", 400); } if (!$isLoggedIn) { throw new Exception("Cannot login."); } echo json_encode(true); } catch (Exception $e) { if ($e->getCode() === 0) { header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); } else { header($_SERVER['SERVER_PROTOCOL'] . ' ' . $e->getCode() . ' ' . $e->getMessage(), true, $e->getCode()); } error_log('There was an error here'); echo json_encode([ 'exception' => [ 'code' => $e->getCode(), 'message' => $e->getMessage() ] ]); } finally { // Something. } ?>

SQL

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

-- Table: `articles`

CREATE TABLE `articles` (
  `id` int(10) UNSIGNED NOT NULL,
  `title` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT 'The article title',
  `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
  `author` mediumint(9) DEFAULT NULL,
  `image` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `category` smallint(6) DEFAULT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `status` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `articles` (`id`, `title`, `content`, `author`, `image`, `category`, `created`, `updated`, `status`) VALUES
(1, 'Not found (404)', 'Lorem Ipsum.', 1, '', 1, '2019-04-24 22:30:35', NULL, 'published');

ALTER TABLE `articles` ADD PRIMARY KEY (`id`);

ALTER TABLE `articles`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

-- Table: `users`

CREATE TABLE `users` (
  `id` int(10) UNSIGNED NOT NULL,
  `type` enum('admin','user') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'user',
  `user_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `first_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `last_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `users` (`id`, `type`, `user_name`, `first_name`, `last_name`, `email`, `password`, `created`, `updated`) VALUES
(1, 'user', 'test', 'first name', 'last name', 'test@test.com', '$2y$10$8TQo5uNyB.bnrVu4TrbxG.2mZxYtghHAswS3Fn/jcxI/WtMQkuewy', '2019-08-11 08:11:28', NULL);

ALTER TABLE `users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `username` (`user_name`),
  ADD UNIQUE KEY `email` (`email`);

ALTER TABLE `users`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- Table: `articles` CREATE TABLE `articles` ( `id` int(10) UNSIGNED NOT NULL, `title` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT 'The article title', `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `author` mediumint(9) DEFAULT NULL, `image` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `category` smallint(6) DEFAULT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `status` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO `articles` (`id`, `title`, `content`, `author`, `image`, `category`, `created`, `updated`, `status`) VALUES (1, 'Not found (404)', 'Lorem Ipsum.', 1, '', 1, '2019-04-24 22:30:35', NULL, 'published'); ALTER TABLE `articles` ADD PRIMARY KEY (`id`); ALTER TABLE `articles` MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; -- Table: `users` CREATE TABLE `users` ( `id` int(10) UNSIGNED NOT NULL, `type` enum('admin','user') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'user', `user_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `first_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `last_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO `users` (`id`, `type`, `user_name`, `first_name`, `last_name`, `email`, `password`, `created`, `updated`) VALUES (1, 'user', 'test', 'first name', 'last name', 'test@test.com', '$2y$10$8TQo5uNyB.bnrVu4TrbxG.2mZxYtghHAswS3Fn/jcxI/WtMQkuewy', '2019-08-11 08:11:28', NULL); ALTER TABLE `users` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `username` (`user_name`), ADD UNIQUE KEY `email` (`email`); ALTER TABLE `users` MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

Dark mode

The dark option switches the color theme to dark.

The dark option switches the color theme to dark. Here is an example of Javascript code in dark mode.

/**
 * This is a
 * multiline comment.
 */
import Vue from 'vue'
import router from './router'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import '@fortawesome/fontawesome-free/css/all.css'
import './styles/index.scss'

Vue.use(Vuetify, {
  iconfont: 'fa',
  theme: {
    primary: '#1b4',
    secondary: '#666',
    maintext: '#999',
    lightgrey: '#eee'
  }
})

new Vue({ // eslint-disable-line no-new
  el: '#app',
  router,
  template: require('./template.pug'),
  data: () => ({
    offsetTop: 0,
    goTopHidden: true
  }),
  methods: {
    onScroll (e) {
      this.offsetTop = window.pageYOffset || document.documentElement.scrollTop

      this.goTopHidden = this.offsetTop < 200
    }
  }
})
/** * This is a * multiline comment. */ import Vue from 'vue' import router from './router' import Vuetify from 'vuetify' import 'vuetify/dist/vuetify.min.css' import '@fortawesome/fontawesome-free/css/all.css' import './styles/index.scss' Vue.use(Vuetify, { iconfont: 'fa', theme: { primary: '#1b4', secondary: '#666', maintext: '#999', lightgrey: '#eee' } }) new Vue({ // eslint-disable-line no-new el: '#app', router, template: require('./template.pug'), data: () => ({ offsetTop: 0, goTopHidden: true }), methods: { onScroll (e) { this.offsetTop = window.pageYOffset || document.documentElement.scrollTop this.goTopHidden = this.offsetTop < 200 } } })

Custom theme

You can easily create your own color theme, as the highlighting is already done, you just need to override the colors of these classes in your css:

.txt {color: #333;}
.comment {color: #aaa;}
.quote {color: #c11;}
.number {color: #c11;}
.boolean {color: #c11;}
.keyword {color: #33c;}
.this {color: #c6d;}
.punctuation {color: #99f;}
.external-var, .special {color: #f63;}
.variable {color: #29e;}
.obj-attr {color: #0bc;}

[data-type="shell"] .keyword {color: #ff5252;}
[data-type="shell"] .param {color: #f63;}

[data-type="html"] .doctype {color: #02027e;}
[data-type="html"] .tag-name {color: #11c;}
[data-type="html"] .attribute {color: #f63;}

[data-type="html-vue"] .doctype {color: #02027e;}
[data-type="html-vue"] .tag-name {color: #42b983;}
[data-type="html-vue"] .punctuation {color: #128953;}
[data-type="html-vue"] .attribute {color: #ff5252;}

[data-type="xml"] .doctype {color: #02027e;}
[data-type="xml"] .tag-name {color: #11c;}
[data-type="xml"] .attribute {color: #f93;}

[data-type="css"] .selector {color: #f0d;}
[data-type="css"] .class-id {color: #f0d;}
[data-type="css"] .pseudo {color: #f35;}
[data-type="css"] .keyword {color: #f5f;}
[data-type="css"] .vendor {color: #0c8;}
[data-type="css"] .keyword {color: #c06;}
[data-type="css"] .attribute {color: #70d;}
[data-type="css"] .keyword {color: #e28;}
[data-type="css"] .vendor {color: #0c8;}
[data-type="css"] .value {color: #c11;}
[data-type="css"] .vendor {color: #0c8;}
[data-type="css"] .color {background: #eee;}
[data-type="css"] .unit {color: #0bc;}
[data-type="css"] .important {color: #f00;}

[data-type="sql"] .var-type {color: #f63;font-weight: bold;}
.txt {color: #333;} .comment {color: #aaa;} .quote {color: #c11;} .number {color: #c11;} .boolean {color: #c11;} .keyword {color: #33c;} .this {color: #c6d;} .punctuation {color: #99f;} .external-var, .special {color: #f63;} .variable {color: #29e;} .obj-attr {color: #0bc;} [data-type="shell"] .keyword {color: #ff5252;} [data-type="shell"] .param {color: #f63;} [data-type="html"] .doctype {color: #02027e;} [data-type="html"] .tag-name {color: #11c;} [data-type="html"] .attribute {color: #f63;} [data-type="html-vue"] .doctype {color: #02027e;} [data-type="html-vue"] .tag-name {color: #42b983;} [data-type="html-vue"] .punctuation {color: #128953;} [data-type="html-vue"] .attribute {color: #ff5252;} [data-type="xml"] .doctype {color: #02027e;} [data-type="xml"] .tag-name {color: #11c;} [data-type="xml"] .attribute {color: #f93;} [data-type="css"] .selector {color: #f0d;} [data-type="css"] .class-id {color: #f0d;} [data-type="css"] .pseudo {color: #f35;} [data-type="css"] .keyword {color: #f5f;} [data-type="css"] .vendor {color: #0c8;} [data-type="css"] .keyword {color: #c06;} [data-type="css"] .attribute {color: #70d;} [data-type="css"] .keyword {color: #e28;} [data-type="css"] .vendor {color: #0c8;} [data-type="css"] .value {color: #c11;} [data-type="css"] .vendor {color: #0c8;} [data-type="css"] .color {background: #eee;} [data-type="css"] .unit {color: #0bc;} [data-type="css"] .important {color: #f00;} [data-type="sql"] .var-type {color: #f63;font-weight: bold;}