summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2022-08-12 21:33:43 +0300
committerGitHub <noreply@github.com>2022-08-12 14:33:43 -0400
commit713f39083ee37085ba24345af741e5b448fdcc05 (patch)
tree582168a3bba1123ff32aa8fab5df4c1d0ee171e9 /doc
parent8155837cde99d7d532071a2a56d95485ffb79292 (diff)
downloadNim-713f39083ee37085ba24345af741e5b448fdcc05.tar.gz
Markdown code blocks part 4 (#20189)
No logic was added, just 8 more files have been migrated.
Diffstat (limited to 'doc')
-rw-r--r--doc/docstyle.md58
-rw-r--r--doc/drnim.md16
-rw-r--r--doc/effects.txt3
-rw-r--r--doc/filters.md6
-rw-r--r--doc/hcr.md37
-rw-r--r--doc/idetools.md194
-rw-r--r--doc/intern.md111
-rw-r--r--doc/koch.md5
-rw-r--r--doc/manual_experimental.md276
9 files changed, 365 insertions, 341 deletions
diff --git a/doc/docstyle.md b/doc/docstyle.md
index df1f36dad..79f7b4e10 100644
--- a/doc/docstyle.md
+++ b/doc/docstyle.md
@@ -18,11 +18,11 @@ General Guidelines
 * (debatable) In nim sources, for links, prefer ``[link text](link.html)`` to `\`link text<link.html>\`_`:code:
   since the syntax is simpler and markdown is more common (likewise, `nim rst2html`:cmd: also supports it in ``rst`` files).
 
-.. code-block:: nim
-
+  ```nim
   proc someproc*(s: string, foo: int) =
     ## Use single backticks for inline code, e.g.: `s` or `someExpr(true)`.
     ## Use a backlash to follow with alphanumeric char: `int8`\s are great.
+  ```
 
 
 Module-level documentation
@@ -32,23 +32,24 @@ Documentation of a module is placed at the top of the module itself. Each line o
 Sometimes `##[ multiline docs containing code ]##` is preferable, see ``lib/pure/times.nim``.
 Code samples are encouraged, and should follow the general RST syntax:
 
-.. code-block:: Nim
-
+  ````Nim
   ## The `universe` module computes the answer to life, the universe, and everything.
   ##
-  ## .. code-block::
-  ##  doAssert computeAnswerString() == 42
+  ##   ```
+  ##   doAssert computeAnswerString() == 42
+  ##   ```
+  ````
 
 
 Within this top-level comment, you can indicate the authorship and copyright of the code, which will be featured in the produced documentation.
 
-.. code-block:: Nim
-
+  ```Nim
   ## This is the best module ever. It provides answers to everything!
   ##
   ## :Author: Steve McQueen
   ## :Copyright: 1965
   ##
+  ```
 
 Leave a space between the last line of top-level documentation and the beginning of Nim code (the imports, etc.).
 
@@ -57,28 +58,29 @@ Procs, Templates, Macros, Converters, and Iterators
 
 The documentation of a procedure should begin with a capital letter and should be in present tense. Variables referenced in the documentation should be surrounded by single tick marks:
 
-.. code-block:: Nim
-
+  ```Nim
   proc example1*(x: int) =
     ## Prints the value of `x`.
     echo x
+  ```
 
 Whenever an example of usage would be helpful to the user, you should include one within the documentation in RST format as below.
 
-.. code-block:: Nim
-
+  ````Nim
   proc addThree*(x, y, z: int8): int =
     ## Adds three `int8` values, treating them as unsigned and
     ## truncating the result.
     ##
-    ## .. code-block::
-    ##  # things that aren't suitable for a `runnableExamples` go in code-block:
-    ##  echo execCmdEx("git pull")
-    ##  drawOnScreen()
+    ##   ```
+    ##   # things that aren't suitable for a `runnableExamples` go in code-block:
+    ##   echo execCmdEx("git pull")
+    ##   drawOnScreen()
+    ##   ```
     runnableExamples:
       # `runnableExamples` is usually preferred to ``code-block``, when possible.
       doAssert addThree(3, 125, 6) == -122
     result = x +% y +% z
+  ````
 
 The command `nim doc`:cmd: will then correctly syntax highlight the Nim code within the documentation.
 
@@ -87,8 +89,7 @@ Types
 
 Exported types should also be documented. This documentation can also contain code samples, but those are better placed with the functions to which they refer.
 
-.. code-block:: Nim
-
+  ```Nim
   type
     NamedQueue*[T] = object ## Provides a linked data structure with names
                             ## throughout. It is named for convenience. I'm making
@@ -96,12 +97,12 @@ Exported types should also be documented. This documentation can also contain co
       name*: string ## The name of the item
       val*: T ## Its value
       next*: ref NamedQueue[T] ## The next item in the queue
+  ```
 
 
 You have some flexibility when placing the documentation:
 
-.. code-block:: Nim
-
+  ```Nim
   type
     NamedQueue*[T] = object
       ## Provides a linked data structure with names
@@ -110,11 +111,11 @@ You have some flexibility when placing the documentation:
       name*: string ## The name of the item
       val*: T ## Its value
       next*: ref NamedQueue[T] ## The next item in the queue
+  ```
 
 Make sure to place the documentation beside or within the object.
 
-.. code-block:: Nim
-
+  ```Nim
   type
     ## Bad: this documentation disappears because it annotates the `type` keyword
     ## above, not `NamedQueue`.
@@ -123,14 +124,14 @@ Make sure to place the documentation beside or within the object.
                     ## is not what we want.
       val*: T ## Its value
       next*: ref NamedQueue[T] ## The next item in the queue
+  ```
 
 Var, Let, and Const
 -------------------
 
 When declaring module-wide constants and values, documentation is encouraged. The placement of doc comments is similar to the `type` sections.
 
-.. code-block:: Nim
-
+  ```Nim
   const
     X* = 42 ## An awesome number.
     SpreadArray* = [
@@ -138,25 +139,26 @@ When declaring module-wide constants and values, documentation is encouraged. Th
       [2,3,1],
       [3,1,2],
     ] ## Doc comment for `SpreadArray`.
+  ```
 
 Placement of comments in other areas is usually allowed, but will not become part of the documentation output and should therefore be prefaced by a single hash (`#`).
 
-.. code-block:: Nim
-
+  ```Nim
   const
     BadMathVals* = [
       3.14, # pi
       2.72, # e
       0.58, # gamma
     ] ## A bunch of badly rounded values.
+  ```
 
 Nim supports Unicode in comments, so the above can be replaced with the following:
 
-.. code-block:: Nim
-
+  ```Nim
   const
     BadMathVals* = [
       3.14, # π
       2.72, # e
       0.58, # γ
     ] ## A bunch of badly rounded values (including π!).
+  ```
diff --git a/doc/drnim.md b/doc/drnim.md
index 070cd1787..036ae0d14 100644
--- a/doc/drnim.md
+++ b/doc/drnim.md
@@ -22,11 +22,11 @@ DrNim's command-line options are the same as the Nim compiler's.
 DrNim currently only checks the sections of your code that are marked
 via `staticBoundChecks: on`:
 
-.. code-block:: nim
-
+  ```nim
   {.push staticBoundChecks: on.}
   # <--- code section here ---->
   {.pop.}
+  ```
 
 DrNim currently only tries to prove array indexing or subrange checks,
 overflow errors are *not* prevented. Overflows will be checked for in
@@ -53,8 +53,7 @@ Motivating Example
 The follow example highlights what DrNim can easily do, even
 without additional annotations:
 
-.. code-block:: nim
-
+  ```nim
   {.push staticBoundChecks: on.}
 
   proc sum(a: openArray[int]): int =
@@ -64,6 +63,7 @@ without additional annotations:
   {.pop.}
 
   echo sum([1, 2, 3])
+  ```
 
 This program contains a famous "index out of bounds" bug. DrNim
 detects it and produces the following error message::
@@ -125,8 +125,7 @@ Example: insertionSort
 
 **Note**: This example does not yet work with DrNim.
 
-.. code-block:: nim
-
+  ```nim
   import std / logic
 
   proc insertionSort(a: var openArray[int]) {.
@@ -142,6 +141,7 @@ Example: insertionSort
         {.invariant: forall(j in 1..k, i in 0..<j, j == t or a[i] <= a[j]).}
         swap a[t], a[t-1]
         dec t
+  ```
 
 Unfortunately, the invariants required to prove that this code is correct take more
 code than the imperative instructions. However, this effort can be compensated
@@ -155,14 +155,14 @@ This is required, but not sufficient to describe that a `sort` operation
 was performed. For example, the same postcondition is true for this proc
 which doesn't sort at all:
 
-.. code-block:: nim
-
+  ```nim
   import std / logic
 
   proc insertionSort(a: var openArray[int]) {.
       ensures: forall(i in 1..<a.len, a[i-1] <= a[i]).} =
     # does not sort, overwrites `a`'s contents!
     for i in 0..<a.len: a[i] = i
+  ```
 
 
 
diff --git a/doc/effects.txt b/doc/effects.txt
index 158c9e9fc..df624e8b0 100644
--- a/doc/effects.txt
+++ b/doc/effects.txt
@@ -13,11 +13,12 @@ difficult is the ``newString`` proc: If it is simply wrapped, it
 should not be evaluated at compile time! On other occasions it can
 and should be evaluated:
 
-.. code-block:: nim
+  ```nim
   proc toUpper(s: string): string =
     result = newString(len(s))
     for i in 0..len(s) - 1:
       result[i] = toUpper(s[i])
+  ```
 
 No, it really can always be evaluated. The code generator should transform
 ``s = "\0\0\0..."`` back into ``s = newString(...)``.
diff --git a/doc/filters.md b/doc/filters.md
index e237744cb..cf88724be 100644
--- a/doc/filters.md
+++ b/doc/filters.md
@@ -41,10 +41,11 @@ recognize it as Nim source file).
 If we use `generateXML` code shown above and call the SCF file `xmlGen.nimf`
 In your `main.nim`:
 
-.. code-block:: nim
+  ```nim
   include "xmlGen.nimf"
   
   echo generateXML("John Smith","42")
+  ```
 
 Pipe operator
 =============
@@ -150,7 +151,7 @@ Example::
 
 The filter transforms this into:
 
-.. code-block:: nim
+  ```nim
   proc generateHTMLPage(title, currentTab, content: string,
                         tabs: openArray[string]): string =
     result = ""
@@ -173,6 +174,7 @@ The filter transforms this into:
       "    A dollar: $.\n" &
       "  </div>\n" &
       "</body>\n")
+  ```
 
 
 Each line that does not start with the meta character (ignoring leading
diff --git a/doc/hcr.md b/doc/hcr.md
index dd25e39b3..285a86282 100644
--- a/doc/hcr.md
+++ b/doc/hcr.md
@@ -26,8 +26,7 @@ code when `F9` is pressed. The important lines are marked with `#***`.
 To install SDL2 you can use `nimble install sdl2`:cmd:.
 
 
-.. code-block:: nim
-
+  ```nim
   # logic.nim
   import sdl2
 
@@ -83,10 +82,10 @@ To install SDL2 you can use `nimble install sdl2`:cmd:.
     discard renderer.fillRect(rect)
     delay(16)
     renderer.present()
+  ```
 
 
-.. code-block:: nim
-
+  ```nim
   # mymain.nim
   import logic
 
@@ -97,42 +96,44 @@ To install SDL2 you can use `nimble install sdl2`:cmd:.
     destroy()
 
   main()
+  ```
 
 
 Compile this example via:
 
-```cmd
+  ```cmd
   nim c --hotcodereloading:on mymain.nim
-```
+  ```
 
 Now start the program and KEEP it running!
 
-.. code:: cmd
+  ```cmd
   # Unix:
   mymain &
   # or Windows (click on the .exe)
   mymain.exe
   # edit
+  ```
 
 For example, change the line:
 
-```nim
+  ```nim
   discard renderer.setDrawColor(255, 128, 128, 0)
-```
+  ```
 
 into:
 
-```nim
+  ```nim
   discard renderer.setDrawColor(255, 255, 128, 0)
-```
+  ```
 
 (This will change the color of the rectangle.)
 
 Then recompile the project, but do not restart or quit the mymain.exe program!
 
-```cmd
+  ```cmd
   nim c --hotcodereloading:on mymain.nim
-```
+  ```
 
 Now give the `mymain` SDL window the focus, press F9, and watch the
 updated version of the program.
@@ -146,7 +147,7 @@ One can use the special event handlers `beforeCodeReload` and
 `afterCodeReload` to reset the state of a particular variable or to force
 the execution of certain statements:
 
-.. code-block:: Nim
+  ```Nim
   var
    settings = initTable[string, string]()
    lastReload: Time
@@ -159,6 +160,7 @@ the execution of certain statements:
   afterCodeReload:
     lastReload = now()
     resetProgramState()
+  ```
 
 On each code reload, Nim will first execute all `beforeCodeReload`:idx:
 handlers registered in the previous version of the program and then all
@@ -167,7 +169,7 @@ that any handlers appearing in modules that weren't reloaded will also be
 executed. To prevent this behavior, one can guard the code with the
 `hasModuleChanged()`:idx: API:
 
-.. code-block:: Nim
+  ```Nim
   import mydb
 
   var myCache = initTable[Key, Value]()
@@ -175,6 +177,7 @@ executed. To prevent this behavior, one can guard the code with the
   afterCodeReload:
     if hasModuleChanged(mydb):
       resetCache(myCache)
+  ```
 
 The hot code reloading is based on dynamic library hot swapping in the native
 targets and direct manipulation of the global namespace in the JavaScript
@@ -203,8 +206,7 @@ runtime demands of the example code above. An example of compiling
 ``nimhcr.nim`` and ``nimrtl.nim`` when the source dir of Nim is installed
 with choosenim follows.
 
-.. code:: console
-
+  ```console
   # Unix/MacOS
   # Make sure you are in the directory containing your .nim files
   $ cd your-source-directory
@@ -215,6 +217,7 @@ with choosenim follows.
 
   # verify that you have two files named libnimhcr and libnimrtl in your
   # source directory (.dll for Windows, .so for Unix, .dylib for MacOS)
+  ```
 
 All modules of the project will be compiled to separate dynamic link
 libraries placed in the `nimcache` directory. Please note that during
diff --git a/doc/idetools.md b/doc/idetools.md
index dcafaf45f..21a1b1e34 100644
--- a/doc/idetools.md
+++ b/doc/idetools.md
@@ -10,10 +10,7 @@
 .. contents::
 
 
-.. raw:: html
-  <blockquote><p>
-  "yes, I'm the creator" -- Araq, 2013-07-26 19:28:32.
-  </p></blockquote>
+> "yes, I'm the creator" -- Araq, 2013-07-26 19:28:32.
 
 Note: this is mostly outdated, see instead `nimsuggest <nimsuggest.html>`_
 
@@ -246,11 +243,12 @@ skConst
 | **Fourth column**: the type of the const value.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    const SOME_SEQUENCE = @[1, 2]
-    --> col 2: $MODULE.SOME_SEQUENCE
-        col 3: seq[int]
-        col 7: ""
+  ```nim
+  const SOME_SEQUENCE = @[1, 2]
+  --> col 2: $MODULE.SOME_SEQUENCE
+      col 3: seq[int]
+      col 7: ""
+  ```
 
 
 skEnumField
@@ -260,11 +258,12 @@ skEnumField
 | **Fourth column**: enum type grouping other enum fields.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    Open(filename, fmWrite)
-    --> col 2: system.FileMode.fmWrite
-        col 3: FileMode
-        col 7: ""
+  ```nim
+  Open(filename, fmWrite)
+  --> col 2: system.FileMode.fmWrite
+      col 3: FileMode
+      col 7: ""
+  ```
 
 
 skForVar
@@ -274,13 +273,14 @@ skForVar
 | **Fourth column**: type of the var.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    proc looper(filename = "tests.nim") =
-      for letter in filename:
-        echo letter
-    --> col 2: $MODULE.looper.letter
-        col 3: char
-        col 7: ""
+  ```nim
+  proc looper(filename = "tests.nim") =
+    for letter in filename:
+      echo letter
+  --> col 2: $MODULE.looper.letter
+      col 3: char
+      col 7: ""
+  ```
 
 
 skIterator, skClosureIterator
@@ -295,13 +295,14 @@ posterior instances of the iterator.
 | **Fourth column**: signature of the iterator including return type.
 | **Docstring**: docstring if available.
 
-.. code-block:: nim
-    let
-      text = "some text"
-      letters = toSeq(runes(text))
-    --> col 2: unicode.runes
-        col 3: iterator (string): Rune
-        col 7: "iterates over any unicode character of the string `s`."
+  ```nim
+  let
+    text = "some text"
+    letters = toSeq(runes(text))
+  --> col 2: unicode.runes
+      col 3: iterator (string): Rune
+      col 7: "iterates over any unicode character of the string `s`."
+  ```
 
 
 skLabel
@@ -311,13 +312,14 @@ skLabel
 | **Fourth column**: always the empty string.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    proc test(text: string) =
-      var found = -1
-      block loops:
-    --> col 2: $MODULE.test.loops
-        col 3: ""
-        col 7: ""
+  ```nim
+  proc test(text: string) =
+    var found = -1
+    block loops:
+  --> col 2: $MODULE.test.loops
+      col 3: ""
+      col 7: ""
+  ```
 
 
 skLet
@@ -327,12 +329,13 @@ skLet
 | **Fourth column**: the type of the let variable.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    let
-      text = "some text"
-    --> col 2: $MODULE.text
-        col 3: string
-        col 7: ""
+  ```nim
+  let
+    text = "some text"
+  --> col 2: $MODULE.text
+      col 3: string
+      col 7: ""
+  ```
 
 
 skMacro
@@ -347,12 +350,13 @@ posterior instances of the macro.
 | **Fourth column**: signature of the macro including return type.
 | **Docstring**: docstring if available.
 
-.. code-block:: nim
-    proc testMacro() =
-      expect(EArithmetic):
-    --> col 2: idetools_api.expect
-        col 3: proc (varargs[expr], stmt): stmt
-        col 7: ""
+  ```nim
+  proc testMacro() =
+    expect(EArithmetic):
+  --> col 2: idetools_api.expect
+      col 3: proc (varargs[expr], stmt): stmt
+      col 7: ""
+  ```
 
 
 skMethod
@@ -384,14 +388,15 @@ This may change in the future.
 | **Fourth column**: signature of the method including return type.
 | **Docstring**: docstring if available.
 
-.. code-block:: nim
-    method eval(e: PExpr): int = quit "to override!"
-    method eval(e: PLiteral): int = e.x
-    method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b)
-    echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
-    --> col 2: $MODULE.eval
-        col 3: proc (PPlusExpr): int
-        col 7: ""
+  ```nim
+  method eval(e: PExpr): int = quit "to override!"
+  method eval(e: PLiteral): int = e.x
+  method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b)
+  echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
+  --> col 2: $MODULE.eval
+      col 3: proc (PPlusExpr): int
+      col 7: ""
+  ```
 
 
 skParam
@@ -401,12 +406,13 @@ skParam
 | **Fourth column**: the type of the parameter.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    proc reader(filename = "tests.nim") =
-      let text = readFile(filename)
-    --> col 2: $MODULE.reader.filename
-        col 3: string
-        col 7: ""
+  ```nim
+  proc reader(filename = "tests.nim") =
+    let text = readFile(filename)
+  --> col 2: $MODULE.reader.filename
+      col 3: string
+      col 7: ""
+  ```
 
 
 skProc
@@ -425,15 +431,16 @@ returned by idetools returns also the pragmas for the proc.
 | **Fourth column**: signature of the proc including return type.
 | **Docstring**: docstring if available.
 
-.. code-block:: nim
-    open(filename, fmWrite)
-    --> col 2: system.Open
-        col 3: proc (var File, string, FileMode, int): bool
-        col 7:
-    "Opens a file named `filename` with given `mode`.
+  ```nim
+  open(filename, fmWrite)
+  --> col 2: system.Open
+      col 3: proc (var File, string, FileMode, int): bool
+      col 7:
+  "Opens a file named `filename` with given `mode`.
 
-     Default mode is readonly. Returns true iff the file could be opened.
-     This throws no exception if the file could not be opened."
+   Default mode is readonly. Returns true iff the file could be opened.
+   This throws no exception if the file could not be opened."
+  ```
 
 
 skResult
@@ -443,12 +450,13 @@ skResult
 | **Fourth column**: the type of the result.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    proc getRandomValue() : int =
-      return 4
-    --> col 2: $MODULE.getRandomValue.result
-        col 3: int
-        col 7: ""
+  ```nim
+  proc getRandomValue() : int =
+    return 4
+  --> col 2: $MODULE.getRandomValue.result
+      col 3: int
+      col 7: ""
+  ```
 
 
 skTemplate
@@ -463,7 +471,7 @@ posterior instances of the template.
 | **Fourth column**: signature of the template including return type.
 | **Docstring**: docstring if available.
 
-.. code-block:: nim
+  `````nim
     let
       text = "some text"
       letters = toSeq(runes(text))
@@ -474,13 +482,15 @@ posterior instances of the template.
 
      Example:
 
-     .. code-block:: nim
+       ```nim
        let
          numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
          odd_numbers = toSeq(filter(numeric) do (x: int) -> bool:
            if x mod 2 == 1:
              result = true)
        assert odd_numbers == @[1, 3, 5, 7, 9]"
+       ```
+  `````
 
 
 skType
@@ -490,12 +500,13 @@ skType
 | **Fourth column**: the type.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    proc writeTempFile() =
-      var output: File
-    --> col 2: system.File
-        col 3: File
-        col 7: ""
+  ```nim
+  proc writeTempFile() =
+    var output: File
+  --> col 2: system.File
+      col 3: File
+      col 7: ""
+  ```
 
 
 skVar
@@ -505,14 +516,15 @@ skVar
 | **Fourth column**: the type of the var.
 | **Docstring**: always the empty string.
 
-.. code-block:: nim
-    proc writeTempFile() =
-      var output: File
-      output.open("/tmp/somefile", fmWrite)
-      output.write("test")
-    --> col 2: $MODULE.writeTempFile.output
-        col 3: File
-        col 7: ""
+  ```nim
+  proc writeTempFile() =
+    var output: File
+    output.open("/tmp/somefile", fmWrite)
+    output.write("test")
+  --> col 2: $MODULE.writeTempFile.output
+      col 3: File
+      col 7: ""
+  ```
 
 
 Test suite
diff --git a/doc/intern.md b/doc/intern.md
index 9c883ed34..61b97f85e 100644
--- a/doc/intern.md
+++ b/doc/intern.md
@@ -42,25 +42,25 @@ Bootstrapping the compiler
 
 Compiling the compiler is a simple matter of running:
 
-.. code:: cmd
-
+  ```cmd
   nim c koch.nim
   koch boot -d:release
+  ```
 
 For a debug version use:
 
-.. code:: cmd
-
+  ```cmd
   nim c koch.nim
   koch boot
+  ```
 
 
 And for a debug version compatible with GDB:
 
-.. code:: cmd
-
+  ```cmd
   nim c koch.nim
   koch boot --debuginfo --linedir:on
+  ```
 
 The `koch`:cmd: program is Nim's maintenance script. It is a replacement for
 make and shell scripting with the advantage that it is much more portable.
@@ -73,10 +73,10 @@ Reproducible builds
 
 Set the compilation timestamp with the `SOURCE_DATE_EPOCH` environment variable.
 
-.. code:: cmd
-
+  ```cmd
   export SOURCE_DATE_EPOCH=$(git log -n 1 --format=%at)
   koch boot # or `./build_all.sh`
+  ```
 
 
 Debugging the compiler
@@ -98,10 +98,10 @@ focus on the changes introduced by that one specific commit.
 compilation fails. This exit code tells `git bisect`:cmd: to skip the
 current commit:
 
-.. code:: cmd
-
+  ```cmd
   git bisect start bad-commit good-commit
   git bisect run ./koch temp -r c test-source.nim
+  ```
 
 You can also bisect using custom options to build the compiler, for example if
 you don't need a debug version of the compiler (which runs slower), you can replace
@@ -141,8 +141,7 @@ enabled. Here are compiler options that are of interest when debugging:
 
 Another method to build and run the compiler is directly through `koch`:cmd:\:
 
-.. code:: cmd
-
+  ```cmd
   koch temp [options] c test.nim
 
   # (will build with js support)
@@ -150,6 +149,7 @@ Another method to build and run the compiler is directly through `koch`:cmd:\:
 
   # (will build with doc support)
   koch temp [options] doc test.nim
+  ```
 
 Debug logging
 -------------
@@ -166,17 +166,16 @@ is being used. One very common way to achieve this is to use the `mdbg` conditio
 which will be true only in contexts, processing expressions and statements from
 the currently compiled main module:
 
-.. code-block:: nim
-
+  ```nim
   # inside some compiler module
   if mdbg:
     debug someAstNode
+  ```
 
 Using the `isCompilerDebug`:nim: condition along with inserting some statements
 into the testcase provides more granular logging:
 
-.. code-block:: nim
-
+  ```nim
   # compilermodule.nim
   if isCompilerDebug():
     debug someAstNode
@@ -186,21 +185,21 @@ into the testcase provides more granular logging:
     {.define(nimCompilerDebug).}
     let a = 2.5 * 3
     {.undef(nimCompilerDebug).}
+  ```
 
 Logging can also be scoped to a specific filename as well. This will of course
 match against every module with that name.
 
-.. code-block:: nim
-
+  ```nim
   if `??`(conf, n.info, "module.nim"):
     debug(n)
+  ```
 
 The above examples also makes use of the `debug`:nim: proc, which is able to
 print a human-readable form of an arbitrary AST tree. Other common ways to print
 information about the internal compiler types include:
 
-.. code-block:: nim
-
+  ```nim
   # pretty print PNode
 
   # pretty prints the Nim ast
@@ -246,23 +245,24 @@ information about the internal compiler types include:
 
   # print the structure of any type
   repr(someVar)
+  ```
 
 Here are some other helpful utilities:
 
-.. code-block:: nim
-
+  ```nim
   # how did execution reach this location?
   writeStackTrace()
+  ```
 
 These procs may not already be imported by the module you're editing.
 You can import them directly for debugging:
 
-.. code-block:: nim
-
+  ```nim
   from astalgo import debug
   from types import typeToString
   from renderer import renderTree
   from msgs import `??`
+  ```
 
 Native debugging
 ----------------
@@ -280,12 +280,12 @@ and `exitingDebugSection()`:nim:.
    * LLDB execute `command source tools/compiler.lldb` at startup
 #. Use one of the scoping helpers like so:
 
-.. code-block:: nim
-
+  ```nim
   if isCompilerDebug():
     enteringDebugSection()
   else:
     exitingDebugSection()
+  ```
 
 A caveat of this method is that all breakpoints and watchpoints are enabled or
 disabled. Also, due to a bug, only breakpoints can be constrained for LLDB.
@@ -448,8 +448,9 @@ Tests with GCC on Amd64 showed that it's really beneficial if the
 Proper thunk generation is harder because the proc that is to wrap
 could stem from a complex expression:
 
-.. code-block:: nim
+  ```nim
   receivesClosure(returnsDefaultCC[i])
+  ```
 
 A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require
 an *additional* closure generation... Ok, not really, but it requires to pass
@@ -460,17 +461,18 @@ to pass a proc pointer around via a generic `ref` type.
 
 Example code:
 
-.. code-block:: nim
+  ```nim
   proc add(x: int): proc (y: int): int {.closure.} =
     return proc (y: int): int =
       return x + y
 
   var add2 = add(2)
   echo add2(5) #OUT 7
+  ```
 
 This should produce roughly this code:
 
-.. code-block:: nim
+  ```nim
   type
     Env = ref object
       x: int # data
@@ -487,11 +489,12 @@ This should produce roughly this code:
   var add2 = add(2)
   let tmp = if add2.data == nil: add2.prc(5) else: add2.prc(5, add2.data)
   echo tmp
+  ```
 
 
 Beware of nesting:
 
-.. code-block:: nim
+  ```nim
   proc add(x: int): proc (y: int): proc (z: int): int {.closure.} {.closure.} =
     return lambda (y: int): proc (z: int): int {.closure.} =
       return lambda (z: int): int =
@@ -499,10 +502,11 @@ Beware of nesting:
 
   var add24 = add(2)(4)
   echo add24(5) #OUT 11
+  ```
 
 This should produce roughly this code:
 
-.. code-block:: nim
+  ```nim
   type
     EnvX = ref object
       x: int # data
@@ -530,6 +534,7 @@ This should produce roughly this code:
   var tmp2 = tmp.fn(4, tmp.data)
   var add24 = tmp2.fn(4, tmp2.data)
   echo add24(5)
+  ```
 
 
 We could get rid of nesting environments by always inlining inner anon procs.
@@ -540,8 +545,7 @@ however.
 Accumulator
 -----------
 
-.. code-block:: nim
-
+  ```nim
   proc getAccumulator(start: int): proc (): int {.closure} =
     var i = start
     return lambda: int =
@@ -560,6 +564,7 @@ Accumulator
     var a = accumulator(3)
     var b = accumulator(4)
     echo a() + b()
+  ```
 
 
 Internals
@@ -614,36 +619,36 @@ keeps the full `int literal(321)` type. Here is an example where that
 difference matters.
 
 
-.. code-block:: nim
+  ```nim
+  proc foo(arg: int8) =
+    echo "def"
 
-   proc foo(arg: int8) =
-     echo "def"
+  const tmp1 = 123
+  foo(tmp1)  # OK
 
-   const tmp1 = 123
-   foo(tmp1)  # OK
-
-   let tmp2 = 123
-   foo(tmp2) # Error
+  let tmp2 = 123
+  foo(tmp2) # Error
+  ```
 
 In a context with multiple overloads, the integer literal kind will
 always prefer the `int` type over all other types. If none of the
 overloads is of type `int`, then there will be an error because of
 ambiguity.
 
-.. code-block:: nim
-
-   proc foo(arg: int) =
-     echo "abc"
-   proc foo(arg: int8) =
-     echo "def"
-   foo(123) # output: abc
+  ```nim
+  proc foo(arg: int) =
+    echo "abc"
+  proc foo(arg: int8) =
+    echo "def"
+  foo(123) # output: abc
 
-   proc bar(arg: int16) =
-     echo "abc"
-   proc bar(arg: int8) =
-     echo "def"
+  proc bar(arg: int16) =
+    echo "abc"
+  proc bar(arg: int8) =
+    echo "def"
 
-   bar(123) # Error ambiguous call
+  bar(123) # Error ambiguous call
+  ```
 
 In the compiler these integer literal types are represented with the
 node kind `nkIntLit`, type kind `tyInt` and the member `n` of the type
diff --git a/doc/koch.md b/doc/koch.md
index 91dd5d570..2454ac2f4 100644
--- a/doc/koch.md
+++ b/doc/koch.md
@@ -8,10 +8,7 @@
 .. include:: rstcommon.rst
 .. contents::
 
-.. raw:: html
-  <blockquote><p>
-  "A great chef is an artist that I truly respect" -- Robert Stack.
-  </p></blockquote>
+> "A great chef is an artist that I truly respect" -- Robert Stack.
 
 
 Introduction
diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md
index 81d4cc51e..f584c8905 100644
--- a/doc/manual_experimental.md
+++ b/doc/manual_experimental.md
@@ -30,17 +30,16 @@ The `void` type denotes the absence of any type. Parameters of
 type `void` are treated as non-existent, `void` as a return type means that
 the procedure does not return a value:
 
-.. code-block:: nim
-
+  ```nim
   proc nothing(x, y: void): void =
     echo "ha"
 
   nothing() # writes "ha" to stdout
+  ```
 
 The `void` type is particularly useful for generic code:
 
-.. code-block:: nim
-
+  ```nim
   proc callProc[T](p: proc (x: T), x: T) =
     when T is void:
       p()
@@ -52,15 +51,16 @@ The `void` type is particularly useful for generic code:
 
   callProc[int](intProc, 12)
   callProc[void](emptyProc)
+  ```
 
 However, a `void` type cannot be inferred in generic code:
 
-.. code-block:: nim
-
+  ```nim
   callProc(emptyProc)
   # Error: type mismatch: got (proc ())
   # but expected one of:
   # callProc(p: proc (T), x: T)
+  ```
 
 The `void` type is only valid for parameters and return types; other symbols
 cannot have the type `void`.
@@ -97,9 +97,7 @@ to a choice between `T.foo` and `U.foo`. During overload resolution,
 the correct type of `foo` is decided from the context. If the type of `foo` is
 ambiguous, a static error will be produced.
 
-.. code-block:: nim
-    :test: "nim c $1"
-
+  ```nim  test = "nim c $1"
   {.experimental: "overloadableEnums".}
 
   type
@@ -124,6 +122,7 @@ ambiguous, a static error will be produced.
     of value2: echo "B"
 
   p value2
+  ```
 
 
 Package level objects
@@ -144,8 +143,7 @@ available.
 
 Example:
 
-.. code-block:: nim
-
+  ```nim
   # module A (in an arbitrary package)
   type
     Pack.SomeObject = object # declare as incomplete object of package 'Pack'
@@ -154,15 +152,16 @@ Example:
 
   # Incomplete objects can be used as parameters:
   proc myproc(x: SomeObject) = discard
+  ```
 
 
-.. code-block:: nim
-
+  ```nim
   # module B (in package "Pack")
   type
     SomeObject* {.package.} = object # Use 'package' to complete the object
       s, t: string
       x, y: int
+  ```
 
 This feature will likely be superseded in the future by support for
 recursive module dependencies.
@@ -223,8 +222,7 @@ preface definitions inside a module.
 
 Example:
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "codeReordering".}
 
   proc foo(x: int) =
@@ -234,14 +232,14 @@ Example:
     echo(x)
 
   foo(10)
+  ```
 
 Variables can also be reordered as well. Variables that are *initialized* (i.e.
 variables that have their declaration and assignment combined in a single
 statement) can have their entire initialization statement reordered. Be wary of
 what code is executed at the top level:
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "codeReordering".}
 
   proc a() =
@@ -250,6 +248,7 @@ what code is executed at the top level:
   var foo = 5
 
   a() # outputs: "5"
+  ```
 
 ..
    TODO: Let's table this for now. This is an *experimental feature* and so the
@@ -260,8 +259,7 @@ what code is executed at the top level:
    code reordering process, and not after. As an example, the output of this
    code is the same as it would be with code reordering disabled.
 
-   .. code-block:: nim
-
+     ```nim
      {.experimental: "codeReordering".}
 
      proc x() =
@@ -270,12 +268,12 @@ what code is executed at the top level:
      var foo = 4
 
      x() # "false"
+     ```
 
 It is important to note that reordering *only* works for symbols at top level
 scope. Therefore, the following will *fail to compile:*
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "codeReordering".}
 
   proc a() =
@@ -284,6 +282,7 @@ scope. Therefore, the following will *fail to compile:*
       echo("Hello!")
 
   a()
+  ```
 
 This feature will likely be replaced with a better solution to remove
 the need for forward declarations.
@@ -295,8 +294,7 @@ Automatic dereferencing
 Automatic dereferencing is performed for the first argument of a routine call.
 This feature has to be enabled via `{.experimental: "implicitDeref".}`:
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "implicitDeref".}
 
   type
@@ -309,6 +307,7 @@ This feature has to be enabled via `{.experimental: "implicitDeref".}`:
   let n = Node()
   echo n.depth
   # no need to write n[].depth
+  ```
 
 
 Special Operators
@@ -333,21 +332,21 @@ for a dot operator that can be matched against a re-written form of
 the expression, where the unknown field or proc name is passed to
 an `untyped` parameter:
 
-.. code-block:: nim
-
+  ```nim
   a.b # becomes `.`(a, b)
   a.b(c, d) # becomes `.`(a, b, c, d)
+  ```
 
 The matched dot operators can be symbols of any callable kind (procs,
 templates and macros), depending on the desired effect:
 
-.. code-block:: nim
-
+  ```nim
   template `.`(js: PJsonNode, field: untyped): JSON = js[astToStr(field)]
 
   var js = parseJson("{ x: 1, y: 2}")
   echo js.x # outputs 1
   echo js.y # outputs 2
+  ```
 
 The following dot operators are available:
 
@@ -366,9 +365,9 @@ operator `.=`
 -------------
 This operator will be matched against assignments to missing fields.
 
-.. code-block:: nim
-
+  ```nim
   a.b = c # becomes `.=`(a, b, c)
+  ```
 
 Call operator
 -------------
@@ -377,8 +376,7 @@ precedence over dot operators, however it does not match missing overloads
 for existing routines. The experimental `callOperator` switch must be enabled
 to use this operator.
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "callOperator".}
 
   template `()`(a: int, b: float): untyped = $(a, b)
@@ -402,6 +400,7 @@ to use this operator.
 
     doAssert not compiles(a.b(c)) # gives a type mismatch error same as b(a, c)
     doAssert (a.b)(c) == `()`(a.b, c)
+  ```
 
 
 Extended macro pragmas
@@ -412,9 +411,10 @@ can also be applied to type, variable and constant declarations.
 
 For types:
 
-.. code-block:: nim
+  ```nim
   type
     MyObject {.schema: "schema.protobuf".} = object
+  ```
 
 This is translated to a call to the `schema` macro with a `nnkTypeDef`
 AST node capturing the left-hand side, remaining pragmas and the right-hand
@@ -437,19 +437,21 @@ For variables and constants, it is largely the same, except a unary node with
 the same kind as the section containing a single definition is passed to macros,
 and macros can return any expression.
 
-.. code-block:: nim
+  ```nim
   var
     a = ...
     b {.importc, foo, nodecl.} = ...
     c = ...
+  ```
 
 Assuming `foo` is a macro or a template, this is roughly equivalent to:
 
-.. code-block:: nim
+  ```nim
   var a = ...
   foo:
     var b {.importc, nodecl.} = ...
   var c = ...
+  ```
 
 
 Symbols as template/macro calls
@@ -459,7 +461,7 @@ Templates and macros that take no arguments can be called as lone symbols,
 i.e. without parentheses. This is useful for repeated uses of complex
 expressions that cannot conveniently be represented as runtime values.
 
-.. code-block:: nim
+  ```nim
   type Foo = object
     bar: int
   
@@ -468,6 +470,7 @@ expressions that cannot conveniently be represented as runtime values.
   assert bar == 10
   bar = 15
   assert bar == 15
+  ```
 
 In the future, this may require more specific information on template or macro
 signatures to be used. Specializations for some applications of this may also
@@ -483,8 +486,7 @@ Not nil annotation
 All types for which `nil` is a valid value can be annotated with the
 `not nil` annotation to exclude `nil` as a valid value:
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "notnil".}
 
   type
@@ -500,6 +502,7 @@ All types for which `nil` is a valid value can be annotated with the
   # and also this:
   var x: PObject
   p(x)
+  ```
 
 The compiler ensures that every code path initializes variables which contain
 non-nilable pointers. The details of this analysis are still to be specified
@@ -545,8 +548,7 @@ via a parameter that is not declared as a `var` parameter.
 
 For example:
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "strictFuncs".}
 
   type
@@ -566,6 +568,7 @@ For example:
     m.data = "yeah" # the mutation is here
     # Error: 'mut' can have side effects
     # an object reachable from 'n' is potentially mutated
+  ```
 
 
 The algorithm behind this analysis is described in
@@ -585,23 +588,23 @@ A view type is a type that is or contains one of the following types:
 
 For example:
 
-.. code-block:: nim
-
+  ```nim
   type
     View1 = openArray[byte]
     View2 = lent string
     View3 = Table[openArray[char], int]
+  ```
 
 
 Exceptions to this rule are types constructed via `ptr` or `proc`.
 For example, the following types are **not** view types:
 
-.. code-block:: nim
-
+  ```nim
   type
     NotView1 = proc (x: openArray[int])
     NotView2 = ptr openArray[char]
     NotView3 = ptr array[4, lent int]
+  ```
 
 
 The mutability aspect of a view type is not part of the type but part
@@ -618,8 +621,7 @@ it was borrowed from.
 
 For example:
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "views".}
 
   proc take(a: openArray[int]) =
@@ -641,6 +643,7 @@ For example:
 
 
   main(@[11, 22, 33])
+  ```
 
 
 A local variable of a view type can borrow from a location
@@ -699,8 +702,7 @@ For the duration of the borrow operation, no mutations to the borrowed locations
 may be performed except via the view that borrowed from the
 location. The borrowed location is said to be *sealed* during the borrow.
 
-.. code-block:: nim
-
+  ```nim
   {.experimental: "views".}
 
   type
@@ -711,16 +713,17 @@ location. The borrowed location is said to be *sealed* during the borrow.
     let v: lent Obj = s[0] # seal 's'
     s.setLen 0  # prevented at compile-time because 's' is sealed.
     echo v.field
+  ```
 
 
 The scope of the view does not matter:
 
-.. code-block:: nim
-
+  ```nim
   proc valid(s: var seq[Obj]) =
     let v: lent Obj = s[0]  # begin of borrow
     echo v.field            # end of borrow
     s.setLen 0  # valid because 'v' isn't used afterwards
+  ```
 
 
 The analysis requires as much precision about mutations as is reasonably obtainable,
@@ -730,13 +733,13 @@ with `--experimental:strictFuncs`:option:.
 
 The analysis is currently control flow insensitive:
 
-.. code-block:: nim
-
+  ```nim
   proc invalid(s: var seq[Obj]) =
     let v: lent Obj = s[0]
     if false:
       s.setLen 0
     echo v.field
+  ```
 
 In this example, the compiler assumes that `s.setLen 0` invalidates the
 borrow operation of `v` even though a human being can easily see that it
@@ -824,8 +827,7 @@ arbitrary set of requirements that the matched type must satisfy.
 
 Concepts are written in the following form:
 
-.. code-block:: nim
-
+  ```nim
   type
     Comparable = concept x, y
       (x < y) is bool
@@ -838,6 +840,7 @@ Concepts are written in the following form:
 
       for value in s:
         value is T
+  ```
 
 The concept matches if:
 
@@ -850,29 +853,28 @@ as `var`, `ref`, `ptr` and `static` to denote a more specific type of
 instance. You can also apply the `type` modifier to create a named instance of
 the type itself:
 
-.. code-block:: nim
-
+  ```nim
   type
     MyConcept = concept x, var v, ref r, ptr p, static s, type T
       ...
+  ```
 
 Within the concept body, types can appear in positions where ordinary values
 and parameters are expected. This provides a more convenient way to check for
 the presence of callable symbols with specific signatures:
 
-.. code-block:: nim
-
+  ```nim
   type
     OutputStream = concept var s
       s.write(string)
+  ```
 
 In order to check for symbols accepting `type` params, you must prefix
 the type with the explicit `type` modifier. The named instance of the
 type, following the `concept` keyword is also considered to have the
 explicit modifier and will be matched only as a type.
 
-.. code-block:: nim
-
+  ```nim
   type
     # Let's imagine a user-defined casting framework with operators
     # such as `val.to(string)` and `val.to(JSonValue)`. We can test
@@ -890,6 +892,7 @@ explicit modifier and will be matched only as a type.
       x is AdditiveMonoid
       -x is T
       x - y is T
+  ```
 
 Please note that the `is` operator allows one to easily verify the precise
 type signatures of the required operations, but since type inference and
@@ -909,12 +912,12 @@ When you need to understand why the compiler is not matching a particular
 concept and, as a result, a wrong overload is selected, you can apply the
 `explain` pragma to either the concept body or a particular call-site.
 
-.. code-block:: nim
-
+  ```nim
   type
     MyConcept {.explain.} = concept ...
 
   overloadedProc(x, y, z) {.explain.}
+  ```
 
 This will provide Hints in the compiler output either every time the concept is
 not matched or only on the particular call-site.
@@ -925,8 +928,7 @@ Generic concepts and type binding rules
 
 The concept types can be parametric just like the regular generic types:
 
-.. code-block:: nim
-
+  ```nim
   ### matrixalgo.nim
 
   import std/typetraits
@@ -986,6 +988,7 @@ The concept types can be parametric just like the regular generic types:
 
   echo m.transposed.determinant
   setPerspectiveProjection projectionMatrix
+  ```
 
 When the concept type is matched against a concrete type, the unbound type
 parameters are inferred from the body of the concept in a way that closely
@@ -999,11 +1002,11 @@ and `x.data is seq[T]`.
 Unbound static params will be inferred from expressions involving the `==`
 operator and also when types dependent on them are being matched:
 
-.. code-block:: nim
-
+  ```nim
   type
     MatrixReducer[M, N: static int; T] = concept x
       x.reduce(SquareMatrix[N, T]) is array[M, int]
+  ```
 
 The Nim compiler includes a simple linear equation solver, allowing it to
 infer static params in some situations where integer arithmetic is involved.
@@ -1014,8 +1017,7 @@ modifier to any of the otherwise inferable types to get a type that will be
 matched without permanently inferring it. This may be useful when you need
 to match several procs accepting the same wide class of types:
 
-.. code-block:: nim
-
+  ```nim
   type
     Enumerable[T] = concept e
       for v in e:
@@ -1032,13 +1034,13 @@ to match several procs accepting the same wide class of types:
       # it's also possible to give an alias name to a `bind many` type class
       type Enum = distinct Enumerable
       o.baz is Enum
+  ```
 
 On the other hand, using `bind once` types allows you to test for equivalent
 types used in multiple signatures, without actually requiring any concrete
 types, thus allowing you to encode implementation-defined types:
 
-.. code-block:: nim
-
+  ```nim
   type
     MyConcept = concept x
       type T1 = auto
@@ -1049,6 +1051,7 @@ types, thus allowing you to encode implementation-defined types:
       x.alpha(T2)
       x.omega(T2) # both procs must accept the same type
                   # and it must be a numeric sequence
+  ```
 
 As seen in the previous examples, you can refer to generic concepts such as
 `Enumerable[T]` just by their short name. Much like the regular generic types,
@@ -1066,9 +1069,7 @@ in any required way. For example, here is how one might define the classic
 `Functor` concept from Haskell and then demonstrate that Nim's `Option[T]`
 type is an instance of it:
 
-.. code-block:: nim
-    :test: "nim c $1"
-
+  ```nim  test = "nim c $1"
   import std/[sugar, typetraits]
 
   type
@@ -1089,6 +1090,7 @@ type is an instance of it:
 
   import std/options
   echo Option[int] is Functor # prints true
+  ```
 
 
 Concept derived values
@@ -1098,8 +1100,7 @@ All top level constants or types appearing within the concept body are
 accessible through the dot operator in procs where the concept was successfully
 matched to a concrete type:
 
-.. code-block:: nim
-
+  ```nim
   type
     DateTime = concept t1, t2, type T
       const Min = T.MinDate
@@ -1121,6 +1122,7 @@ matched to a concrete type:
 
       deviation: float
     ...
+  ```
 
 
 Concept refinement
@@ -1133,8 +1135,7 @@ overload resolution, Nim will assign a higher precedence to the most specific
 one. As an alternative way of defining concept refinements, you can use the
 object inheritance syntax involving the `of` keyword:
 
-.. code-block:: nim
-
+  ```nim
   type
     Graph = concept g, type G of EquallyComparable, Copyable
       type
@@ -1168,6 +1169,7 @@ object inheritance syntax involving the `of` keyword:
   proc f(g: IncidendeGraph)
   proc f(g: BidirectionalGraph) # this one will be preferred if we pass a type
                                 # matching the BidirectionalGraph concept
+  ```
 
 ..
   Converter type classes
@@ -1177,8 +1179,7 @@ object inheritance syntax involving the `of` keyword:
   a small set of simpler types. This is achieved with a `return` statement within
   the concept body:
 
-  .. code-block:: nim
-
+    ```nim
     type
       Stringable = concept x
         $x is string
@@ -1202,6 +1203,7 @@ object inheritance syntax involving the `of` keyword:
     # the same call at the cost of additional instantiations
     # the varargs param will be converted to a tuple
     proc log(format: static string, varargs[distinct StringRef])
+    ```
 
 
 ..
@@ -1229,8 +1231,7 @@ object inheritance syntax involving the `of` keyword:
   a converter type class, which converts the regular instances of the matching
   types to the corresponding VTable type.
 
-  .. code-block:: nim
-
+    ```nim
     type
       IntEnumerable = vtref Enumerable[int]
 
@@ -1243,6 +1244,7 @@ object inheritance syntax involving the `of` keyword:
 
     proc addStream(o: var MyObject, e: OutputStream.vtref) =
       o.streams.add e
+    ```
 
   The procs that will be included in the vtable are derived from the concept
   body and include all proc calls for which all param types were specified as
@@ -1272,9 +1274,9 @@ object inheritance syntax involving the `of` keyword:
 
   The signature has to be:
 
-  .. code-block:: nim
-
+    ```nim
     proc `=deepCopy`(x: T): T
+    ```
 
   This mechanism will be used by most data structures that support shared memory,
   like channels, to implement thread safe automatic memory management.
@@ -1289,7 +1291,7 @@ Dynamic arguments for bindSym
 This experimental feature allows the symbol name argument of `macros.bindSym`
 to be computed dynamically.
 
-.. code-block:: nim
+  ```nim
   {.experimental: "dynamicBindSym".}
 
   import macros
@@ -1299,6 +1301,7 @@ to be computed dynamically.
 
   echo callOp("+", 1, 2)
   echo callOp("-", 5, 4)
+  ```
 
 
 Term rewriting macros
@@ -1309,12 +1312,12 @@ a *name* but also a *pattern* that is searched for after the semantic checking
 phase of the compiler: This means they provide an easy way to enhance the
 compilation pipeline with user defined optimizations:
 
-.. code-block:: nim
-
+  ```nim
   template optMul{`*`(a, 2)}(a: int): int = a + a
 
   let x = 3
   echo x * 2
+  ```
 
 The compiler now rewrites `x * 2` as `x + x`. The code inside the
 curly brackets is the pattern to match against. The operators `*`,  `**`,
@@ -1332,8 +1335,7 @@ Once this limit has been passed, the term rewriting macro will be ignored.
 Unfortunately optimizations are hard to get right and even this tiny example
 is **wrong**:
 
-.. code-block:: nim
-
+  ```nim
   template optMul{`*`(a, 2)}(a: int): int = a + a
 
   proc f(): int =
@@ -1341,12 +1343,12 @@ is **wrong**:
     result = 55
 
   echo f() * 2
+  ```
 
 We cannot duplicate 'a' if it denotes an expression that has a side effect!
 Fortunately Nim supports side effect analysis:
 
-.. code-block:: nim
-
+  ```nim
   template optMul{`*`(a, 2)}(a: int{noSideEffect}): int = a + a
 
   proc f(): int =
@@ -1354,6 +1356,7 @@ Fortunately Nim supports side effect analysis:
     result = 55
 
   echo f() * 2 # not optimized ;-)
+  ```
 
 You can make one overload matching with a constraint and one without, and the
 one with a constraint will have precedence, and so you can handle both cases
@@ -1363,15 +1366,15 @@ So what about `2 * a`? We should tell the compiler `*` is commutative. We
 cannot really do that however as the following code only swaps arguments
 blindly:
 
-.. code-block:: nim
-
+  ```nim
   template mulIsCommutative{`*`(a, b)}(a, b: int): int = b * a
+  ```
 
 What optimizers really need to do is a *canonicalization*:
 
-.. code-block:: nim
-
+  ```nim
   template canonMul{`*`(a, b)}(a: int{lit}, b: int): int = b * a
+  ```
 
 The `int{lit}` parameter pattern matches against an expression of
 type `int`, but only if it's a literal.
@@ -1429,17 +1432,16 @@ The `alias` and `noalias` predicates refer not only to the matching AST,
 but also to every other bound parameter; syntactically they need to occur after
 the ordinary AST predicates:
 
-.. code-block:: nim
-
+  ```nim
   template ex{a = b + c}(a: int{noalias}, b, c: int) =
     # this transformation is only valid if 'b' and 'c' do not alias 'a':
     a = b
     inc a, c
+  ```
 
 Another example:
 
-.. code-block:: nim
-
+  ```nim
   proc somefunc(s: string)                 = assert s == "variable"
   proc somefunc(s: string{nkStrLit})       = assert s == "literal"
   proc somefunc(s: string{nkRStrLit})      = assert s == r"raw"
@@ -1454,6 +1456,7 @@ Another example:
   somefunc("literal")
   somefunc(r"raw")
   somefunc("""triple""")
+  ```
 
 
 Pattern operators
@@ -1467,21 +1470,21 @@ if they are written in infix notation.
 
 The `|` operator if used as infix operator creates an ordered choice:
 
-.. code-block:: nim
-
+  ```nim
   template t{0|1}(): untyped = 3
   let a = 1
   # outputs 3:
   echo a
+  ```
 
 The matching is performed after the compiler performed some optimizations like
 constant folding, so the following does not work:
 
-.. code-block:: nim
-
+  ```nim
   template t{0|1}(): untyped = 3
   # outputs 1:
   echo 1
+  ```
 
 The reason is that the compiler already transformed the 1 into "1" for
 the `echo` statement. However, a term rewriting macro should not change the
@@ -1494,20 +1497,19 @@ command line option or temporarily with the `patterns` pragma.
 A pattern expression can be bound to a pattern parameter via the `expr{param}`
 notation:
 
-.. code-block:: nim
-
+  ```nim
   template t{(0|1|2){x}}(x: untyped): untyped = x + 1
   let a = 1
   # outputs 2:
   echo a
+  ```
 
 
 ### The `~` operator
 
 The `~` operator is the 'not' operator in patterns:
 
-.. code-block:: nim
-
+  ```nim
   template t{x = (~x){y} and (~x){z}}(x, y, z: bool) =
     x = y
     if x: x = z
@@ -1518,6 +1520,7 @@ The `~` operator is the 'not' operator in patterns:
     c = false
   a = b and c
   echo a
+  ```
 
 
 ### The `*` operator
@@ -1525,8 +1528,7 @@ The `~` operator is the 'not' operator in patterns:
 The `*` operator can *flatten* a nested binary expression like `a & b & c`
 to `&(a, b, c)`:
 
