Skip to content

Instantly share code, notes, and snippets.

@westc
Last active November 1, 2024 14:59
Show Gist options
  • Select an option

  • Save westc/8acb0f026014a6630b0b8ecbfeaf51f1 to your computer and use it in GitHub Desktop.

Select an option

Save westc/8acb0f026014a6630b0b8ecbfeaf51f1 to your computer and use it in GitHub Desktop.
unindentMin() - Finds the minimum indentation of all of the lines that have non-space characters and removes the indentation accordingly for all indented lines.
def unindent(input_str):
indent = None
# Find all non-blank lines and their indentation
for non_blank_line in re.finditer(r'^\n?(\s*)(?=\S)', input_str, re.MULTILINE):
this_indent = non_blank_line.group(1)
# Determine the smallest indent
if indent is None or (indent != this_indent and indent.startswith(this_indent)):
indent = this_indent
if indent == '':
break
# If indent is found, remove it from all lines
if indent is not None:
return re.sub(rf'^\n?{indent}', '', input_str, flags=re.MULTILINE)
return input_str
/**
* Finds the minimum indentation of all of the lines that have non-space
* characters and removes the indentation accordingly for all indented lines.
* @param {string} text
* The string containing the lines of text that should be unindented.
* @param {{trim: boolean, tabSize: number}=} opt_options
* Optional, defaults to `{trim: true, tabSize: 4}`. The `trim` property
* indicates if leading lines should be removed along with trailing
* whitespaces. The `tabSize` property indicates how many spaces will be
* used to replace all tab characters.
* @returns {string}
* A new version of `text` with all of the minimally indented lines having
* no leading spacing and all other indented lines following suit. If
* `opt_options.trim` is `true` all leading lines and trailing spaces will
* not exist. All tab characters will be replaced with
* `opt_options.tabSize` amount of space characters.
*/
function unindentMin(text, opt_options) {
opt_options = Object(opt_options);
const tabSize = opt_options.tabSize ?? 4;
const trim = opt_options.trim ?? true;
text = text.replace(/\t/g, ' '.repeat(tabSize));
if (!/(^|[\r\n])\S/.test(text)) {
const rgx = /(^|[\r\n])((?:(?!\r|\n)\s)+)(?=(\S)?)/g;
let min = Infinity;
for (let match; match = rgx.exec(text);) {
if (match[3]) {
min = Math.min(min, match[2].length);
}
}
text = text.replace(
rgx,
(_, start, spaces) => start + spaces.slice(min)
);
}
return trim ? text.replace(/^(\s*[\r\n]+)+|\s+$/g, '') : text;
}
{
// Name of the function responsable for transforming the input into the output.
"transform": "unindentMin",
// Where to find the code that will be eval'd.
"files": ["unindentMin.js"],
// Type of YourJS IO-App
"type": "instant"
}
@westc
Copy link
Author

westc commented Feb 7, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment