Skip to content

Commit 8fa9078

Browse files
committed
Add functions: Word wrap, cleanup
1 parent ac4ec11 commit 8fa9078

6 files changed

Lines changed: 179 additions & 423 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Regex_Replace
2+
let
3+
/*
4+
future: this could be extended, by waiting for a css selector
5+
6+
Web.BrowserContents("https://microsoft.com", [WaitFor = [Selector = "div.ready"]])
7+
*/
8+
9+
Source =
10+
(string as nullable text, pattern as text, optional replacement as text, optional modifiers as text) =>
11+
let
12+
Source =
13+
"<html><body><script>
14+
var x = '"
15+
& Text.Replace(
16+
Text.Replace(
17+
Text.Replace(string, "'", "\'"),
18+
"#(lf)",
19+
"\n"
20+
),
21+
"#(cr)",
22+
"\r"
23+
)
24+
& "';
25+
var z = '"
26+
& (
27+
if modifiers <> null then
28+
modifiers
29+
else
30+
""
31+
)
32+
& "';
33+
var y = new RegExp('"
34+
& Text.Replace(pattern, "\", "\\")
35+
& "',z);
36+
var a = '"
37+
& (
38+
if replacement <> null then
39+
replacement
40+
else
41+
""
42+
)
43+
& "'
44+
var result = x.replace(y,a);
45+
document.write('<pre>' + result + '</pre>')
46+
</script></body><html>",
47+
WebPage = Web.Page(Source),
48+
Data = WebPage{0}[Data],
49+
Children = Data{0}[Children],
50+
Children1 = Children{[Name = "BODY"]}[Children],
51+
Children2 = Children1{[Name = "PRE"]}[Children],
52+
Text = Children2{0}[Text]
53+
in
54+
Text,
55+
documentation = [
56+
Documentation.Name = "RegexReplace",
57+
Documentation.Category = "",
58+
Documentation.Author = "reddit.com/u/tirlibibi17",
59+
Documentation.Description = "A generic regular expression replacement function based on the Javascript replace() method. Adapted from https://www.thebiccountant.com/2018/04/25/regex-in-power-bi-and-power-query-in-excel-with-java-script/. #(lf)See https://www.w3schools.com/jsref/jsref_obj_regexp.asp for Javascript regular expression reference and https://www.regular-expressions.info/ for general regular expression information.",
60+
Documentation.Examples = {
61+
[
62+
Description = "Pattern without capturing groups",
63+
Code = "RegexReplace(""The quick brown fox jumps over the lazy dog"", ""the quick brown fox"",""Da fox"",""i"")",
64+
Result = "Da fox jumps over the lazy dog"""
65+
],
66+
[
67+
Description = "Pattern that does not match",
68+
Code = "RegexReplace(""The quick brown fox jumps over the lazy dog"", ""the quick brown fox"",""Da fox"")",
69+
Result = "The quick brown fox jumps over the lazy dog"
70+
],
71+
[
72+
Description = "Pattern with capturing groups",
73+
Code = "RegexReplace(""The quick brown fox jumps over the lazy dog"", ""the quick brown (.*?) jumps over the ([^ ]*) ([^ ]*)"", ""THE QUICK BROWN $1 JUMPS OVER THE $2 $3"", ""i"")",
74+
Result = "THE QUICK BROWN fox JUMPS OVER THE lazy dog"
75+
]
76+
}
77+
]
78+
in
79+
Value.ReplaceType(
80+
Source,
81+
Value.ReplaceMetadata(
82+
Value.Type(Source),
83+
documentation
84+
)
85+
)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class RuneToPqLiteral {
2+
[string] $Source
3+
[int] $Codepoint
4+
[string] $Hex
5+
6+
# hidden $First
7+
8+
hidden [string] $DisplayCodepoint
9+
10+
RuneToPqLiteral ( [string] $Rune ) {
11+
$first, $rest = $Rune.EnumerateRunes()
12+
if ($rest.count -gt 0) { throw 'nyi IEnumerable list of runes' }
13+
14+
$This.Source = $Rune
15+
# $This.First = $first
16+
$This.Codepoint = $first.Value
17+
$This.Hex = '{0:x}' -f @($This.Codepoint)
18+
$This.DisplayCodepoint = '0x' + $this.Hex
19+
# just do 1 for now
20+
# foreach($Rune in $InputText.EnumerateRunes()) {
21+
22+
# }
23+
$null -eq 2
24+
}
25+
26+
[string] ToString() {
27+
return ''
28+
}
29+
30+
[int] Length () {
31+
return $this.Source.EnumerateRunes().Value.Count
32+
}
33+
34+
35+
}
36+
37+
function StringToPqLiteral {
38+
param(
39+
[Parameter(ValueFromPipeline)]
40+
$InputText
41+
)
42+
43+
process {
44+
# $ErrorActionPreference = 'break'
45+
$InputText.EnumerateRunes() | ForEach-Object {
46+
[RuneToPqLiteral]::new($_)
47+
}
48+
# $ErrorActionPreference = 'continue'
49+
}
50+
}
51+
52+
53+
$sample = ' 🙊🐛🐈'
54+
55+
StringToPqLiteral $sample

source/Text/Text.WordWrap.pq

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
let
3+
/*
4+
Example:
5+
6+
wrapped = Text.WordWrap(LoremIpsum, 80)
7+
LoremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eu laoreet turpis. Curabitur lacinia, risus ut rhoncus mattis, turpis lorem iaculis justo, nec ultrices arcu erat vitae felis. Pellentesque vulputate efficitur scelerisque. Etiam bibendum dignissim mauris",
8+
*/
9+
10+
// calculate length of string *after* the rightmost newline
11+
strNewline = "#(lf)",
12+
Text_LengthAfterNewline = (string as text) as number =>
13+
let
14+
posLastNewline = Text.PositionOf(string, strNewline, Occurrence.Last),
15+
posOffset = if posLastNewline <> -1 then posLastNewline else 0,
16+
deltaLen = Text.Length(string) - posOffset
17+
in
18+
deltaLen,
19+
20+
// word wraps text
21+
Text.WordWrap = (string as text, max_width as number) as text =>
22+
let
23+
words = Text.Split(string, " "),
24+
accum_result = List.Accumulate(
25+
words, "",
26+
(state as text, current as text) as text =>
27+
let
28+
len = Text_LengthAfterNewline(state) + Text.Length(current) + 1,
29+
maybeNewline =
30+
if len > max_width then strNewline else "",
31+
32+
accum_string = Text.Combine({state & maybeNewline, current}, " ")
33+
in
34+
accum_string
35+
)
36+
in
37+
accum_result
38+
in
39+
Text.WordWrap

source/readme.byDirectory.md

Lines changed: 0 additions & 211 deletions
This file was deleted.

0 commit comments

Comments
 (0)