-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #208 from appthrust/feat-add-outdent-module
feat: add `outdent` module
- Loading branch information
Showing
5 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# KCL outdent Module | ||
|
||
The `outdent` module provides a function to remove common leading whitespace from multi-line strings in KCL. This functionality is similar to: | ||
|
||
- Python's `textwrap.dedent()` | ||
- Kotlin's `trimMargin()` | ||
- Scala's `stripMargin` | ||
- The `outdent` NPM package for JavaScript | ||
- Rust's `indoc` crate | ||
|
||
## Features | ||
|
||
- Removes common leading whitespace from multi-line strings | ||
- Preserves relative indentation within the text | ||
- Handles both spaces and tabs | ||
- Trims leading and trailing blank lines | ||
|
||
## Usage | ||
|
||
Here's a basic example of how to use the `outdent` function: | ||
|
||
main.k: | ||
|
||
```kcl | ||
import outdent | ||
input = """ | ||
This is an example | ||
of a multi-line string | ||
with varying indentation | ||
""" | ||
output = outdent.outdent(input) | ||
``` | ||
|
||
Run the script with: | ||
|
||
```shell | ||
kcl run main.k --format yaml | ||
``` | ||
|
||
Output: | ||
|
||
```yaml | ||
input: "\n This is an example\n of a multi-line string\n with varying indentation\n " | ||
output: |- | ||
This is an example | ||
of a multi-line string | ||
with varying indentation | ||
``` | ||
## Function Signature | ||
```rust | ||
outdent(text: str) -> str | ||
``` | ||
- `text`: The input string to be outdented | ||
- Returns: A new string with common leading whitespace removed | ||
|
||
## Testing | ||
|
||
The module includes a comprehensive test suite in `main_test.k`. To run the tests, use the KCL test runner: | ||
|
||
```shell | ||
kcl test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[package] | ||
name = "outdent" | ||
version = "0.1.0" | ||
description = "`outdent` is ...(write here)" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import regex | ||
|
||
outdent = lambda text: str { | ||
# Split the text into lines, preserving line endings | ||
lines = regex.split(text, "\r\n|\n") | ||
# Function to get leading whitespace | ||
get_leading_whitespace = lambda line: str { | ||
whitespace = regex.findall(line, "^\s+") | ||
whitespace[0] if whitespace else "" | ||
} | ||
# Find non-empty lines and their indentations | ||
non_empty_lines = [line for line in lines if line.strip()] | ||
indents = [get_leading_whitespace(line) for line in non_empty_lines] | ||
indentations = [len(get_leading_whitespace(line)) for line in non_empty_lines] | ||
# Find the minimum indentation | ||
min_indent = min([""] | indentations) | ||
# Remove the common indent and join the lines | ||
outdented_lines = [line[min_indent::] if line.strip() else line for line in lines] | ||
result = "\n".join(outdented_lines) | ||
# Trim leading and trailing blank lines | ||
regex.replace(result, r'^\s*\n|\n\s*$', '') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
test_outdent_basic = lambda { | ||
input = """ | ||
line1 | ||
line2 | ||
line3 | ||
line4 | ||
""" | ||
expected = """ | ||
line1 | ||
line2 | ||
line3 | ||
line4 | ||
""" | ||
assert outdent(input) == expected.strip(), "Basic indentation test failed" | ||
} | ||
test_outdent_empty_lines = lambda { | ||
input = """ | ||
|
||
line1 | ||
line2 | ||
line3 | ||
|
||
""" | ||
expected = """ | ||
line1 | ||
line2 | ||
line3 | ||
""" | ||
assert outdent(input) == expected.strip(), "Empty lines test failed" | ||
} | ||
test_outdent_no_common_indent = lambda { | ||
input = """ | ||
line1 | ||
line2 | ||
line3 | ||
""" | ||
expected = """ line1 | ||
line2 | ||
line3""" | ||
assert outdent(input) == expected, "No common indent test failed" | ||
} | ||
test_outdent_empty_string = lambda { | ||
assert outdent("") == "", "Empty string test failed" | ||
} | ||
test_outdent_single_line = lambda { | ||
assert outdent(" single line") == "single line", "Single line test failed" | ||
} | ||
test_outdent_tabs = lambda { | ||
input = """ | ||
\tline1 | ||
\t\tline2 | ||
\t\t\tline3 | ||
""" | ||
expected = """ | ||
line1 | ||
\tline2 | ||
\t\tline3 | ||
""" | ||
assert outdent(input) == expected.strip(), "Tabs test failed" | ||
} | ||
test_outdent_only_whitespace = lambda { | ||
input = """ | ||
|
||
|
||
|
||
""" | ||
assert outdent(input) == "", "Only whitespace test failed" | ||
} |