Last active
January 7, 2021 14:26
-
-
Save jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e to your computer and use it in GitHub Desktop.
Revisions
-
jeffkreeftmeijer revised this gist
Jan 7, 2021 . 1 changed file with 1 addition 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 charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,7 @@ Jeff Kreeftmeijer <https://jeffkreeftmeijer.com> :url: https://jeffkreeftmeijer.com/vim-reformat-dates/ :image: substitute-dark-shadow.png :tweet_id: 920242997282840577 :revisions: https://gist.github.com/jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e/revisions ifdef::env-github[] :imagesdir: https://gist.githubusercontent.com/jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e/raw endif::[] -
jeffkreeftmeijer revised this gist
Nov 13, 2018 . 1 changed file with 1 addition and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once. image::substitute-dark.png["Finding, converting and replacing dates with Vim substitutions", 730, 568] The _input file_ is an HTML page with a list of articles. Each article includes a `<time>` tag with a value and a datetime attribute to show the publication -
jeffkreeftmeijer revised this gist
Nov 4, 2018 . 4 changed files with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
jeffkreeftmeijer revised this gist
Nov 4, 2018 . 1 changed file with 1 addition and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ Jeff Kreeftmeijer <https://jeffkreeftmeijer.com> 2017-10-17 :description: By using the date utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once. :url: https://jeffkreeftmeijer.com/vim-reformat-dates/ :image: substitute-dark-shadow.png :tweet_id: 920242997282840577 ifdef::env-github[] :imagesdir: https://gist.githubusercontent.com/jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e/raw -
jeffkreeftmeijer revised this gist
Nov 4, 2018 . 4 changed files with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
jeffkreeftmeijer revised this gist
Nov 3, 2018 . 3 changed files with 1 addition and 1 deletion.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.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 charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once. image::substitute-dark.png["Finding, converting and replacing dates with Vim substitutions", 720, 680] The _input file_ is an HTML page with a list of articles. Each article includes a `<time>` tag with a value and a datetime attribute to show the publication -
jeffkreeftmeijer revised this gist
Nov 2, 2018 . 1 changed file with 1 addition 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 charactersOriginal file line number Diff line number Diff line change @@ -342,6 +342,7 @@ without adding that extra newline. .The result ---- include::archive_after.html[lines=1..19] … ---- [small]#_Thanks Wouter Vos and Rico Sta. Cruz for feedback on the substitution command -
jeffkreeftmeijer revised this gist
Nov 2, 2018 . 4 changed files with 1 addition and 1 deletion.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.Binary file not shown.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 charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once. image::substitute-dark.png["Finding, converting and replacing dates with Vim substitutions", 1082, 859] The _input file_ is an HTML page with a list of articles. Each article includes a `<time>` tag with a value and a datetime attribute to show the publication -
jeffkreeftmeijer revised this gist
Nov 2, 2018 . 3 changed files with 213 additions and 35 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 charactersOriginal file line number Diff line number Diff line change @@ -1,16 +1,104 @@ <ul> <li> <article> <time datetime="2017-10-17">2017-10-17</time> <span><a href="/vim-reformat-dates/">Find, convert and replace dates with Vim substitutions</a></span> </article> </li> <li> <article> <time datetime="2017-09-19">2017-09-19</time> <span><a href="/open-source-maintainability/">Keeping open source software projects maintainable</a></span> </article> </li> <li> <article> <time datetime="2017-08-22">2017-08-22</time> <span><a href="/mix-proper/">Property-based testing in Elixir using PropEr</a></span> </article> </li> <li> <article> <time datetime="2015-10-01">2015-10-01</time> <span><a href="/git-git/">“git is not a git command”</a></span> </article> </li> <li> <article> <time datetime="2014-09-11">2014-09-11</time> <span><a href="/activerecord-destroyed/">Checking if an ActiveRecord model instance was destroyed</a></span> </article> </li> <li> <article> <time datetime="2014-09-09">2014-09-09</time> <span><a href="/carrierwave-rails-test-fixtures/">Using Rails test fixtures with CarrierWave</a></span> </article> </li> <li> <article> <time datetime="2013-04-29">2013-04-29</time> <span><a href="/2013/on-the-death-of-ifs/">On the death of ifs</a></span> </article> </li> <li> <article> <time datetime="2012-06-11">2012-06-11</time> <span><a href="/2012/preloading-dependencies-for-faster-test-suite-start-up-times/">Preloading dependencies for faster test suite start-up times</a></span> </article> </li> <li> <article> <time datetime="2012-01-30">2012-01-30</time> <span><a href="/vim-number/">Vim’s absolute, relative and hybrid line numbers</a></span> </article> </li> <li> <article> <time datetime="2011-11-28">2011-11-28</time> <span><a href="/ruby-method-chaining/">Method chaining and lazy evaluation in Ruby</a></span> </article> </li> <li> <article> <time datetime="2011-10-03">2011-10-03</time> <span><a href="/2011/microgems-five-minute-rubygems/">MicroGems: five minute RubyGems</a></span> </article> </li> <li> <article> <time datetime="2011-07-25">2011-07-25</time> <span><a href="/2011/the-pain-of-json-api-testing/">The pain of JSON API testing</a></span> </article> </li> <li> <article> <time datetime="2011-04-18">2011-04-18</time> <span><a href="/ruby-compare-images/">Comparing images and creating image diffs in Ruby</a></span> </article> </li> <li> <article> <time datetime="2010-11-15">2010-11-15</time> <span><a href="/fuubar-rspec-progress-bar-formatter/">Fuubar: the instafailing RSpec progress bar formatter</a></span> </article> </li> <li> <article> <time datetime="2010-11-08">2010-11-08</time> <span><a href="/rspec-fail-fast/">Stop RSpec on the first failure with the --fail-fast command line option</a></span> </article> </li> <li> <article> <time datetime="2010-10-11">2010-10-11</time> <span><a href="/git-rebase/">Git rebase: reapply your changes onto another branch</a></span> </article> </li> <li> <article> <time datetime="2011-08-19">2010-08-19</time> <span><a href="/git-flow/">Using git-flow to automate your git branching workflow</a></span> </article> </li> </ul> 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 charactersOriginal file line number Diff line number Diff line change @@ -1,16 +1,104 @@ <ul> <li> <article> <time datetime="2017-10-17">October 17, 2017</time> <span><a href="/vim-reformat-dates/">Find, convert and replace dates with Vim substitutions</a></span> </article> </li> <li> <article> <time datetime="2017-09-19">September 19, 2017</time> <span><a href="/open-source-maintainability/">Keeping open source software projects maintainable</a></span> </article> </li> <li> <article> <time datetime="2017-08-22">August 22, 2017</time> <span><a href="/mix-proper/">Property-based testing in Elixir using PropEr</a></span> </article> </li> <li> <article> <time datetime="2015-10-01">October 01, 2015</time> <span><a href="/git-git/">“git is not a git command”</a></span> </article> </li> <li> <article> <time datetime="2014-09-11">September 11, 2014</time> <span><a href="/activerecord-destroyed/">Checking if an ActiveRecord model instance was destroyed</a></span> </article> </li> <li> <article> <time datetime="2014-09-09">September 09, 2014</time> <span><a href="/carrierwave-rails-test-fixtures/">Using Rails test fixtures with CarrierWave</a></span> </article> </li> <li> <article> <time datetime="2013-04-29">April 29, 2013</time> <span><a href="/2013/on-the-death-of-ifs/">On the death of ifs</a></span> </article> </li> <li> <article> <time datetime="2012-06-11">June 11, 2012</time> <span><a href="/2012/preloading-dependencies-for-faster-test-suite-start-up-times/">Preloading dependencies for faster test suite start-up times</a></span> </article> </li> <li> <article> <time datetime="2012-01-30">January 30, 2012</time> <span><a href="/vim-number/">Vim’s absolute, relative and hybrid line numbers</a></span> </article> </li> <li> <article> <time datetime="2011-11-28">November 28, 2011</time> <span><a href="/ruby-method-chaining/">Method chaining and lazy evaluation in Ruby</a></span> </article> </li> <li> <article> <time datetime="2011-10-03">October 03, 2011</time> <span><a href="/2011/microgems-five-minute-rubygems/">MicroGems: five minute RubyGems</a></span> </article> </li> <li> <article> <time datetime="2011-07-25">July 25, 2011</time> <span><a href="/2011/the-pain-of-json-api-testing/">The pain of JSON API testing</a></span> </article> </li> <li> <article> <time datetime="2011-04-18">April 18, 2011</time> <span><a href="/ruby-compare-images/">Comparing images and creating image diffs in Ruby</a></span> </article> </li> <li> <article> <time datetime="2010-11-15">November 15, 2010</time> <span><a href="/fuubar-rspec-progress-bar-formatter/">Fuubar: the instafailing RSpec progress bar formatter</a></span> </article> </li> <li> <article> <time datetime="2010-11-08">November 08, 2010</time> <span><a href="/rspec-fail-fast/">Stop RSpec on the first failure with the --fail-fast command line option</a></span> </article> </li> <li> <article> <time datetime="2010-10-11">October 11, 2010</time> <span><a href="/git-rebase/">Git rebase: reapply your changes onto another branch</a></span> </article> </li> <li> <article> <time datetime="2011-08-19">August 19, 2010</time> <span><a href="/git-flow/">Using git-flow to automate your git branching workflow</a></span> </article> </li> </ul> 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 charactersOriginal file line number Diff line number Diff line change @@ -24,7 +24,8 @@ date. .The input file [source, html] ---- include::archive.html[lines=1..19] … ---- We need to convert the dates`' values to a friendlier format that @@ -34,7 +35,8 @@ datetime attributes in their current format. .The result: articles with reformatted dates [source, html] ---- include::archive_after.html[lines=1..19] … ---- The input file has more than forty articles, so replacing them all by hand @@ -339,7 +341,7 @@ without adding that extra newline. .The result ---- include::archive_after.html[lines=1..19] ---- [small]#_Thanks Wouter Vos and Rico Sta. Cruz for feedback on the substitution command -
jeffkreeftmeijer revised this gist
Jun 5, 2018 . 1 changed file with 4 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 charactersOriginal file line number Diff line number Diff line change @@ -341,3 +341,7 @@ without adding that extra newline. ---- include::archive_after.html[] ---- [small]#_Thanks Wouter Vos and Rico Sta. Cruz for feedback on the substitution command styling, u/Vurpius for suggesting `\ze` and Ben Sinclair for suggesting piping through `tr`._# -
jeffkreeftmeijer revised this gist
Jun 5, 2018 . 2 changed files with 14 additions and 3 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 charactersOriginal file line number Diff line number Diff line change @@ -284,8 +284,13 @@ We can run a second substitution to remove them after running the first one: :%s/\n<\/time>/<\/time>/g To keep the original substitution from adding newlines in the first place, we can pipe the result from the `date` command to `tr` to remove the newline with the `-d` argument: :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y" | tr -d "\n"')/gc Another option is to take the newline out with a _nested substitution_. .The `substitute()` function **** 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 charactersOriginal file line number Diff line number Diff line change @@ -141,7 +141,13 @@ We can run a second substitution to remove them after running the first one: :%s/\n<\/time>/<\/time>/g To keep the original substitution from adding newlines in the first place, we can pipe the result from the `date` command to `tr` to remove the newline with the `-d` argument: :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y" | tr -d "\n"')/gc Another option is to take the newline out with a *nested substitution*. ### The `substitute()` function -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 2 changed files with 2 additions and 2 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 charactersOriginal file line number Diff line number Diff line change @@ -262,7 +262,7 @@ hardcoded date with a call to `submatch(0)` to insert the whole match. Running this substitution will turn all `<time>` tags from the input file to our desired format, but it puts a newline before the closing `</time>` tag. .The current result, with an added newline before the closing `</time>` tag [source, html] ---- <article> 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 charactersOriginal file line number Diff line number Diff line change @@ -120,7 +120,7 @@ To pass the matched date to the call to `date` in our expression, we need to bre Running this substitution will turn all `<time>` tags from the input file to our desired format, but it beaks the closing `</time>` tag with an extra newline. The current result, with an added newline before the closing `</time>` tag ``` html <article> -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 0 additions and 10 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 charactersOriginal file line number Diff line number Diff line change @@ -114,16 +114,6 @@ We use the `system()` function from an expression (`\=`) to call out to the `dat The replacement value is still hardcoded (“1991-11-02”), so this substitution will overwrite all date values in the file to a date in 1991. To put the matched date values back in the file, we need to pass them to the date command. To pass the matched date to the call to `date` in our expression, we need to break out of the string passed to the `system()` function and replace the hardcoded date with a call to `submatch(0)` to insert the whole match. :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y"')/gc -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 1 addition and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -108,7 +108,7 @@ We use the `system()` function from an expression (`\=`) to call out to the `dat - `....-..-..\ze<`: The search pattern to find all dates in the file - `\=system('date …')`: An expression that uses the `system()` function to execute an external command and returns its value as the substitute string - `'date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y"'`: The date command as a string, with a hardcoded date (`"1991-11-02"`) as its input date argument. This date matches the format of the search pattern's matches. > ⚠️ This substitution produces a newline in the `<time>` tag, because the `date` utility appends one to its output. We'll remove these later while discussing nested substitutions. -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 2 changed files with 2 additions and 2 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 charactersOriginal file line number Diff line number Diff line change @@ -135,7 +135,7 @@ to match the results from the search pattern. The _output format_ is `"%B %d, %Y"` to produce the month's full name, the date's number, a comma and the year number. With these formats the `date` utility reformats `1991-11-02` to `November 02, 1991`. [[date-command]] 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 charactersOriginal file line number Diff line number Diff line change @@ -78,7 +78,7 @@ We need the month's full name in the date replacements, so we can't reorder the We reformat each match of our search pattern to our desired format (“September 19, 2017”) with the `date` utility. We use `"%Y-%m-%d"` as the *input format* to match the results from the search pattern. The *output format* is `"%B %d, %Y"` to produce the month's full name, the date's number, a comma and the year number. With these formats the `date` utility reformats `1991-11-02` to `November 02, 1991`. $ date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y" November 02 1991 -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 9 additions and 9 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 charactersOriginal file line number Diff line number Diff line change @@ -95,20 +95,20 @@ We know how to find all dates in the file, and how to convert a date to another Using the search pattern we prepared earlier, we can find and replace all date values from the input file with a substitution. For example, we could overwrite all dates with a hardcoded value: :%s/....-..-..\ze</November 2, 1991/gc - `....-..-..\ze<`: The search pattern to find all dates in the file - `November 2, 1991`: The literal substitute string to replace the dates with a hardcoded one Instead of inserting a hardcoded substitute string, we need to run an expression for each match to get its replacement. We use the `system()` function from an expression (`\=`) to call out to the `date` utility. Sticking with hardcoded dates for now, we can use the utility to convert a date's format from “1991-11-02” to “November 2, 1991” before inserting it into the file: :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y"')/gc - `....-..-..\ze<`: The search pattern to find all dates in the file - `\=system('date …')`: An expression that uses the `system()` function to execute an external command and returns its value as the substitute string - `'date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y"'`: The [date command](#date-command) as a string, with a hardcoded date (`"1991-11-02"`) as its input date argument. This date matches the format of the search pattern's matches. > ⚠️ This substitution produces a newline in the `<time>` tag, because the `date` utility appends one to its output. We'll remove these later while discussing nested substitutions. @@ -126,7 +126,7 @@ In an expression, submatches can be included using the `submatch()` function. To pass the matched date to the call to `date` in our expression, we need to break out of the string passed to the `system()` function and replace the hardcoded date with a call to `submatch(0)` to insert the whole match. :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y"')/gc Running this substitution will turn all `<time>` tags from the input file to our desired format, but it beaks the closing `</time>` tag with an extra newline. @@ -149,7 +149,7 @@ A newline is appended to the result of the `date` command, which ends up in the We can run a second substitution to remove them after running the first one: :%s/\n<\/time>/<\/time>/g Another option is to use a *nested substitution* to keep the original substitution from adding newlines in the first place. @@ -174,7 +174,7 @@ If an external command called from a substitution returns a trailing newline (li We wrap the call to the `date` utility in a nested substitution using the `substitute()` function. It takes the result, matches the newline (`"\n"`) and replaces it with an empty string. :%s/....-..-..\ze</\=substitute(system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y"'), "\n", "", "")/gc Now our substitution will turn the `<time>` tags into the correct format, without adding that extra newline. -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 32 additions and 110 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 charactersOriginal file line number Diff line number Diff line change @@ -1,19 +1,12 @@ Find, convert and replace dates with Vim substitutions ====================================================== Vim's substitution command is a powerful way to make changes to text files. Besides finding and replacing text using regular expressions, substitutions can call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once.  The *input file* is an HTML page with a list of articles. Each article includes a `<time>` tag with a value and a datetime attribute to show the publication date. *The input file* ``` html @@ -35,9 +28,7 @@ the publication date. ... ``` We need to convert the dates' values to a friendlier format that includes the full month name (“September 19, 2017”), while keeping the datetime attributes in their current format. *The result: articles with reformatted dates* ``` html @@ -59,59 +50,35 @@ datetime attributes in their current format. ... ``` The input file has more than forty articles, so replacing them all by hand would be a lot of error-prone work. Instead, we write a substitution that finds all dates in the file and replaces them with a reformatted value. Finding the dates ----------------- The first step in replacing the dates is finding where they are in the input file and making sure not to match the ones in the datetime attributes. To find all dates in the file, we could use `....-..-..` (`esc` `/....-..-..`) as our search pattern to match the date format. However, this pattern's results will include all matching dates in the file, including the ones in the `<time>` tags' datetime attributes. ``` html <time datetime="2017-09-19">2017-09-19</time> ``` In the input file, all `<time>` values are immediately followed by the less-than sign from the closing `</time>` tag. To prevent the datetimes from the attributes to be included in the results, we could include the less-than sign in the search pattern and make sure to add it back when replacing. ....-..-..< Hoever, Vim supports setting the start and end of the match in the search pattern using the `\zs` and `\ze` pattern atoms. By prefixing the `<` in our search pattern with `\ze`, the pattern finds all dates followed by a less-than sign, but doesn't include it in the match, meaning it won't be replaced. ....-..-..\ze< Reformatting dates from the command line ---------------------------------------- We need the month's full name in the date replacements, so we can't reorder the input value (“2017-09-19”) to get the result we want. Instead, we need to call out to an external utility that knows month names and can convert between date formats. We reformat each match of our search pattern to our desired format (“September 19, 2017”) with the `date` utility. We use `"%Y-%m-%d"` as the *input format* to match the results from the search pattern. The *output format* is `"%B %d, %Y"` to produce the month's full name, the date's number, a comma and the year number. With these formats the `date` utility reformats `1992-11-02` to `November 02, 1991`. $ date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y" November 02 1991 @@ -124,70 +91,46 @@ With these formats the `date` utility reformats `1992-11-02` to Calling out to external utilities from substitutions ---------------------------------------------------- We know how to find all dates in the file, and how to convert a date to another format from the command line. To replace all found dates with a reformatted version from the `date` utility, we need to run an *expression* from a *substitution*. Using the search pattern we prepared earlier, we can find and replace all date values from the input file with a substitution. For example, we could overwrite all dates with a hardcoded value: :%s/....-..-..</November 2, 1991</gc - `....-..-..<`: The search pattern to find all dates in the file - `November 2, 1991<`: The literal substitute string to replace the dates with a hardcoded one Instead of inserting a hardcoded substitute string, we need to run an expression for each match to get its replacement. We use the `system()` function from an expression (`\=`) to call out to the `date` utility. Sticking with hardcoded dates for now, we can use the utility to convert a date's format from “1991-11-02” to “November 2, 1991” before inserting it into the file: :%s/....-..-..</\=system('date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"')/gc - `....-..-..<`: The search pattern to find all dates in the file - `\=system('date …')`: An expression that uses the `system()` function to execute an external command and returns its value as the substitute string - `'date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"'`: The [date command](#date-command) as a string, with a hardcoded date (`"1991-11-02<"`) as its input date argument. This date matches the format of the search pattern's matches. > ⚠️ This substitution produces a newline in the `<time>` tag, because the `date` utility appends one to its output. We'll remove these later while discussing nested substitutions. The replacement value is still hardcoded (“1991-11-02”), so this substitution will overwrite all date values in the file to a date in 1991. To put the matched date values back in the file, we need to pass them to the date command. ### Submatches Vim's `submatch()` function returns matches from our pattern. If we call it with `0` as its argument, it will return the whole match instead of a submatch. To wrap each occurrence of “October” in brackets, we use `[\0]` as the substitute string. :%s/October/[\0]/gc In an expression, submatches can be included using the `submatch()` function. :%s/October/\='['.submatch('0').']'/gc To pass the matched date to the call to `date` in our expression, we need to break out of the string passed to the `system()` function and replace the hardcoded date with a call to `submatch(0)` to insert the whole match. :%s/....-..-..</\=system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"')/gc Running this substitution will turn all `<time>` tags from the input file to our desired format, but it beaks the closing `</time>` tag with an extra newline. The current result, with an added newline that breaks the closing `</time>` tag ``` html <article> @@ -202,59 +145,38 @@ The current result, with an added newline that breaks the closing Nested substitutions -------------------- A newline is appended to the result of the `date` command, which ends up in the file after running the substitution. Since there's no way to get the date command to omit the newline, we need to take it out ourselves. We can run a second substitution to remove them after running the first one: :%s/<\n\/time>/<\/time>/g Another option is to use a *nested substitution* to keep the original substitution from adding newlines in the first place. ### The `substitute()` function Vim's `substitute()` function replaces strings and can be run from an expression in a substitution. Nested substitutions are useful for transforming the result of another function. The function (`substitute()`) works like the substitute command (`:s`), and takes the same arguments, so `substitute("input", "find", "replace", "g")` is equivalent to running `:%s/find/replace/g` in a file. The `substitute()` function works like the substitute command (`:s[ubstitute]`) in Vim's command line and takes the same arguments. The first argument is the input, then the search pattern, the substitute string, followed by optional options. `substitute("input", "find", "replace", "g")` is equivalent to running `:%s/find/replace/g` in a file. :echom substitute("October 02, 1991", "October", "November", "") - `"October 02, 1991"`: The input string to run the substitution on. - `"October"`: The search pattern. - `"November"`: The substitute string. - `""`: Options, like in a “regular” substitution. This example doesn't use the `g` option because we're sure there's only one match in the input string, so it isn't necessary. If an external command called from a substitution returns a trailing newline (like `echo` would without the `-n` flag), we can use the `substitute()` function to take it out before the match is replaced. :%s/October/\=substitute(system('echo "November"'), "\n", "", "")/gc We wrap the call to the `date` utility in a nested substitution using the `substitute()` function. It takes the result, matches the newline (`"\n"`) and replaces it with an empty string. :%s/....-..-..</\=substitute(system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"'), "\n", "", "")/gc Now our substitution will turn the `<time>` tags into the correct format, without adding that extra newline. *The result* -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 4 additions and 4 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 charactersOriginal file line number Diff line number Diff line change @@ -71,10 +71,10 @@ The first step in replacing the dates is finding where they are in the input file and making sure not to match the ones in the datetime attributes. To find all dates in the file, we could use `....-..-..` (`esc` `/....-..-..`) as our search pattern to match the date format. However, this pattern's results will include all matching dates in the file, including the ones in the `<time>` tags' datetime attributes. ``` html <time datetime="2017-09-19">2017-09-19</time> -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 19 additions and 19 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 charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ Find, convert and replace dates with Vim substitutions ====================================================== Vim's substitution command is a powerful way to make changes to text files. Besides finding and replacing text using regular expressions, substitutions can call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can @@ -35,7 +35,7 @@ the publication date. ... ``` We need to convert the dates' values to a friendlier format that includes the full month name (“September 19, 2017”), while keeping the datetime attributes in their current format. @@ -73,8 +73,8 @@ attributes. To find all dates in the file, we could use `....-..-..` (esc `/....-..-..`) as our search pattern to match the date format. However, this pattern's results will include all matching dates in the file, including the ones in the `<time>` tags' datetime attributes. ``` html <time datetime="2017-09-19">2017-09-19</time> @@ -91,32 +91,32 @@ replacing. Hoever, Vim supports setting the start and end of the match in the search pattern using the `\zs` and `\ze` pattern atoms. By prefixing the `<` in our search pattern with `\ze`, the pattern finds all dates followed by a less-than sign, but doesn't include it in the match, meaning it won't be replaced. ....-..-..\ze< Reformatting dates from the command line ---------------------------------------- We need the month's full name in the date replacements, so we can't reorder the input value (“2017-09-19”) to get the result we want. Instead, we need to call out to an external utility that knows month names and can convert between date formats. We reformat each match of our search pattern to our desired format (“September 19, 2017”) with the `date` utility. We use `"%Y-%m-%d"` as the *input format* to match the results from the search pattern. The *output format* is `"%B %d, %Y"` to produce the month's full name, the date's number, a comma and the year number. With these formats the `date` utility reformats `1992-11-02` to `November 02, 1991`. $ date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y" November 02 1991 - `-j`: Don't try to set the system date - `-f "%Y-%m-%d"`: Use the passed input format instead of the default. In this case `"%Y-%m-%d"` to match the input format (`1991-11-02`) - `"1991-11-02"`: An example date to be parsed using the input format passed to `-f` - `+"%B %d, %Y"`: The output format, which produces `November 02, 1991` @@ -143,17 +143,17 @@ expression for each match to get its replacement. We use the `system()` function from an expression (`\=`) to call out to the `date` utility. Sticking with hardcoded dates for now, we can use the utility to convert a date's format from “1991-11-02” to “November 2, 1991” before inserting it into the file: :%s/....-..-..</\=system('date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"')/gc - `....-..-..<`: The search pattern to find all dates in the file - `\=system('date …')`: An expression that uses the `system()` function to execute an external command and returns its value as the substitute string - `'date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"'`: The [date command](#date-command) as a string, with a hardcoded date (`"1991-11-02<"`) as its input date argument. This date matches the format of the search pattern's matches. > ⚠️ This substitution produces a newline in the `<time>` tag, because the > `date` utility appends one to its output. We'll remove these later while > discussing nested substitutions. The replacement value is still hardcoded (“1991-11-02”), so this @@ -163,7 +163,7 @@ them to the date command. ### Submatches Vim's `submatch()` function returns matches from our pattern. If we call it with `0` as its argument, it will return the whole match instead of a submatch. To wrap each occurrence of “October” in brackets, we use `[\0]` as the substitute string. @@ -203,7 +203,7 @@ Nested substitutions -------------------- A newline is appended to the result of the `date` command, which ends up in the file after running the substitution. Since there's no way to get the date command to omit the newline, we need to take it out ourselves. We can run a second substitution to remove them after running the first @@ -216,7 +216,7 @@ substitution from adding newlines in the first place. ### The `substitute()` function Vim's `substitute()` function replaces strings and can be run from an expression in a substitution. Nested substitutions are useful for transforming the result of another function. @@ -226,7 +226,7 @@ and takes the same arguments, so `:%s/find/replace/g` in a file. The `substitute()` function works like the substitute command (`:s[ubstitute]`) in Vim's command line and takes the same arguments. The first argument is the input, then the search pattern, the substitute string, followed by optional options. `substitute("input", "find", "replace", "g")` is equivalent to running @@ -238,8 +238,8 @@ string, followed by optional options. - `"October"`: The search pattern. - `"November"`: The substitute string. - `""`: Options, like in a “regular” substitution. This example doesn't use the `g` option because we're sure there's only one match in the input string, so it isn't necessary. If an external command called from a substitution returns a trailing newline (like `echo` would without the `-n` flag), we can use the -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 22 additions and 18 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 charactersOriginal file line number Diff line number Diff line change @@ -82,11 +82,20 @@ including the ones in the `<time>` tags’ datetime attributes. In the input file, all `<time>` values are immediately followed by the less-than sign from the closing `</time>` tag. To prevent the datetimes from the attributes to be included in the results, we could include the less-than sign in the search pattern and make sure to add it back when replacing. ....-..-..< Hoever, Vim supports setting the start and end of the match in the search pattern using the `\zs` and `\ze` pattern atoms. By prefixing the `<` in our search pattern with `\ze`, the pattern finds all dates followed by a less-than sign, but doesn’t include it in the match, meaning it won’t be replaced. ....-..-..\ze< Reformatting dates from the command line ---------------------------------------- @@ -96,26 +105,21 @@ Instead, we need to call out to an external utility that knows month names and can convert between date formats. We reformat each match of our search pattern to our desired format (“September 19, 2017”) with the `date` utility. We use `"%Y-%m-%d"` as the *input format* to match the results from the search pattern. The *output format* is `"%B %d, %Y"` to produce the month’s full name, the date’s number, a comma and the year number. With these formats the `date` utility reformats `1992-11-02` to `November 02, 1991`. $ date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y" November 02 1991 - `-j`: Don’t try to set the system date - `-f "%Y-%m-%d"`: Use the passed input format instead of the default. In this case `"%Y-%m-%d"` to match the input format (`1991-11-02`) - `"1991-11-02"`: An example date to be parsed using the input format passed to `-f` - `+"%B %d, %Y"`: The output format, which produces `November 02, 1991` Calling out to external utilities from substitutions ---------------------------------------------------- -
jeffkreeftmeijer renamed this gist
Jun 3, 2018 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 2 additions and 2 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 charactersOriginal file line number Diff line number Diff line change @@ -71,14 +71,14 @@ ones in the `<time>` tags`' datetime attributes. In the input file, all `<time>` values are immediately followed by the less-than sign from the closing `</time>` tag. To prevent the datetimes from the attributes to be included in the results, we could include the less-than sign in the search pattern and make sure to add it back when replacing. ....-..-..< Hoever, Vim supports setting the start and end of the match in the search pattern using the `\zs` and `\ze` pattern atoms. By prefixing the `<` in our search pattern with `\ze`, the pattern finds all dates followed by a less-than sign, but doesn't include it in the match, meaning it won't be replaced. ....-..-..\ze< -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 38 additions and 36 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 charactersOriginal file line number Diff line number Diff line change @@ -70,11 +70,18 @@ ones in the `<time>` tags`' datetime attributes. In the input file, all `<time>` values are immediately followed by the less-than sign from the closing `</time>` tag. To prevent the datetimes from the attributes to be included in the results, we could include the less-than sign in the search pattern and take it out later. ....-..-..< Hoever, Vim supports setting the start and end of the match in the search pattern using the `\zs` and `\ze` pattern atoms. By prefixing the `<` in our search pattern with `\ze`, the pattern finds all dates followed by a less-than sign, but doesn't include it in the match. ....-..-..\ze< == Reformatting dates from the command line We need the month's full name in the date replacements, so we can't reorder the @@ -123,31 +130,27 @@ reformat dates. **** We reformat each match of our search pattern to our desired format ("`September 19, 2017`") with the `date` utility. We use `"%Y-%m-%d"` as the _input format_ to match the results from the search pattern. The _output format_ is `"%B %d, %Y"` to produce the month's full name, the date's number, a comma and the year number. With these formats the `date` utility reformats `1992-11-02` to `November 02, 1991`. [[date-command]] $ date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y" November 02 1991 `-j`:: Don't try to set the system date `-f "%Y-%m-%d"`:: Use the passed input format instead of the default. In this case `"%Y-%m-%d"` to match the input format (`1991-11-02`). `"1991-11-02"`:: An example date to be parsed using the input format passed to `-f`. `+"%B %d, %Y"`:: The output format, which produces `November 02, 1991`. == Calling out to external utilities from substitutions @@ -176,11 +179,11 @@ Using the search pattern we prepared earlier, we can find and replace all date values from the input file with a substitution. For example, we could overwrite all dates with a hardcoded value: :%s/....-..-..\ze</November 2, 1991/gc `\....-..-..`:: The <<finding-the-dates, search pattern>> to find all dates in the file. `November 2, 1991`:: The literal substitute string to replace the dates with a hardcoded one. Instead of inserting a hardcoded substitute string, we need to run an @@ -216,20 +219,20 @@ We use the `system()` function from an expression (`\=`) to call out to the to convert a date's format from "`1991-11-02`" to "`November 2, 1991`" before inserting it into the file: :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y"')/gc `\....-..-..\ze<`:: The <<finding-the-dates, search pattern>> to find all dates in the file. `\=system('date ...')`:: An expression that uses the `system()` function to execute an external command and returns its value as the substitute string. `'date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y"'`:: The <<date-command, date command>> as a string, with a hardcoded date (`"1991-11-02"`) as its input date argument. This date matches the format of the search pattern's matches. WARNING: This substitution produces a newline before the `<time>` tag, because the `date` utility appends one to its output. We'll remove these later while discussing <<nested-substitutions, nested substitutions>>. The replacement value is still hardcoded ("`1991-11-02`"), so this substitution @@ -254,19 +257,18 @@ To pass the matched date to the call to `date` in our expression, we need to break out of the string passed to the `system()` function and replace the hardcoded date with a call to `submatch(0)` to insert the whole match. :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y"')/gc Running this substitution will turn all `<time>` tags from the input file to our desired format, but it puts a newline before the closing `</time>` tag. .The current result, with an added newline that breaks the closing `</time>` tag [source, html] ---- <article> <h1>Keeping open source projects maintainable</h1> <time datetime="2017-09-19">September 19, 2017 </time> </article> ... @@ -280,7 +282,7 @@ command to omit the newline, we need to take it out ourselves. We can run a second substitution to remove them after running the first one: :%s/\n<\/time>/<\/time>/g Another option is to use a _nested substitution_ to keep the original substitution from adding newlines in the first place. @@ -325,7 +327,7 @@ We wrap the call to the `date` utility in a nested substitution using the `substitute()` function. It takes the result, matches the newline (`"\n"`) and replaces it with an empty string. :%s/....-..-..\ze</\=substitute(system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y"'), "\n", "", "")/gc Now our substitution will turn the `<time>` tags into the correct format, without adding that extra newline. -
jeffkreeftmeijer revised this gist
Jun 3, 2018 . 1 changed file with 274 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,274 @@ Find, convert and replace dates with Vim substitutions ====================================================== Vim’s substitution command is a powerful way to make changes to text files. Besides finding and replacing text using regular expressions, substitutions can call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once.  The *input file* is an HTML page with a list of articles. Each article includes a `<time>` tag with a value and a datetime attribute to show the publication date. *The input file* ``` html <article> <h1>Keeping open source projects maintainable</h1> <time datetime="2017-09-19">2017-09-19</time> </article> <article> <h1>Property-based testing in Elixir using PropEr</h1> <time datetime="2017-08-22">2017-08-22</time> </article> <article> <h1>git is not a git command</h1> <time datetime="2015-10-01">2015-10-01</time> </article> ... ``` We need to convert the dates’ values to a friendlier format that includes the full month name (“September 19, 2017”), while keeping the datetime attributes in their current format. *The result: articles with reformatted dates* ``` html <article> <h1>Keeping open source projects maintainable</h1> <time datetime="2017-09-19">September 19, 2017</time> </article> <article> <h1>Property-based testing in Elixir using PropEr</h1> <time datetime="2017-08-22">August 22, 2017</time> </article> <article> <h1>git is not a git command</h1> <time datetime="2015-10-01">October 01, 2015</time> </article> ... ``` The input file has more than forty articles, so replacing them all by hand would be a lot of error-prone work. Instead, we write a substitution that finds all dates in the file and replaces them with a reformatted value. Finding the dates ----------------- The first step in replacing the dates is finding where they are in the input file and making sure not to match the ones in the datetime attributes. To find all dates in the file, we could use `....-..-..` (esc `/....-..-..`) as our search pattern to match the date format. However, this pattern’s results will include all matching dates in the file, including the ones in the `<time>` tags’ datetime attributes. ``` html <time datetime="2017-09-19">2017-09-19</time> ``` In the input file, all `<time>` values are immediately followed by the less-than sign from the closing `</time>` tag. To prevent the datetimes from the attributes to be included in the results, we include the less-than sign in the search pattern. ....-..-..< Reformatting dates from the command line ---------------------------------------- We need the month’s full name in the date replacements, so we can’t reorder the input value (“2017-09-19”) to get the result we want. Instead, we need to call out to an external utility that knows month names and can convert between date formats. We reformat each match of our search pattern to our desired format (“September 19, 2017”) with the `date` utility. Because we include the trailing less-than sign in the search pattern, the dates we use for the conversion will end with one too (“2017-09-19<”). We append the less-than sign to the input format to match the results from the search pattern (`"%Y-%m-%d<"`). The output format is `"%B %d, %Y<"` to produce the month’s name, the date’s number, a comma and the year number, followed by the less-than sign (`September 19, 2017<`) to keep the HTML intact. With these formats the `date` utility reformats `1992-11-02<` to `November 02, 1991<`. $ date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<" November 02 1991< - `-j`: Don’t try to set the system date - `-f "%Y-%m-%d<"`: Use the passed input format instead of the default. In this case `"%Y-%m-%d<"` to match the input format (`1991-11-02<`) - `"1991-11-02<"`: An example date to be parsed using the input format passed to `-f` - `+"%B %d, %Y<"`: The output format, which produces `November 02, 1991<` Calling out to external utilities from substitutions ---------------------------------------------------- We know how to find all dates in the file, and how to convert a date to another format from the command line. To replace all found dates with a reformatted version from the `date` utility, we need to run an *expression* from a *substitution*. Using the search pattern we prepared earlier, we can find and replace all date values from the input file with a substitution. For example, we could overwrite all dates with a hardcoded value: :%s/....-..-..</November 2, 1991</gc - `....-..-..<`: The search pattern to find all dates in the file - `November 2, 1991<`: The literal substitute string to replace the dates with a hardcoded one Instead of inserting a hardcoded substitute string, we need to run an expression for each match to get its replacement. We use the `system()` function from an expression (`\=`) to call out to the `date` utility. Sticking with hardcoded dates for now, we can use the utility to convert a date’s format from “1991-11-02” to “November 2, 1991” before inserting it into the file: :%s/....-..-..</\=system('date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"')/gc - `....-..-..<`: The search pattern to find all dates in the file - `\=system('date …')`: An expression that uses the `system()` function to execute an external command and returns its value as the substitute string - `'date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"'`: The [date command](#date-command) as a string, with a hardcoded date (`"1991-11-02<"`) as its input date argument. This date matches the format of the search pattern’s matches. > ⚠️ This substitution produces a newline in the `<time>` tag, because the > `date` utility appends one to its output. We’ll remove these later while > discussing nested substitutions. The replacement value is still hardcoded (“1991-11-02”), so this substitution will overwrite all date values in the file to a date in 1991. To put the matched date values back in the file, we need to pass them to the date command. ### Submatches Vim’s `submatch()` function returns matches from our pattern. If we call it with `0` as its argument, it will return the whole match instead of a submatch. To wrap each occurrence of “October” in brackets, we use `[\0]` as the substitute string. :%s/October/[\0]/gc In an expression, submatches can be included using the `submatch()` function. :%s/October/\='['.submatch('0').']'/gc To pass the matched date to the call to `date` in our expression, we need to break out of the string passed to the `system()` function and replace the hardcoded date with a call to `submatch(0)` to insert the whole match. :%s/....-..-..</\=system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"')/gc Running this substitution will turn all `<time>` tags from the input file to our desired format, but it beaks the closing `</time>` tag with an extra newline. The current result, with an added newline that breaks the closing `</time>` tag ``` html <article> <h1>Keeping open source projects maintainable</h1> <time datetime="2017-09-19">September 19, 2017< /time> </article> ... ``` Nested substitutions -------------------- A newline is appended to the result of the `date` command, which ends up in the file after running the substitution. Since there’s no way to get the date command to omit the newline, we need to take it out ourselves. We can run a second substitution to remove them after running the first one: :%s/<\n\/time>/<\/time>/g Another option is to use a *nested substitution* to keep the original substitution from adding newlines in the first place. ### The `substitute()` function Vim’s `substitute()` function replaces strings and can be run from an expression in a substitution. Nested substitutions are useful for transforming the result of another function. The function (`substitute()`) works like the substitute command (`:s`), and takes the same arguments, so `substitute("input", "find", "replace", "g")` is equivalent to running `:%s/find/replace/g` in a file. The `substitute()` function works like the substitute command (`:s[ubstitute]`) in Vim’s command line and takes the same arguments. The first argument is the input, then the search pattern, the substitute string, followed by optional options. `substitute("input", "find", "replace", "g")` is equivalent to running `:%s/find/replace/g` in a file. :echom substitute("October 02, 1991", "October", "November", "") - `"October 02, 1991"`: The input string to run the substitution on. - `"October"`: The search pattern. - `"November"`: The substitute string. - `""`: Options, like in a “regular” substitution. This example doesn’t use the `g` option because we’re sure there’s only one match in the input string, so it isn’t necessary. If an external command called from a substitution returns a trailing newline (like `echo` would without the `-n` flag), we can use the `substitute()` function to take it out before the match is replaced. :%s/October/\=substitute(system('echo "November"'), "\n", "", "")/gc We wrap the call to the `date` utility in a nested substitution using the `substitute()` function. It takes the result, matches the newline (`"\n"`) and replaces it with an empty string. :%s/....-..-..</\=substitute(system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"'), "\n", "", "")/gc Now our substitution will turn the `<time>` tags into the correct format, without adding that extra newline. *The result* ```html <article> <h1>Keeping open source projects maintainable</h1> <time datetime="2017-09-19">September 19, 2017</time> </article> <article> <h1>Property-based testing in Elixir using PropEr</h1> <time datetime="2017-08-22">August 22, 2017</time> </article> <article> <h1>git is not a git command</h1> <time datetime="2015-10-01">October 01, 2015</time> </article> ... ``` -
jeffkreeftmeijer revised this gist
May 29, 2018 . 1 changed file with 1 addition and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -37,7 +37,7 @@ datetime attributes in their current format. include::archive_after.html[] ---- The input file has more than forty articles, so replacing them all by hand would be a lot of error-prone work. Instead, we write a substitution that finds all dates in the file and replaces them with a reformatted value. -
jeffkreeftmeijer revised this gist
May 29, 2018 . 3 changed files with 21 additions and 47 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 charactersOriginal file line number Diff line number Diff line change @@ -12,3 +12,5 @@ <h1>Property-based testing in Elixir using PropEr</h1> <h1>git is not a git command</h1> <time datetime="2015-10-01">2015-10-01</time> </article> ... 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ <article> <h1>Keeping open source projects maintainable</h1> <time datetime="2017-09-19">September 19, 2017</time> </article> <article> <h1>Property-based testing in Elixir using PropEr</h1> <time datetime="2017-08-22">August 22, 2017</time> </article> <article> <h1>git is not a git command</h1> <time datetime="2015-10-01">October 01, 2015</time> </article> ... 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 charactersOriginal file line number Diff line number Diff line change @@ -24,22 +24,7 @@ date. .The input file [source, html] ---- include::archive.html[] ---- We need to convert the dates`' values to a friendlier format that @@ -49,21 +34,7 @@ datetime attributes in their current format. .The result: articles with reformatted dates [source, html] ---- include::archive_after.html[] ---- The input file has more then forty articles, so replacing them all by hand @@ -361,20 +332,5 @@ without adding that extra newline. .The result ---- include::archive_after.html[] ---- -
jeffkreeftmeijer revised this gist
May 26, 2018 . 1 changed file with 3 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 charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,9 @@ Jeff Kreeftmeijer <https://jeffkreeftmeijer.com> :url: https://jeffkreeftmeijer.com/vim-reformat-dates/ :image: substitute.png :tweet_id: 920242997282840577 ifdef::env-github[] :imagesdir: https://gist.githubusercontent.com/jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e/raw endif::[] Vim's substitution command is a powerful way to make changes to text files. Besides finding and replacing text using regular expressions, substitutions can -
jeffkreeftmeijer revised this gist
May 26, 2018 . 1 changed file with 5 additions and 3 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 charactersOriginal file line number Diff line number Diff line change @@ -14,6 +14,10 @@ different format and replace them all at once. image::substitute.png["Finding, converting and replacing dates with Vim substitutions", 746, 581] The _input file_ is an HTML page with a list of articles. Each article includes a `<time>` tag with a value and a datetime attribute to show the publication date. .The input file [source, html] ---- @@ -35,9 +39,7 @@ image::substitute.png["Finding, converting and replacing dates with Vim substitu ... ---- We need to convert the dates`' values to a friendlier format that includes the full month name ("`September 19, 2017`"), while keeping the datetime attributes in their current format. -
jeffkreeftmeijer revised this gist
May 26, 2018 . 1 changed file with 1 addition and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -12,7 +12,7 @@ call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once. image::substitute.png["Finding, converting and replacing dates with Vim substitutions", 746, 581] .The input file [source, html] -
jeffkreeftmeijer revised this gist
Oct 18, 2017 . 1 changed file with 1 addition and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -12,7 +12,7 @@ call out to external programs for more complicated replacements. By using the `date` utility from a substitution, Vim can convert all dates in a file to a different format and replace them all at once. image::substitute.png["Finding, converting and replacing dates with Vim substitutions", 1490, 1162] .The input file [source, html]
NewerOlder