Skip to content

Commit

Permalink
Introduce tabSize config parameter (#56)
Browse files Browse the repository at this point in the history
* Add tabsize config

* Fix codeblock lexing indentifying tabs or space indentations

Signed-off-by: Parajuli Kiran <[email protected]>

---------

Signed-off-by: Parajuli Kiran <[email protected]>
  • Loading branch information
kiranparajuli589 committed Nov 13, 2023
1 parent 2915ece commit e75e23a
Show file tree
Hide file tree
Showing 19 changed files with 379 additions and 224 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ htmlmark.parse("## Hello World"); // returns the HTML code
| Option | Type | Default | Description |
|-------------|------------|-------------|---------------------------------------------------|
| indent | `number` | `4` | Number of spaces (or tabs) to use for indentation |
| tabSize | `number` | `4` | Equivalent spaces for a single tab used |
| highlightFn | `function` | `undefined` | Function to highlight the code |
| useLinkRefs | `boolean` | `true` | Whether to use link references or not |

Expand Down
11 changes: 7 additions & 4 deletions lib/lexer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ class Lexer {
#indentObj

constructor(lines, { from = null, config= {} } = {}) {
this.#cursor = 0
this.#lines = lines
this.#lexerData = []
this.#fromToken = from
this.#cursor = 0

this.#config = Utils.prepareConfig(config)

this.#indentObj = new Indent(this.#config.indent)
this.#indentObj = new Indent(
this.#config.indent,
this.#config.tabSize
)
}

#runCurrLineLexer() {
Expand Down Expand Up @@ -276,8 +279,8 @@ class Lexer {
this.#nextLine = this.#lines[this.#cursor + 1]
this.#lexerLengthBefore = this.#lexerData.length
this.#lastLexerItem = this.#lexerData[this.#lexerLengthBefore - 1] || null
this.#currLineRawIndent = Indent.raw(this.#currLine)
this.#currLineIndent = this.#indentObj.calc(this.#currLineRawIndent)
this.#currLineRawIndent = this.#indentObj.raw(this.#currLine)
this.#currLineIndent = this.#indentObj.calc(this.#currLine)
}

#skipFrontMatter() {
Expand Down
23 changes: 18 additions & 5 deletions lib/tokenizer/codeblock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import REGEX from "../regex/index.js"
import { Indent, TOKENS, Utils, Esc } from "../util/index.js"
import { TOKENS, Utils, Esc } from "../util/index.js"


class CodeBlock {
Expand Down Expand Up @@ -145,7 +145,22 @@ class CodeBlock {
const start = (this.#withBraces) ? this.#start + 1 : this.#start

this.#body = this.#lines.slice(start, this.#cursor)
.map(line => line.slice(Math.min(this.#rawIndent, Indent.raw(line))))
.map(line => {
const lineIndent = this.#indentObj.raw(line)
let indentToSlice = Math.min(this.#rawIndent, lineIndent)

while(indentToSlice > 0) {
if (line.startsWith("\t")) {
line = line.replace("\t", "")
indentToSlice -= this.#indentObj.tabSize
} else {
line = line.slice(1)
indentToSlice--
}
}

return line
})
.join("\n")
}

Expand Down Expand Up @@ -205,9 +220,7 @@ class CodeBlock {
* @returns {string} - the CodeBlock HTML
*/
static parse(lexer, highlightFn = null) {
let skeleton = `<pre><code%class>
%s
</code></pre>
let skeleton = `<pre><code%class>%s</code></pre>
`
if (lexer.language) {
skeleton = skeleton.replace("%class", ` class='language-${lexer.language}'`)
Expand Down
2 changes: 1 addition & 1 deletion lib/tokenizer/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class List {
this.#indent = indent
this.#isEmpty = List.testEmpty(lines[cursor])
this.#config = Utils.prepareConfig(config)
this.#indentObj = new Indent(this.#config.indent)
this.#indentObj = new Indent(this.#config.indent, this.#config.tabSize)
this.#processMeta()
}

Expand Down
40 changes: 15 additions & 25 deletions lib/util/indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ Number.prototype.inRange = function (a, b) {
* Markdown Indentation
*/
class Indent {
#indentSize
indentSize
tabSize

constructor(indentSize) {
this.#indentSize = indentSize
constructor(indentSize, tabSize) {
this.indentSize = indentSize
this.tabSize = tabSize
}

/**
Expand All @@ -26,24 +28,27 @@ class Indent {
*
* @returns {number}
*/
static raw(text) {
raw(text) {
if (["", "\n", undefined].includes(text)) return 0
let count = 0
while (text[count] === " " || text[count] === "\t") {
count++
let index = 0
while (text[index] === " " || text[index] === "\t") {
count += (text[index] === " ") ? 1 : this.tabSize
index++
}
return count
}

/**
* calculates the indentation of the given value
*
* @param {number} rawIndent
* @param {string} text
*
* @returns {number}
*/
calc(rawIndent) {
return Math.floor(rawIndent / this.#indentSize) * this.#indentSize
calc(text) {
const rawIndent = this.raw(text)
return Math.floor(rawIndent / this.indentSize) * this.indentSize
}

/**
Expand All @@ -54,22 +59,7 @@ class Indent {
* @returns {number}
*/
get(text) {
return this.calc(Indent.raw(text))
}

/**
* returns if in the range of the given indentation
*
* @param {number} test the indentation to test
* @param {number} indent the indentation to test against
*
* @returns {boolean}
*/
inRange(test, indent) {
return test.inRange(
(indent-this.#indentSize < 0) ? 0 : indent-this.#indentSize,
indent+this.#indentSize
)
return this.calc(text)
}
}

Expand Down
5 changes: 3 additions & 2 deletions lib/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,13 @@ class Utils {

/**
* Prepare HtmlMark Config Object
* @param {{indent: (number| null), highlightFn: (function|null), useLinkRefs: (boolean|null)}} config
* @returns {{indent: number, highlightFn: (function|null), useLinkRefs: (boolean)}}
* @param {{indent: (number| null), tabSize: (number|null), highlightFn: (function|null), useLinkRefs: (boolean|null)}} config
* @returns {{indent: number,tabSize: number, highlightFn: (function|null), useLinkRefs: (boolean)}}
*/
static prepareConfig(config) {
return {
indent: config?.indent || 4,
tabSize: config?.tabSize || 4,
highlightFn: config?.highlightFn || null,
useLinkRefs: config?.useLinkRefs || true
}
Expand Down
4 changes: 1 addition & 3 deletions tests/integration/__snapshots__/codeHighlight.spec.js.snap
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`code highlight support should highlight code blocks 1`] = `
"<pre><code class='language-javascript'>
<span class=\\"hljs-keyword\\">const</span> a = <span class=\\"hljs-number\\">1</span>
</code></pre>
"<pre><code class='language-javascript'><span class=\\"hljs-keyword\\">const</span> a = <span class=\\"hljs-number\\">1</span></code></pre>
"
`;
Loading

0 comments on commit e75e23a

Please sign in to comment.