Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Predictive transformation #15

Closed
bnadim opened this issue Oct 5, 2017 · 0 comments
Closed

Predictive transformation #15

bnadim opened this issue Oct 5, 2017 · 0 comments

Comments

@bnadim
Copy link

bnadim commented Oct 5, 2017

i tried to used dedent and came accros two issues :
First i had some bug with \` being transformed the wrong way (i can't remember exactly)
Second is if you try for example to add a first blank line or you want to tab all you text you can't.

Here is the short module i ended up writing to overcome both. If you want i could make it a pr.
Code here : https://github.com/ekino/veggies/blob/master/src/extensions/snapshot/dedent.js
tests here : https://github.com/ekino/veggies/blob/master/tests/extensions/snapshot/dedent.test.js

For commodity here is the code


/**
 * Extract spaces length
 * @param {string} text
 * @returns {number} length tab and space before first char
 */
const getSpacesLength = text => {
    let length = 0

    while (length < text.length) {
        const char = text[length]
        if (char !== ' ' && char !== '\t') break
        length += 1
    }

    return length
}

/**
 * Used to remove indentation from a text. Usefull with multine string in backticks.
 *
 * Two way to use it : `
 *     My text
 *       Another line
 *     Another line again
 * `
 * the result text will be :
 * "My text
 *   Another line
 * Another line again"
 *
 * In this case, alignment is done on the length of the first character that is not a space or a tab of all lines
 *
 * Or
 *
 * Another way : `
 *     """
 *       My text
 *         Another line
 *      Another line again
 *     """
 * `
 * the result text will be :
 * "  My text
 *      Another line
 *  Another line again"
 *
 *  In this case, alignment is donne on the spaces or tab before """
 *
 * Warning : First line and last line will always be ignored
 *
 * @param {string} text
 * @return {string}
 */
module.exports = text => {
    if (typeof text !== 'string') text = text[0]

    let lines = text.split('\n')
    if (lines.length < 3) return text

    lines = lines.slice(1, lines.length - 1)

    let skipLength = getSpacesLength(lines[0])

    if (
        lines[0].substr(skipLength, 3) === '"""' &&
        lines[lines.length - 1].substr(skipLength, 3) === '"""'
    ) {
        lines = lines.slice(1, lines.length - 1)
    } else {
        for (let i = 0; i < lines.length; i++) {
            const line = lines[i]
            skipLength = Math.min(skipLength, getSpacesLength(line))
        }
    }

    const resultLines = []
    for (let i = 0; i < lines.length; i++) {
        resultLines.push(lines[i].substring(skipLength))
    }

    return resultLines.join('\n')
}
@bnadim bnadim closed this as completed Feb 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant