Aqua

Version v20.3.0

Introduction

Aqua acts as a preprocessor for Web Components and markdown parsers, mainly built to be compatible with Svelte, but it could also work in browsers natively as a callable API.

This parses markdown/markups and returns a styled HTMLElement block that could be injected to any DOM or directly replace the processed Node if used natively in a browser.

It only utilizes prism, everything else is built from the ground up using native Web APIs and modern CSS layouts, preprocessed to be compatible with both modern and old browsers.

Quick Start

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.min.css" /> <script defer src="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.cbs.js"></script>
Use as highlighter function
import Aqua from '@ignatiusmb/aqua'; const options = { highlight: (str, language) => Aqua.code.highlight(str, { language }); } // Use it like so as 'markdown-it' options const markIt = require('markdown-it')(options);

The output from the parsed block of code should then look like the code block above. There’s also a couple more examples below in the Modules / API section. This documentation is also built with Aqua.

You should be able to use highlight API from code with any markdown parser that allows you to handle the syntax highlighting yourself. This is basically the custom highlight function replacement, and it respects the DOM hierarchy by starting with the <pre> tag so there won’t be any unnecessary nesting happening.

Getting Started

Use in Node.js

npm install @ignatiusmb/aqua

Use in Browser

Direct Include --> jsDelivr CDN
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.min.css" /> <script defer src="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.min.js"></script>
Direct Include --> UNPKG CDN
<link rel="stylesheet" href="https://unpkg.com/@ignatiusmb/aqua@20.3.0/lib/aqua.min.css" /> <script defer src="https://unpkg.com/@ignatiusmb/aqua@20.3.0/lib/aqua.min.js"></script>

Included Font Vars

:root { --aqua-default: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Rubik', 'Ubuntu', 'Roboto', sans-serif; --aqua-heading: 'Karla', sans-serif; --aqua-monospace: 'Fira Code', 'Inconsolata', 'Consolas', monospace; } /* Example */ body { font-family: var(--aqua-default); } header { font-family: var(--aqua-heading); } footer { font-family: var(--aqua-monospace); }
Use your own binaries or through CDN
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Rubik&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Karla&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Fira+Code&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inconsolata&display=swap">

Important Note

Aqua provides stylesheets and script files, linking or including the stylesheet is mandatory to display the elements properly. A custom reset is included as well so it makes quick prototyping a breeze, everything should display properly, and it works without any additional configuration.

1.0 - without bundler
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.min.css" />
2.0 - with a bundler
import '@ignatiusmb/aqua/lib/aqua.min.css';

On the other hand, there’s a couple of ways to use the script files. You can use and import the entire module through the CDN if you’re using it in the client-side. But, if you use the parser from the server-side, you can just bundle the callback script file with your website or include it in the head.

1.0 - Parsing in client-side
<script defer src="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.min.js"></script>
2.0 - Parsing from server-side | With bundler
import '@ignatiusmb/aqua/lib/aqua.cbs';
2.1 - Parsing from server-side | No bundler
<script defer src="https://cdn.jsdelivr.net/npm/@ignatiusmb/aqua@20.3.0/lib/aqua.cbs.js"></script>

Modules / API

Aqua doesn’t have any named export by default, but it provides many props that has it, all available and listed below. First, import the entire module through its default export with the name Aqua.

import Aqua from '@ignatiusmb/aqua';

Code.js

const { cbs, highlight, highlightAll, init } = Aqua.code;

Aqua.code provides 4 public methods

  1. init - method used for client-side parsing
  2. cbs - all the needed callbacks for toolbar onclick events
  3. highlight - the highlighter function to parse code blocks
  4. highlightAll - wrapper to call Prism highlightAll function
Client-side usage
<body> <pre class="aqua code-block" data-language="" data-title=""> <!-- text to be preformatted --> </pre> <div id="root" class="container"> <pre class="aqua code-block" data-language="" data-title=""> <!-- text to be preformatted --> </pre> </div> </body> <script> // Defaults to document.body if no argument is passed // This will parse and highlight all <pre> tags // with class of 'aqua code-block' inside <body> Aqua.code.init(); // Select tag with class of 'container' and id 'root' // as the starting element and will only parse // all <pre> tags inside tags with this class and id Aqua.code.init(document.querySelector('.container#root')); </script>
Server-side usage | Simple
const markIt = require('markdown-it')({ highlight: (str, language) => Aqua.code.highlight(str, { language }) });
Server-side usage | With title parsing
const options = { highlight: (str, language) => { const strList = str.split('\n'); const dataset = { language }; // If the first line has a prefix of '~' // It will use the first line as the title if (strList[0][0] === '~') { dataset['title'] = strList[0].slice(1); } // Check if title exist and remove it from string to be parsed const content = strList.slice(dataset['title'] ? 1 : 0).join('\n'); return Aqua.code.highlight(content, dataset); }, }
Server-side usage | With title and lineStart parsing
import Aqua from '@ignatiusmb/aqua'; const options = { highlight: (str, language) => { const strList = str.split('\n'); const dataset = { language }; if (strList[0][0] === '~') { const [title, lineNumber] = strList[0].split('#'); dataset['title'] = title.slice(1); // Check if there's a hash '#' in the title and use it as start line number if (lineNumber) dataset['lineStart'] = parseInt(lineNumber); } const content = strList.slice(dataset['title'] ? 1 : 0).join('\n'); return Aqua.code.highlight(content, dataset); }, }