Skip to content

Instantly share code, notes, and snippets.

@audunolsen
Last active November 29, 2018 14:50
Show Gist options
  • Save audunolsen/8ac589675d60289ba5435e14a2830e4d to your computer and use it in GitHub Desktop.
Save audunolsen/8ac589675d60289ba5435e14a2830e4d to your computer and use it in GitHub Desktop.
Single Line — Tagged Template Literals
oneline = (strings, ...values) => {
let interpolated = "", raw = strings.raw, ref;
for (let [i, string] of raw.entries())
interpolated += ((ref = values[i-1]) ? ref : "") + string;
return interpolated
.split("\n")
.map((line, i, lines) =>
/\\$/.test((ref = line.trim())) ? ref.slice(0, -1) :
i == lines.length-1 ? ref : ref + " "
).join("");
}
const style =
oneline`style="\
grid-area:
${y} / ${x}
span 1 / span 1;
-ms-grid-row: ${y};
-ms-grid-row-span: 1;
-ms-grid-column: ${x};
-ms-grid-column-span: 1;"`
console.log(style)
// style="grid-area: 9 / 5 span 1 / span 1; -ms-grid-row: 9; -ms-grid-row-span: 1; -ms-grid-column: 5; -ms-grid-column-span: 1;"

Why

This function for tagging template literals adresses something which I sorely miss from CoffeeScript. It lets you format a template literal over multiple lines, but still returns a single line string. Lines are joined by a single space unless they end with a backslash, indentation is ignored—Just like CoffeeScript.

Not so great alternatives

Here's an example on using template literals' default behaviour to retrieve a single line string. By ending lines with a backslash the following is returned:

const pure = 
    `style="\
        grid-area:\
            ${y} / ${x}\
            span 1 / span 1;\
        -ms-grid-row: ${y};\
        -ms-grid-row-span: 1;\
        -ms-grid-column: ${x};\
        -ms-grid-column-span: 1;"`


console.log(pure);

// style="    	grid-area:        	9 / 5         	span 1 / span 1;       -ms-grid-row: 9;       -ms-grid-row-span: 1;       -ms-grid-column: 5;       -ms-grid-column-span: 1;"

Because of the whitespace sensitivity, neatly formatted strings for ergonomic reading, but which ultimately need to be a single line will need a different approach. Another contention of mine is that if you're already inside deeply nested code, this string will begin to look really ridiculous. Another alternative:

const alternative = 
    'style="'                     +
        'grid-area: '             +
            `${y} / ${x} `        +
            'span 1 / span 1; '   +
        `-ms-grid-row: ${y}; `    +
        '-ms-grid-row-span: 1; '  +
        `-ms-grid-column: ${x}; ` +
        '-ms-grid-column-span: 1;'

console.log(alternative);

// style="grid-area: 9 / 5 span 1 / span 1; -ms-grid-row: 9; -ms-grid-row-span: 1; -ms-grid-column: 5; -ms-grid-column-span: 1;

Honsetly, I find regular strings and template literals to have a respectable synergy, but i prefer not to spam back-ticks, quotation marks and plus signs.

Usage example

Through the use of ES6 raw string access, I've flipped the behaviour of "\" to no longer escape the newline, but escape joining lines by spaces. Default behaviour is to join lines by a space. A great usage example for this and the oneline tag overall is handling URIs—which are often far too long to resemble anything readable.

const filter = "hardcover";

const URL = oneline`
    https://www.adlibris.com\
    /se/bok/factfulness-tio-knep-som-hjalper-dig-forsta-varlden-9789127149946\
    ?filter=${filter}\
    &gclid=760a19f0-5057-417a-8e6a-b44a01b12a46\
    &some=thing`;

/*
Link example is taken from: https://www.youtube.com/watch?v=zDovsTG2a7g&t=2s
The above video was kind of an inspiration for this snippet.
*/

console.log(URL);

// https://www.adlibris.com/se/bok/factfulness-tio-knep-som-hjalper-dig-forsta-varlden-9789127149946?filter=hardcover&gclid=760a19f0-5057-417a-8e6a-b44a01b12a46&some=thing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment