Skip to content

Instantly share code, notes, and snippets.

@jeffkreeftmeijer
Last active January 7, 2021 14:26
Show Gist options
  • Save jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e to your computer and use it in GitHub Desktop.
Save jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e to your computer and use it in GitHub Desktop.

Revisions

  1. jeffkreeftmeijer revised this gist Jan 7, 2021. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions vim-reformat-dates.adoc
    Original 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::[]
  2. jeffkreeftmeijer revised this gist Nov 13, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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]
    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
  3. jeffkreeftmeijer revised this gist Nov 4, 2018. 4 changed files with 0 additions and 0 deletions.
    Binary file modified substitute-dark-shadow.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file modified substitute-dark.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file modified substitute-light-shadow.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file modified substitute-light.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  4. jeffkreeftmeijer revised this gist Nov 4, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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.png
    :image: substitute-dark-shadow.png
    :tweet_id: 920242997282840577
    ifdef::env-github[]
    :imagesdir: https://gist.githubusercontent.com/jeffkreeftmeijer/b3185d5fcda90a1aca921f1cd5b07c0e/raw
  5. jeffkreeftmeijer revised this gist Nov 4, 2018. 4 changed files with 0 additions and 0 deletions.
    Binary file added substitute-dark-shadow.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file modified substitute-dark.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added substitute-light-shadow.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file modified substitute-light.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  6. jeffkreeftmeijer revised this gist Nov 3, 2018. 3 changed files with 1 addition and 1 deletion.
    Binary file modified substitute-dark.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file modified substitute-light.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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]
    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
  7. jeffkreeftmeijer revised this gist Nov 2, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions vim-reformat-dates.adoc
    Original 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
  8. jeffkreeftmeijer revised this gist Nov 2, 2018. 4 changed files with 1 addition and 1 deletion.
    Binary file added substitute-dark.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added substitute-light.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file removed substitute.png
    Binary file not shown.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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.png["Finding, converting and replacing dates with Vim substitutions", 746, 581]
    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
  9. jeffkreeftmeijer revised this gist Nov 2, 2018. 3 changed files with 213 additions and 35 deletions.
    120 changes: 104 additions & 16 deletions archive.html
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,104 @@
    <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>

    ...
    <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>
    120 changes: 104 additions & 16 deletions archive_after.html
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,104 @@
    <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>

    ...
    <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>
    8 changes: 5 additions & 3 deletions vim-reformat-dates.adoc
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,8 @@ date.
    .The input file
    [source, html]
    ----
    include::archive.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[]
    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[]
    include::archive_after.html[lines=1..19]
    ----

    [small]#_Thanks Wouter Vos and Rico Sta. Cruz for feedback on the substitution command
  10. jeffkreeftmeijer revised this gist Jun 5, 2018. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions vim-reformat-dates.adoc
    Original 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`._#
  11. jeffkreeftmeijer revised this gist Jun 5, 2018. 2 changed files with 14 additions and 3 deletions.
    9 changes: 7 additions & 2 deletions vim-reformat-dates.adoc
    Original 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

    Another option is to use a _nested substitution_ to keep the original
    substitution from adding newlines in the first place.
    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
    ****
    8 changes: 7 additions & 1 deletion vim-reformat-dates.markdown
    Original 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

    Another option is to use a *nested substitution* to keep the original substitution from adding newlines in the first place.
    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

  12. jeffkreeftmeijer revised this gist Jun 3, 2018. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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 that breaks the closing `</time>` tag
    .The current result, with an added newline before the closing `</time>` tag
    [source, html]
    ----
    <article>
    2 changes: 1 addition & 1 deletion vim-reformat-dates.markdown
    Original 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 that breaks the closing `</time>` tag
    The current result, with an added newline before the closing `</time>` tag

    ``` html
    <article>
  13. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 0 additions and 10 deletions.
    10 changes: 0 additions & 10 deletions vim-reformat-dates.markdown
    Original 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.

    ### 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/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "'.submatch(0).'" +"%B %d, %Y"')/gc
  14. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.markdown
    Original 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](#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.
    - `'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.
  15. jeffkreeftmeijer revised this gist Jun 3, 2018. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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 `1992-11-02` to `November 02,
    With these formats the `date` utility reformats `1991-11-02` to `November 02,
    1991`.

    [[date-command]]
    2 changes: 1 addition & 1 deletion vim-reformat-dates.markdown
    Original 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 `1992-11-02` to `November 02, 1991`.
    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
  16. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions vim-reformat-dates.markdown
    Original 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/....-..-..</November 2, 1991</gc
    :%s/....-..-..\ze</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
    - `....-..-..\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/....-..-..</\=system('date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"')/gc
    :%s/....-..-..\ze</\=system('date -jf "%Y-%m-%d" "1991-11-02" +"%B %d, %Y"')/gc

    - `....-..-..<`: The search pattern to find all dates in the file
    - `....-..-..\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.
    - `'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/....-..-..</\=system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"')/gc
    :%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
    :%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/....-..-..</\=substitute(system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"'), "\n", "", "")/gc
    :%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.

  17. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 32 additions and 110 deletions.
    142 changes: 32 additions & 110 deletions vim-reformat-dates.markdown
    Original 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.
    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.

    ![Finding, converting and replacing dates with Vim
    substitutions](https://jeffkreeftmeijer.com/vim-reformat-dates/substitute.png)

    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* 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.
    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.
    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.
    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.
    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.
    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.
    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 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.
    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`.
    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*.
    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:
    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.
    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:
    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.
    > ⚠️ 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.
    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.
    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.
    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.
    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.
    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
    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.
    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:
    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.
    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.
    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 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.
    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.
    - `""`: 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.
    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.
    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.
    Now our substitution will turn the `<time>` tags into the correct format, without adding that extra newline.

    *The result*

  18. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions vim-reformat-dates.markdown
    Original 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.
    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>
  19. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 19 additions and 19 deletions.
    38 changes: 19 additions & 19 deletions vim-reformat-dates.markdown
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    Find, convert and replace dates with Vim substitutions
    ======================================================

    Vims substitution command is a powerful way to make changes to text
    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
    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 patterns results will include all matching dates in the file,
    including the ones in the `<time>` tags datetime attributes.
    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 doesnt include it in the match,
    meaning it wont be replaced.
    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 months full name in the date replacements, so we cant
    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 months full name, the
    dates number, a comma and the year number.
    *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`: Dont try to set the system date
    - `-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 dates format from “1991-11-02” to “November 2,
    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 patterns matches.
    - `'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. Well remove these later while
    > `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

    Vims `submatch()` function returns matches from our pattern. If we call
    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 theres no way to get
    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

    Vims `substitute()` function replaces strings and can be run from an
    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 Vims command line and takes the same arguments.
    (`: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 doesnt use the `g` option because were sure theres only
    one match in the input string, so it isnt necessary.
    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
  20. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 22 additions and 18 deletions.
    40 changes: 22 additions & 18 deletions vim-reformat-dates.markdown
    Original 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 include the
    less-than sign in the search pattern.
    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. 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&lt;”). 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.
    (“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<`.
    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<
    $ 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<`
    - `-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
    ----------------------------------------------------
  21. jeffkreeftmeijer renamed this gist Jun 3, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  22. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions vim-reformat-dates.adoc
    Original 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 take it out later.
    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.
    sign, but doesn't include it in the match, meaning it won't be replaced.

    ....-..-..\ze<

  23. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 38 additions and 36 deletions.
    74 changes: 38 additions & 36 deletions vim-reformat-dates.adoc
    Original 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 include the less-than sign in
    the search pattern.
    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. 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.
    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<`.
    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<
    $ 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<"`::
    `-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<`.
    `+"%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/....-..-..</November 2, 1991</gc
    :%s/....-..-..\ze</November 2, 1991/gc

    `\....-..-..<`::
    `\....-..-..`::
    The <<finding-the-dates, search pattern>> to find all dates in the file.
    `November 2, 1991<`::
    `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/....-..-..</\=system('date -jf "%Y-%m-%d<" "1991-11-02<" +"%B %d, %Y<"')/gc
    :%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<"'`::
    `'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
    (`"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 in the `<time>` tag, because the
    `date` utility appends one to its output. We'll remove these later
    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/....-..-..</\=system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"')/gc
    :%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.
    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>
    <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
    :%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/....-..-..</\=substitute(system('date -jf "%Y-%m-%d<" "'.submatch(0).'" +"%B %d, %Y<"'), "\n", "", "")/gc
    :%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.
  24. jeffkreeftmeijer revised this gist Jun 3, 2018. 1 changed file with 274 additions and 0 deletions.
    274 changes: 274 additions & 0 deletions vim-reformat-dates.md
    Original 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.

    ![Finding, converting and replacing dates with Vim
    substitutions](https://jeffkreeftmeijer.com/vim-reformat-dates/substitute.png)

    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&lt;”). 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>

    ...
    ```
  25. jeffkreeftmeijer revised this gist May 29, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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 then forty articles, so replacing them all by hand
    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.

  26. jeffkreeftmeijer revised this gist May 29, 2018. 3 changed files with 21 additions and 47 deletions.
    2 changes: 2 additions & 0 deletions archive.html
    Original 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>

    ...
    16 changes: 16 additions & 0 deletions archive_after.html
    Original 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>

    ...
    50 changes: 3 additions & 47 deletions vim-reformat-dates.adoc
    Original file line number Diff line number Diff line change
    @@ -24,22 +24,7 @@ date.
    .The input file
    [source, 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>
    ...
    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]
    ----
    <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>
    ...
    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
    ----
    <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>
    ...
    include::archive_after.html[]
    ----
  27. jeffkreeftmeijer revised this gist May 26, 2018. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions vim-reformat-dates.adoc
    Original 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
  28. jeffkreeftmeijer revised this gist May 26, 2018. 1 changed file with 5 additions and 3 deletions.
    8 changes: 5 additions & 3 deletions vim-reformat-dates.adoc
    Original 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
    ...
    ----

    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. We need to convert the dates`' values to a friendlier format that
    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.

  29. jeffkreeftmeijer revised this gist May 26, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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]
    image::substitute.png["Finding, converting and replacing dates with Vim substitutions", 746, 581]

    .The input file
    [source, html]
  30. jeffkreeftmeijer revised this gist Oct 18, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vim-reformat-dates.adoc
    Original 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]
    image::substitute.png["Finding, converting and replacing dates with Vim substitutions", 1490, 1162]

    .The input file
    [source, html]