{"id":1538,"date":"2021-02-12T23:06:21","date_gmt":"2021-02-13T05:06:21","guid":{"rendered":"http:\/\/ninmonkeys.com\/blog\/?p=1538"},"modified":"2022-03-12T10:03:18","modified_gmt":"2022-03-12T16:03:18","slug":"word-wrapping-text-in-power-query","status":"publish","type":"post","link":"https:\/\/ninmonkeys.com\/blog\/2021\/02\/12\/word-wrapping-text-in-power-query\/","title":{"rendered":"Word Wrapping Text in Power Query"},"content":{"rendered":"\n\n\n<p>How to wrap long lines, *without* splitting words. The input is a very long string, with no newlines:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">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<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2>Query<\/h2>\n\n\n\n<p><code class=\"\" data-line=\"\">&lt;a href=&quot;https:\/\/docs.microsoft.com\/en-us\/powerquery-m\/list-accumulate&quot;&gt;List.Accumulate&lt;\/a&gt;<\/code> is an aggregate function. I&#8217;m using it to &#8220;sum&#8221; &#8212; to add strings together. If the current line plus the next word is longer than 80 characters, then insert a newline first.<\/p>\n\n\n\n<p>To find the length of the current line, I only want the length <em>after<\/em> the very last newline. <code class=\"\" data-line=\"\">Occurrence.Last<\/code> returns the last match, else <code class=\"\" data-line=\"\">-1<\/code> if nothing is found.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let  \n    LoremIpsum = &quot;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&quot;,\n\n    \/\/ calculate length of string *after* the rightmost newline\n    Text_LengthAfterNewline = (string as text) as number =&gt;\n        let \n            posLastNewline = Text.PositionOf(string, &quot;#(lf)&quot;, Occurrence.Last),\n            posOffset = if posLastNewline &lt;&gt; -1 then posLastNewline else 0,\n            deltaLen = Text.Length(string) - posOffset\n        in\n            deltaLen,\n\n    \/\/ word wraps text\n    Text_WordWrap = (string as text, max_width as number) as text =&gt;\n        let\n            words = Text.Split(string, &quot; &quot;),\n            accum_result = List.Accumulate(\n                words, &quot;&quot;, \n                (state as text, current as text) as text =&gt;\n                    let\n                        len = Text_LengthAfterNewline(state) + Text.Length(current) + 1,\n                        maybeNewline =\n                            if len &gt; max_width then &quot;#(lf)&quot; else &quot;&quot;,\n\n                        accum_string = Text.Combine({state &amp; maybeNewline, current}, &quot; &quot;)\n                    in \n                        accum_string\n            )\n        in\n            accum_result,\n    \n    wrapped_text = Text_WordWrap(LoremIpsum, 80)\nin\n    wrapped_text<\/code><\/pre>\n\n\n\n<p>The final result is 80 characters wide or less<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eu laoreet turpis.\nCurabitur lacinia, risus ut rhoncus mattis, turpis lorem iaculis justo, nec\nultrices arcu erat vitae felis. Pellentesque vulputate efficitur scelerisque.\nEtiam bibendum dignissim mauris<\/pre>\n\n\n\n<h2>Validating lengths of each line<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"622\" height=\"158\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-6.png\" alt=\"\" class=\"wp-image-1549\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-6.png 622w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-6-300x76.png 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let\n    Source = #&quot;wrap lines&quot;,\n    validate_lengths =\n        let \n            lines = Text.Split(Source, &quot;#(lf)&quot;),\n            lengths = List.Transform(\n                lines,\n                each [ String = _, Length = Text.Length(_) ])\n        in\n            Table.FromRecords(\n                lengths,\n                type table[String = text, Length = number],\n                MissingField.Error )\nin\n    validate_lengths<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Word wrapping text using <code class=\"\" data-line=\"\">List.Accumulate<\/code> and <code class=\"\" data-line=\"\">Occurrence.Last<\/code>[simple_icon name=\"powerbi\"]<\/p>\n","protected":false},"author":1,"featured_media":1547,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9],"tags":[6,7,74],"_links":{"self":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1538"}],"collection":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/comments?post=1538"}],"version-history":[{"count":17,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1538\/revisions"}],"predecessor-version":[{"id":2230,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1538\/revisions\/2230"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media\/1547"}],"wp:attachment":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media?parent=1538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/categories?post=1538"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/tags?post=1538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}