-.. code-block:: nim
-
+  ```nim
   var
     calls = 0
 
@@ -1542,6 +1544,7 @@ to `&(a, b, c)`:
 
   # check that it's been optimized properly:
   doAssert calls == 1
+  ```
 
 
 The second operator of `*` must be a parameter; it is used to gather all the
@@ -1550,9 +1553,9 @@ is passed to `optConc` in `a` as a special list (of kind `nkArgList`)
 which is flattened into a call expression; thus the invocation of `optConc`
 produces:
 
-.. code-block:: nim
-
-   `&&`("my", space & "awe", "some ", "concat")
+  ```nim
+  `&&`("my", space & "awe", "some ", "concat")
+  ```
 
 
 ### The `**` operator
@@ -1560,8 +1563,7 @@ produces:
 The `**` is much like the `*` operator, except that it gathers not only
 all the arguments, but also the matched operators in reverse polish notation:
 
-.. code-block:: nim
-
+  ```nim
   import std/macros
 
   type
@@ -1582,6 +1584,7 @@ all the arguments, but also the matched operators in reverse polish notation:
   var x, y, z: Matrix
 
   echo x + y * z - x
+  ```
 
 This passes the expression `x + y * z - x` to the `optM` macro as
 an `nnkArgList` node containing::
@@ -1605,13 +1608,13 @@ Parameters in a pattern are type checked in the matching process. If a
 parameter is of the type `varargs`, it is treated specially and can match
 0 or more arguments in the AST to be matched against:
 
-.. code-block:: nim
-
+  ```nim
   template optWrite{
     write(f, x)
     ((write|writeLine){w})(f, y)
   }(x, y: varargs[untyped], f: File, w: untyped) =
     w(f, x, y)
+  ```
 
 
 noRewrite pragma
@@ -1625,12 +1628,12 @@ e.g. when rewriting term to same term plus extra content.
 `noRewrite` pragma can actually prevent further rewriting on marked code,
 e.g. with given example `echo("ab")` will be rewritten just once:
 
-.. code-block:: nim
-
+  ```nim
   template pwnEcho{echo(x)}(x: untyped) =
     {.noRewrite.}: echo("pwned!")
 
   echo "ab"
+  ```
 
 `noRewrite` pragma can be useful to control term-rewriting macros recursion.
 
@@ -1642,13 +1645,13 @@ Example: Partial evaluation
 The following example shows how some simple partial evaluation can be
 implemented with term rewriting:
 
-.. code-block:: nim
-
+  ```nim
   proc p(x, y: int; cond: bool): int =
     result = if cond: x + y else: x - y
 
   template optP1{p(x, y, true)}(x, y: untyped): untyped = x + y
   template optP2{p(x, y, false)}(x, y: untyped): untyped = x - y
+  ```
 
 
 Example: Hoisting
@@ -1656,8 +1659,7 @@ Example: Hoisting
 
 The following example shows how some form of hoisting can be implemented:
 
-.. code-block:: nim
-
+  ```nim
   import std/pegs
 
   template optPeg{peg(pattern)}(pattern: string{lit}): Peg =
@@ -1667,6 +1669,7 @@ The following example shows how some form of hoisting can be implemented:
   for i in 0 .. 3:
     echo match("(a b c)", peg"'(' @ ')'")
     echo match("W_HI_Le", peg"\y 'while'")
+  ```
 
 The `optPeg` template optimizes the case of a peg constructor with a string
 literal, so that the pattern will only be parsed once at program startup and
@@ -1680,8 +1683,7 @@ AST based overloading
 Parameter constraints can also be used for ordinary routine parameters; these
 constraints then affect ordinary overloading resolution:
 
-.. code-block:: nim
-
+  ```nim
   proc optLit(a: string{lit|`const`}) =
     echo "string literal"
   proc optLit(a: string) =
@@ -1696,6 +1698,7 @@ constraints then affect ordinary overloading resolution:
   optLit("literal")
   optLit(constant)
   optLit(variable)
+  ```
 
 However, the constraints `alias` and `noalias` are not available in
 ordinary routines.
@@ -1735,8 +1738,7 @@ Spawn statement
 
 The `spawn`:idx: statement can be used to pass a task to the thread pool:
 
-.. code-block:: nim
-
+  ```nim
   import std/threadpool
 
   proc processLine(line: string) =
@@ -1745,6 +1747,7 @@ The `spawn`:idx: statement can be used to pass a task to the thread pool:
   for x in lines("myinput.txt"):
     spawn processLine(x)
   sync()
+  ```
 
 For reasons of type safety and implementation simplicity the expression
 that `spawn` takes is restricted:
@@ -1768,8 +1771,7 @@ a `data flow variable`:idx: `FlowVar[T]` that can be read from. The reading
 with the `^` operator is **blocking**. However, one can use `blockUntilAny` to
 wait on multiple flow variables at the same time:
 
-.. code-block:: nim
-
+  ```nim
   import std/threadpool, ...
 
   # wait until 2 out of 3 servers received the update:
@@ -1781,6 +1783,7 @@ wait on multiple flow variables at the same time:
     assert index >= 0
     responses.del(index)
     discard blockUntilAny(responses)
+  ```
 
 Data flow variables ensure that no data races are possible. Due to
 technical limitations, not every type `T` can be used in
@@ -1795,9 +1798,7 @@ Parallel statement
 
 Example:
 
-.. code-block:: nim
-    :test: "nim c --threads:on $1"
-
+  ```nim  test = "nim c --threads:on $1"
   # Compute pi in an inefficient way
   import std/[strutils, math, threadpool]
   {.experimental: "parallel".}
@@ -1813,6 +1814,7 @@ Example:
       result += ch[k]
 
   echo formatFloat(pi(5000))
+  ```
 
 
 The parallel statement is the preferred mechanism to introduce parallelism in a
@@ -1853,8 +1855,7 @@ lock of level `N < M`. Another lock of level `M` cannot be acquired. Locks
 of the same level can only be acquired *at the same time* within a
 single `locks` section:
 
-.. code-block:: nim
-
+  ```nim
   var a, b: TLock[2]
   var x: TLock[1]
   # invalid locking order: TLock[1] cannot be acquired before TLock[2]:
@@ -1874,14 +1875,14 @@ single `locks` section:
   # valid locking order, locks of the same level acquired at the same time:
   {.locks: [a, b].}:
     ...
+  ```
 
 
 Here is how a typical multilock statement can be implemented in Nim. Note how
 the runtime check is required to ensure a global ordering for two locks `a`
 and `b` of the same lock level:
 
-.. code-block:: nim
-
+  ```nim
   template multilock(a, b: ptr TLock; body: untyped) =
     if cast[ByteAddress](a) < cast[ByteAddress](b):
       pthread_mutex_lock(a)
@@ -1895,20 +1896,21 @@ and `b` of the same lock level:
       finally:
         pthread_mutex_unlock(a)
         pthread_mutex_unlock(b)
+  ```
 
 
 Whole routines can also be annotated with a `locks` pragma that takes a lock
 level. This then means that the routine may acquire locks of up to this level.
 This is essential so that procs can be called within a `locks` section:
 
-.. code-block:: nim
-
+  ```nim
   proc p() {.locks: 3.} = discard
 
   var a: TLock[4]
   {.locks: [a].}:
     # p's locklevel (3) is strictly less than a's (4) so the call is allowed:
     p()
+  ```
 
 
 As usual, `locks` is an inferred effect and there is a subtype
@@ -1924,8 +1926,7 @@ cannot be inferred statically, leading to compiler warnings. By using
 `{.locks: "unknown".}`, the base method can be marked explicitly as
 having unknown lock level as well:
 
-.. code-block:: nim
-
+  ```nim
   type SomeBase* = ref object of RootObj
   type SomeDerived* = ref object of SomeBase
     memberProc*: proc ()
@@ -1934,5 +1935,6 @@ having unknown lock level as well:
   method testMethod(g: SomeDerived) =
     if g.memberProc != nil:
       g.memberProc()
+  ```
 
 This feature may be removed in the future due to its practical difficulties.