Skip to content

Commit

Permalink
add s_lines func; improve RPath func docs
Browse files Browse the repository at this point in the history
* new s_lines function splits a string into lines.
  • Loading branch information
molsonkiko committed Dec 14, 2023
1 parent 5d6e52f commit 825eb95
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `loop()` function used in `s_sub` callbacks is not thread-safe. *This doesn't matter right now* because RemesPath is single-threaded, but it could matter in the future.
- __GrepperForm loses its JSON permanently when the buffer associated with its treeview is deleted.__

## [6.1.0] - (UNRELEASED) YYYY-MM-DD

### Added

1. [`s_lines` RemesPath vectorized function](/docs/RemesPath.md#vectorized-functions).

## [6.0.0] - 2023-12-13

### Added
Expand Down
44 changes: 41 additions & 3 deletions JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2963,6 +2963,12 @@ public static JNode StrFindAll(List<JNode> args)
return StrFindAllHelper(text, rex, args, 3, "s_fa", -1, headerHandling);
}

/// <summary>
/// s_split(x: string, sep: string | regex = g`\s+`) -> array[string]<br></br>
/// split x by each match to sep (which is always treated as a regex)<br></br>
/// if sep is not provided, split on whitespace.<br></br>
/// See https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.split?view=netframework-4.8#system-text-regularexpressions-regex-split(system-string) for implementation details.
/// </summary>
public static JNode StrSplit(List<JNode> args)
{
JNode node = args[0];
Expand All @@ -2981,21 +2987,52 @@ public static JNode StrSplit(List<JNode> args)
return new JArray(0, out_nodes);
}

/// <summary>
/// s_lines(x: string) -> array[string]<br></br>
/// splits x into an array of lines, treating '\r', '\n', and '\r\n' all as line terminators.<br></br>
/// Use s_split(x, `\r\n`) or s_split(x, `\r`) or s_split(x, `\n`) instead if you only want to consider one type of line terminator.
/// </summary>
public static JNode StrSplitLines(List<JNode> args)
{
string s = (string)args[0].value;
string[] lines = Regex.Split(s, @"\r\n?|\n");
var lineArr = new List<JNode>(lines.Length);
foreach (string line in lines)
lineArr.Add(new JNode(line));
return new JArray(0, lineArr);
}

/// <summary>
/// s_lower(x: string) -> string<br></br>
/// returns x converted to lowercase
/// </summary>
public static JNode StrLower(List<JNode> args)
{
return new JNode(((string)args[0].value).ToLower());
}

/// <summary>
/// s_lower(x: string) -> string<br></br>
/// returns x converted to uppercase
/// </summary>
public static JNode StrUpper(List<JNode> args)
{
return new JNode(((string)args[0].value).ToUpper());
}

/// <summary>
/// s_lower(x: string) -> string<br></br>
/// returns x with no leading or trailing whitespace
/// </summary>
public static JNode StrStrip(List<JNode> args)
{
return new JNode(((string)args[0].value).Trim());
}


/// <summary>
/// See string.Slice extension method in ArrayExtensions.cs
/// </summary>
public static JNode StrSlice(List<JNode> args)
{
string s = (string)args[0].value;
Expand Down Expand Up @@ -3071,23 +3108,23 @@ string replacementFunction(Match m)
}

/// <summary>
/// returns true is x is string
/// returns true iff is x is a string
/// </summary>
public static JNode IsStr(List<JNode> args)
{
return new JNode(args[0].type == Dtype.STR);
}

/// <summary>
/// returns true is x is long, double, or bool
/// returns true iff x is long, double, or bool
/// </summary>
public static JNode IsNum(List<JNode> args)
{
return new JNode((args[0].type & Dtype.NUM) != 0);
}

/// <summary>
/// returns true if x is JObject or JArray
/// returns true iff x is JObject or JArray
/// </summary>
public static JNode IsExpr(List<JNode> args)
{
Expand Down Expand Up @@ -3422,6 +3459,7 @@ public static JNode ObjectsToJNode(object obj)
["s_fa"] = new ArgFunction(StrFindAll, "s_fa", Dtype.ARR, 2, int.MaxValue, true, new Dtype[] { Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX, Dtype.BOOL | Dtype.NULL, Dtype.INT}, true, new ArgsTransform((1, Dtype.STR_OR_REGEX, TransformRegex), (2, Dtype.NULL, x => new JNode(false)))),
["s_find"] = new ArgFunction(StrFind, "s_find", Dtype.ARR, 2, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.REGEX}),
["s_len"] = new ArgFunction(StrLen, "s_len", Dtype.INT, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}),
["s_lines"] = new ArgFunction(StrSplitLines, "s_lines", Dtype.ARR, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}),
["s_lower"] = new ArgFunction(StrLower, "s_lower", Dtype.STR, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}),
["s_mul"] = new ArgFunction(StrMul, "s_mul", Dtype.STR, 2, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.INT }),
["s_slice"] = new ArgFunction(StrSlice, "s_slice", Dtype.STR, 2, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.INT_OR_SLICE}),
Expand Down
4 changes: 2 additions & 2 deletions JsonToolsNppPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.0.0")]
[assembly: AssemblyVersion("6.0.0.1")]
[assembly: AssemblyFileVersion("6.0.0.1")]
1 change: 1 addition & 0 deletions JsonToolsNppPlugin/Tests/RemesPathTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ public static bool Test()
new Query_DesiredResult("log2(j`[1, 4, 8]`)", $"[0, 2, 3]"),
new Query_DesiredResult("abs(j`[-1, 0, 1]`)", "[1, 0, 1]"),
new Query_DesiredResult("is_str(@.bar.b)", "[true, true]"),
new Query_DesiredResult("s_lines(j`[\"a\\r\\nb\\rc\\td\\ne\\n\", \"foo bar\"]`)", "[[\"a\", \"b\", \"c\\td\", \"e\", \"\"], [\"foo bar\"]]"),
new Query_DesiredResult("s_split(@.bar.b[0], g`[^a-z]+`)", "[\"a\", \"g\"]"),
new Query_DesiredResult("s_split(@.bar.b, `a`)", "[[\"\", \"`g\"], [\"b\", \"h\"]]"),
new Query_DesiredResult("s_split(`foo\\r\\nb\\t c \\r bar-baz\\n`, )", "[\"foo\", \"b\", \"c\", \"bar-baz\", \"\"]"), // omit optional 2nd arg; split on whitespace
Expand Down
8 changes: 8 additions & 0 deletions JsonToolsNppPlugin/Utils/ArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ public static string Slice(this string source, int start, int stop, int stride)
return new string(source.ToCharArray().LazySlice(start, stop, stride).ToArray());
}

/// <summary>
/// s_slice(x: string, sli: integer | slicer) -> string<br></br>
/// uses Python slicing syntax.<br></br>
/// EXAMPLES:<br></br>
/// * s_slice(abcde, 1:-2) returns "bc"<br></br>
/// * s_slice(abcde, :2) returns "ab"<br></br>
/// * s_slice(abcde, -2) returns "d"<br></br>
/// </summary>
public static string Slice(this string source, int?[] slicer)
{
return new string(source.ToCharArray().LazySlice(slicer).ToArray());
Expand Down
17 changes: 12 additions & 5 deletions docs/RemesPath.md
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,15 @@ The length of string x.

The lower-case form of x.

---
`s_lines(x: string) -> array[string]`

*Added in [v6.1](/CHANGELOG.md#610---unreleased-yyyy-mm-dd)*

Returns an array of all the lines (including an empty string at the end if there's a trailing newline) in `x`.

This function treats `\r`, `\n`, and `\r\n` all as valid newlines. Use `s_split` below if you want to only accept one or two of those.

----
`s_mul(x: string, reps: int) -> string`

Expand All @@ -917,17 +926,15 @@ Prior to [v5.5.0](/CHANGELOG.md#550---2023-08-13), Python-style negative indices
If `sep` is not specified (the function is called with one argument):
* Returns `x` split by whitespace.
* E.g., ``s_split(`a b c\n d `)`` returns `["a", "b", "c", "d", ""]` (the last empty string is because `x` ends with whitespace)
* The 1-argument option was added in [v6.0](/CHANGELOG.md#600---2023-12-13).

If `sep` is a string:
* Returns an array containing all the substrings of `x` that don't contain `sep`, split by the places where `sep` occurs.
* E.g., ``s_split(`abac`, `a`)`` returns `["", "b", "c"]`

If `sep` is a regex:
If `sep` is a string (which is treated as a regex) or regex:
* Returns an array containing substrings of `x` where the parts that match `sep` are missing.
* E.g., ``s_split(`a big bad man`, g`\\s+`)`` returns `["a", "big", "bad", "man"]`.
* However, if `sep` contains any capture groups, the capture groups are included in the array.
* ``s_split(`a big bad man`, g`(\\s+)`)`` returns `["a", " " "big", " ", "bad", " ", "man"]`.
* ``s_split(`bob num: 111-222-3333, carol num: 123-456-7890`, g`(\\d{3})-(\\d{3}-\\d{4})`)`` returns `["bob num: ", "111", "222-3333", ", carol num: ", "123", "456-7890", ""]`
* See [the docs for C# Regex.Split](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.split?view=netframework-4.8#system-text-regularexpressions-regex-split(system-string)) for more info.

----
`s_strip(x: string) -> string`
Expand Down

0 comments on commit 825eb95

Please sign in to comment.