summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2022-08-04 10:32:23 +0300
committerGitHub <noreply@github.com>2022-08-04 09:32:23 +0200
commita34dd3d77a3c76b5bb5c1939412f592c6fdbd771 (patch)
treefa85c28be58d9f2ef656e54c6b49ddaa688afcd2 /doc
parent2aeb0d516b5e4cde1abb68a0c0d5393cf8c65915 (diff)
downloadNim-a34dd3d77a3c76b5bb5c1939412f592c6fdbd771.tar.gz
Markdown code blocks part 3 (#20117)
No logic was added, just 4 more files migrated.
Diffstat (limited to 'doc')
-rw-r--r--doc/astspec.txt400
-rw-r--r--doc/backends.md63
-rw-r--r--doc/contributing.md120
-rw-r--r--doc/destructors.md103
-rw-r--r--doc/manual.md6
5 files changed, 409 insertions, 283 deletions
diff --git a/doc/astspec.txt b/doc/astspec.txt
index dbbe2799d..bfaec7155 100644
--- a/doc/astspec.txt
+++ b/doc/astspec.txt
@@ -6,8 +6,7 @@ The AST consists of nodes (``NimNode``) with a variable number of
 children. Each node has a field named ``kind`` which describes what the node
 contains:
 
-.. code-block:: nim
-
+  ```nim
   type
     NimNodeKind = enum     ## kind of a node; only explanatory
       nnkNone,             ## invalid node kind
@@ -32,6 +31,7 @@ contains:
         strVal: string                 ## the string literal
       else:
         sons: seq[NimNode]             ## the node's sons (or children)
+  ```
 
 For the ``NimNode`` type, the ``[]`` operator has been overloaded:
 ``n[i]`` is ``n``'s ``i``-th child.
@@ -86,17 +86,19 @@ Command call
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   echo "abc", "xyz"
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCommand(
     nnkIdent("echo"),
     nnkStrLit("abc"),
     nnkStrLit("xyz")
   )
+  ```
 
 
 Call with ``()``
@@ -104,17 +106,19 @@ Call with ``()``
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   echo("abc", "xyz")
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCall(
     nnkIdent("echo"),
     nnkStrLit("abc"),
     nnkStrLit("xyz")
   )
+  ```
 
 
 Infix operator call
@@ -122,29 +126,32 @@ Infix operator call
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   "abc" & "xyz"
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkInfix(
     nnkIdent("&"),
     nnkStrLit("abc"),
     nnkStrLit("xyz")
   )
+  ```
 
 Note that with multiple infix operators, the command is parsed by operator
 precedence.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   5 + 3 * 4
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkInfix(
     nnkIdent("+"),
     nnkIntLit(5),
@@ -154,6 +161,7 @@ AST:
       nnkIntLit(4)
     )
   )
+  ```
 
 As a side note, if you choose to use infix operators in a prefix form, the AST
 behaves as a
@@ -162,12 +170,13 @@ behaves as a
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   `+`(3, 4)
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCall(
     nnkAccQuoted(
       nnkIdent("+")
@@ -175,22 +184,25 @@ AST:
     nnkIntLit(3),
     nnkIntLit(4)
   )
+  ```
 
 Prefix operator call
 --------------------
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   ? "xyz"
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkPrefix(
     nnkIdent("?"),
     nnkStrLit("abc")
   )
+  ```
 
 
 Postfix operator call
@@ -201,16 +213,18 @@ Postfix operator call
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   identifier*
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkPostfix(
     nnkIdent("*"),
     nnkIdent("identifier")
   )
+  ```
 
 
 Call with named arguments
@@ -218,12 +232,13 @@ Call with named arguments
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   writeLine(file=stdout, "hallo")
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCall(
     nnkIdent("writeLine"),
     nnkExprEqExpr(
@@ -232,6 +247,7 @@ AST:
     ),
     nnkStrLit("hallo")
   )
+  ```
 
 Call with raw string literal
 ----------------------------
@@ -242,29 +258,33 @@ This is used, for example, in the ``bindSym`` examples
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   echo"abc"
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCallStrLit(
     nnkIdent("echo"),
     nnkRStrLit("hello")
   )
+  ```
 
 Dereference operator ``[]``
 ---------------------------
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   x[]
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkDerefExpr(nnkIdent("x"))
+  ```
 
 
 Addr operator
@@ -272,13 +292,15 @@ Addr operator
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   addr(x)
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkAddr(nnkIdent("x"))
+  ```
 
 
 Cast operator
@@ -286,13 +308,15 @@ Cast operator
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   cast[T](x)
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCast(nnkIdent("T"), nnkIdent("x"))
+  ```
 
 
 Object access operator ``.``
@@ -300,13 +324,15 @@ Object access operator ``.``
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   x.y
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkDotExpr(nnkIdent("x"), nnkIdent("y"))
+  ```
 
 If you use Nim's flexible calling syntax (as in ``x.len()``), the result is the
 same as above but wrapped in an ``nnkCall``.
@@ -317,13 +343,15 @@ Array access operator ``[]``
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   x[y]
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkBracketExpr(nnkIdent("x"), nnkIdent("y"))
+  ```
 
 
 Parentheses
@@ -333,16 +361,18 @@ Parentheses for affecting operator precedence use the ``nnkPar`` node.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   (a + b) * c
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkInfix(nnkIdent("*"),
     nnkPar(
       nnkInfix(nnkIdent("+"), nnkIdent("a"), nnkIdent("b"))),
     nnkIdent("c"))
+  ```
 
 Tuple Constructors
 ------------------
@@ -351,35 +381,39 @@ Nodes for tuple construction are built with the ``nnkTupleConstr`` node.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   (1, 2, 3)
   (a: 1, b: 2, c: 3)
   ()
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTupleConstr(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
   nnkTupleConstr(
     nnkExprColonExpr(nnkIdent("a"), nnkIntLit(1)),
     nnkExprColonExpr(nnkIdent("b"), nnkIntLit(2)),
     nnkExprColonExpr(nnkIdent("c"), nnkIntLit(3)))
   nnkTupleConstr()
+  ```
 
 Since the one tuple would be syntactically identical to parentheses
 with an expression in them, the parser expects a trailing comma for
 them. For tuple constructors with field names, this is not necessary.
 
-.. code-block:: nim
+  ```nim
   (1,)
   (a: 1)
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTupleConstr(nnkIntLit(1))
   nnkTupleConstr(
     nnkExprColonExpr(nnkIdent("a"), nnkIntLit(1)))
+  ```
 
 Curly braces
 ------------
@@ -388,28 +422,32 @@ Curly braces are used as the set constructor.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   {1, 2, 3}
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCurly(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
+  ```
 
 When used as a table constructor, the syntax is different.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   {a: 3, b: 5}
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTableConstr(
     nnkExprColonExpr(nnkIdent("a"), nnkIntLit(3)),
     nnkExprColonExpr(nnkIdent("b"), nnkIntLit(5))
   )
+  ```
 
 
 Brackets
@@ -419,13 +457,15 @@ Brackets are used as the array constructor.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   [1, 2, 3]
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkBracket(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
+  ```
 
 
 Ranges
@@ -437,21 +477,23 @@ AST, construction with ``..`` as an infix operator should be used instead.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   1..3
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkInfix(
     nnkIdent(".."),
     nnkIntLit(1),
     nnkIntLit(3)
   )
+  ```
 
 Example code:
 
-.. code-block:: nim
+  ```nim
   macro genRepeatEcho() =
     result = newNimNode(nnkStmtList)
 
@@ -470,6 +512,7 @@ Example code:
                   # 3
                   # 3
                   # 3
+  ```
 
 
 If expression
@@ -479,17 +522,19 @@ The representation of the ``if`` expression is subtle, but easy to traverse.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   if cond1: expr1 elif cond2: expr2 else: expr3
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkIfExpr(
     nnkElifExpr(cond1, expr1),
     nnkElifExpr(cond2, expr2),
     nnkElseExpr(expr3)
   )
+  ```
 
 Documentation Comments
 ----------------------
@@ -500,19 +545,21 @@ comments are ignored.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   ## This is a comment
   ## This is part of the first comment
   stmt1
   ## Yet another
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCommentStmt() # only appears once for the first two lines!
   stmt1
   nnkCommentStmt() # another nnkCommentStmt because there is another comment
                    # (separate from the first)
+  ```
 
 Pragmas
 -------
@@ -523,30 +570,33 @@ objects, but the standalone ``emit`` pragma shows the basics with the AST.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   {.emit: "#include <stdio.h>".}
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkPragma(
     nnkExprColonExpr(
       nnkIdent("emit"),
       nnkStrLit("#include <stdio.h>") # the "argument"
     )
   )
+  ```
 
 As many ``nnkIdent`` appear as there are pragmas between ``{..}``. Note that
 the declaration of new pragmas is essentially the same:
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   {.pragma: cdeclRename, cdecl.}
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkPragma(
     nnkExprColonExpr(
       nnkIdent("pragma"), # this is always first when declaring a new pragma
@@ -554,6 +604,7 @@ AST:
     ),
     nnkIdent("cdecl")
   )
+  ```
 
 Statements
 ==========
@@ -566,7 +617,7 @@ there is no ``else`` branch, no ``nnkElse`` child exists.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   if cond1:
     stmt1
   elif cond2:
@@ -575,16 +626,18 @@ Concrete syntax:
     stmt3
   else:
     stmt4
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkIfStmt(
     nnkElifBranch(cond1, stmt1),
     nnkElifBranch(cond2, stmt2),
     nnkElifBranch(cond3, stmt3),
     nnkElse(stmt4)
   )
+  ```
 
 
 When statement
@@ -598,13 +651,15 @@ Assignment
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   x = 42
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkAsgn(nnkIdent("x"), nnkIntLit(42))
+  ```
 
 This is not the syntax for assignment when combined with ``var``, ``let``,
 or ``const``.
@@ -614,15 +669,17 @@ Statement list
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   stmt1
   stmt2
   stmt3
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkStmtList(stmt1, stmt2, stmt3)
+  ```
 
 
 Case statement
@@ -630,7 +687,7 @@ Case statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   case expr1
   of expr2, expr3..expr4:
     stmt1
@@ -640,10 +697,11 @@ Concrete syntax:
     stmt3
   else:
     stmt4
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkCaseStmt(
     expr1,
     nnkOfBranch(expr2, nnkRange(expr3, expr4), stmt1),
@@ -651,6 +709,7 @@ AST:
     nnkElifBranch(cond1, stmt3),
     nnkElse(stmt4)
   )
+  ```
 
 The ``nnkElifBranch`` and ``nnkElse`` parts may be missing.
 
@@ -660,14 +719,16 @@ While statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   while expr1:
     stmt1
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkWhileStmt(expr1, stmt1)
+  ```
 
 
 For statement
@@ -675,14 +736,16 @@ For statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   for ident1, ident2 in expr1:
     stmt1
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkForStmt(ident1, ident2, expr1, stmt1)
+  ```
 
 
 Try statement
@@ -690,7 +753,7 @@ Try statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   try:
     stmt1
   except e1, e2:
@@ -701,10 +764,11 @@ Concrete syntax:
     stmt4
   finally:
     stmt5
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTryStmt(
     stmt1,
     nnkExceptBranch(e1, e2, stmt2),
@@ -712,6 +776,7 @@ AST:
     nnkExceptBranch(stmt4),
     nnkFinally(stmt5)
   )
+  ```
 
 
 Return statement
@@ -719,13 +784,15 @@ Return statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   return expr1
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkReturnStmt(expr1)
+  ```
 
 
 Yield statement
@@ -733,8 +800,9 @@ Yield statement
 
 Like ``return``, but with ``nnkYieldStmt`` kind.
 
-.. code-block:: nim
+  ```nim
   nnkYieldStmt(expr1)
+  ```
 
 
 Discard statement
@@ -742,8 +810,9 @@ Discard statement
 
 Like ``return``, but with ``nnkDiscardStmt`` kind.
 
-.. code-block:: nim
+  ```nim
   nnkDiscardStmt(expr1)
+  ```
 
 
 Continue statement
@@ -751,26 +820,30 @@ Continue statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   continue
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkContinueStmt()
+  ```
 
 Break statement
 ---------------
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   break otherLocation
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkBreakStmt(nnkIdent("otherLocation"))
+  ```
 
 If ``break`` is used without a jump-to location, ``nnkEmpty`` replaces ``nnkIdent``.
 
@@ -779,13 +852,15 @@ Block statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   block name:
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkBlockStmt(nnkIdent("name"), nnkStmtList(...))
+  ```
 
 A ``block`` doesn't need an name, in which case ``nnkEmpty`` is used.
 
@@ -794,18 +869,20 @@ Asm statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   asm """
     some asm
   """
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkAsmStmt(
     nnkEmpty(), # for pragmas
     nnkTripleStrLit("some asm"),
   )
+  ```
 
 Import section
 --------------
@@ -815,37 +892,42 @@ on what keywords are present. Let's start with the simplest form.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   import math
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkImportStmt(nnkIdent("math"))
+  ```
 
 With ``except``, we get ``nnkImportExceptStmt``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   import math except pow
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkImportExceptStmt(nnkIdent("math"),nnkIdent("pow"))
+  ```
 
 Note that ``import math as m`` does not use a different node; rather,
 we use ``nnkImportStmt`` with ``as`` as an infix operator.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   import strutils as su
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkImportStmt(
     nnkInfix(
       nnkIdent("as"),
@@ -853,6 +935,7 @@ AST:
       nnkIdent("su")
     )
   )
+  ```
 
 From statement
 --------------
@@ -861,13 +944,15 @@ If we use ``from ... import``, the result is different, too.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   from math import pow
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkFromStmt(nnkIdent("math"), nnkIdent("pow"))
+  ```
 
 Using ``from math as m import pow`` works identically to the ``as`` modifier
 with the ``import`` statement, but wrapped in ``nnkFromStmt``.
@@ -880,26 +965,30 @@ the ``export`` syntax is pretty straightforward.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   export unsigned
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkExportStmt(nnkIdent("unsigned"))
+  ```
 
 Similar to the ``import`` statement, the AST is different for
 ``export ... except``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   export math except pow # we're going to implement our own exponentiation
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkExportExceptStmt(nnkIdent("math"),nnkIdent("pow"))
+  ```
 
 Include statement
 -----------------
@@ -908,25 +997,28 @@ Like a plain ``import`` statement but with ``nnkIncludeStmt``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   include blocks
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkIncludeStmt(nnkIdent("blocks"))
+  ```
 
 Var section
 -----------
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   var a = 3
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkVarSection(
     nnkIdentDefs(
       nnkIdent("a"),
@@ -934,6 +1026,7 @@ AST:
       nnkIntLit(3),
     )
   )
+  ```
 
 Note that either the second or third (or both) parameters above must exist,
 as the compiler needs to know the type somehow (which it can infer from
@@ -951,12 +1044,13 @@ This is equivalent to ``var``, but with ``nnkLetSection`` rather than
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   let a = 3
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkLetSection(
     nnkIdentDefs(
       nnkIdent("a"),
@@ -964,18 +1058,20 @@ AST:
       nnkIntLit(3),
     )
   )
+  ```
 
 Const section
 -------------
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   const a = 3
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkConstSection(
     nnkConstDef( # not nnkConstDefs!
       nnkIdent("a"),
@@ -983,6 +1079,7 @@ AST:
       nnkIntLit(3), # required in a const declaration!
     )
   )
+  ```
 
 Type section
 ------------
@@ -992,12 +1089,13 @@ and ``const``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type A = int
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTypeSection(
     nnkTypeDef(
       nnkIdent("A"),
@@ -1005,18 +1103,20 @@ AST:
       nnkIdent("int")
     )
   )
+  ```
 
 Declaring ``distinct`` types is similar, with the last ``nnkIdent`` wrapped
 in ``nnkDistinctTy``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type MyInt = distinct int
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkTypeDef(
     nnkIdent("MyInt"),
@@ -1025,17 +1125,19 @@ AST:
       nnkIdent("int")
     )
   )
+  ```
 
 If a type section uses generic parameters, they are treated here:
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type A[T] = expr1
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTypeSection(
     nnkTypeDef(
       nnkIdent("A"),
@@ -1050,6 +1152,7 @@ AST:
       expr1,
     )
   )
+  ```
 
 Note that not all ``nnkTypeDef`` utilize ``nnkIdent`` as their
 parameter. One of the most common uses of type declarations
@@ -1057,12 +1160,13 @@ is to work with objects.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type IO = object of RootObj
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkTypeDef(
     nnkIdent("IO"),
@@ -1075,13 +1179,14 @@ AST:
       nnkEmpty()
     )
   )
+  ```
 
 Nim's object syntax is rich. Let's take a look at an involved example in
 its entirety to see some of the complexities.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type Obj[T] {.inheritable.} = object
     name: string
     case isFat: bool
@@ -1089,10 +1194,11 @@ Concrete syntax:
       m: array[100_000, T]
     of false:
       m: array[10, T]
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkPragmaExpr(
     nnkIdent("Obj"),
@@ -1149,36 +1255,40 @@ AST:
       )
     )
   )
+  ```
 
 
 Using an ``enum`` is similar to using an ``object``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type X = enum
     First
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkEnumTy(
     nnkEmpty(),
     nnkIdent("First") # you need at least one nnkIdent or the compiler complains
   )
+  ```
 
 The usage of ``concept`` (experimental) is similar to objects.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type Con = concept x,y,z
     (x & y & z) is string
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkTypeClassTy( # note this isn't nnkConceptTy!
     nnkArgList(
@@ -1186,18 +1296,20 @@ AST:
     )
     # ...
   )
+  ```
 
 Static types, like ``static[int]``, use ``nnkIdent`` wrapped in
 ``nnkStaticTy``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type A[T: static[int]] = object
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ... within nnkGenericParams
   nnkIdentDefs(
     nnkIdent("T"),
@@ -1207,6 +1319,7 @@ AST:
     nnkEmpty()
   )
   # ...
+  ```
 
 In general, declaring types mirrors this syntax (i.e., ``nnkStaticTy`` for
 ``static``, etc.). Examples follow (exceptions marked by ``*``):
@@ -1234,12 +1347,13 @@ Generic parameters are treated in the type, not the ``proc`` itself.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   type MyProc[T] = proc(x: T)
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkTypeDef(
     nnkIdent("MyProc"),
@@ -1252,6 +1366,7 @@ AST:
       )
     )
   )
+  ```
 
 The same syntax applies to ``iterator`` (with ``nnkIteratorTy``), but
 *does not* apply to ``converter`` or ``template``.
@@ -1261,26 +1376,30 @@ Mixin statement
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   mixin x
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkMixinStmt(nnkIdent("x"))
+  ```
 
 Bind statement
 --------------
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   bind x
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkBindStmt(nnkIdent("x"))
+  ```
 
 Procedure declaration
 ---------------------
@@ -1290,12 +1409,13 @@ a feel for how procedure calls are broken down.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   proc hello*[T: SomeInteger](x: int = 3, y: float32): int {.inline.} = discard
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkProcDef(
     nnkPostfix(nnkIdent("*"), nnkIdent("hello")), # the exported proc name
     nnkEmpty(), # patterns for term rewriting in templates and macros (not procs)
@@ -1323,6 +1443,7 @@ AST:
     nnkEmpty(), # reserved slot for future use
     nnkStmtList(nnkDiscardStmt(nnkEmpty())) # the meat of the proc
   )
+  ```
 
 There is another consideration. Nim has flexible type identification for
 its procs. Even though ``proc(a: int, b: int)`` and ``proc(a, b: int)``
@@ -1330,12 +1451,13 @@ are equivalent in the code, the AST is a little different for the latter.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   proc(a, b: int)
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...AST as above...
   nnkFormalParams(
     nnkEmpty(), # no return here
@@ -1347,24 +1469,27 @@ AST:
     )
   ),
   # ...
+  ```
 
 When a procedure uses the special ``var`` type return variable, the result
 is different from that of a var section.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   proc hello(): var int
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   # ...
   nnkFormalParams(
     nnkVarTy(
       nnkIdent("int")
     )
   )
+  ```
 
 Iterator declaration
 --------------------
@@ -1374,17 +1499,19 @@ replacing ``nnkProcDef``.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   iterator nonsense[T](x: seq[T]): float {.closure.} = ...
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkIteratorDef(
     nnkIdent("nonsense"),
     nnkEmpty(),
     ...
   )
+  ```
 
 Converter declaration
 ---------------------
@@ -1393,16 +1520,18 @@ A converter is similar to a proc.
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   converter toBool(x: float): bool
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkConverterDef(
     nnkIdent("toBool"),
     # ...
   )
+  ```
 
 Template declaration
 --------------------
@@ -1415,12 +1544,13 @@ the ``nnkEmpty()`` as the second argument to ``nnkProcDef`` and
 
 Concrete syntax:
 
-.. code-block:: nim
+  ```nim
   template optOpt{expr1}(a: int): int
+  ```
 
 AST:
 
-.. code-block:: nim
+  ```nim
   nnkTemplateDef(
     nnkIdent("optOpt"),
     nnkStmtList( # instead of nnkEmpty()
@@ -1428,6 +1558,7 @@ AST:
     ),
     # follows like a proc or iterator
   )
+  ```
 
 If the template does not have types for its parameters, the type identifiers
 inside ``nnkFormalParams`` just becomes ``nnkEmpty``.
@@ -1441,8 +1572,9 @@ Macros behave like templates, but ``nnkTemplateDef`` is replaced with
 Hidden Standard Conversion
 --------------------------
 
-.. code-block:: nim
+  ```nim
   var f: float = 1
+  ```
 
 The type of "f" is ``float`` but the type of "1" is actually ``int``. Inserting 
 ``int`` into a ``float`` is a type error. Nim inserts the ``nnkHiddenStdConv``  
diff --git a/doc/backends.md b/doc/backends.md
index 4f8a2bfff..134731461 100644
--- a/doc/backends.md
+++ b/doc/backends.md
@@ -57,11 +57,11 @@ project. This allows you to take the generated code and place it directly
 into a project using any of these languages. Here are some typical command-
 line invocations:
 
-.. code:: cmd
-
-   nim c hallo.nim
-   nim cpp hallo.nim
-   nim objc hallo.nim
+  ```cmd
+  nim c hallo.nim
+  nim cpp hallo.nim
+  nim objc hallo.nim
+  ```
 
 The compiler commands select the target backend, but if needed you can
 `specify additional switches for cross-compilation
@@ -99,9 +99,9 @@ default is a ``.js`` file that is supposed to be referenced in an ``.html``
 file. However, you can also run the code with `nodejs`:idx:
 (`<http://nodejs.org>`_):
 
-.. code:: cmd
-
+  ```cmd
   nim js -d:nodejs -r examples/hallo.nim
+  ```
 
 If you experience errors saying that `globalThis` is not defined, be
 sure to run a recent version of Node.js (at least 12.0).
@@ -159,21 +159,22 @@ interface.
 
 Create a ``logic.c`` file with the following content:
 
-.. code-block:: c
+  ```c
   int addTwoIntegers(int a, int b)
   {
     return a + b;
   }
+  ```
 
 Create a ``calculator.nim`` file with the following content:
 
-.. code-block:: nim
-
+  ```nim
   {.compile: "logic.c".}
   proc addTwoIntegers(a, b: cint): cint {.importc.}
 
   when isMainModule:
     echo addTwoIntegers(3, 7)
+  ```
 
 With these two files in place, you can run `nim c -r calculator.nim`:cmd: and
 the Nim compiler will compile the ``logic.c`` file in addition to
@@ -182,11 +183,11 @@ run. Another way to link the C file statically and get the same effect would
 be to remove the line with the `compile` pragma and run the following
 typical Unix commands:
 
-.. code:: cmd
-
-    gcc -c logic.c
-    ar rvs mylib.a logic.o
-    nim c --passL:mylib.a -r calculator.nim
+  ```cmd
+  gcc -c logic.c
+  ar rvs mylib.a logic.o
+  nim c --passL:mylib.a -r calculator.nim
+  ```
 
 Just like in this example we pass the path to the ``mylib.a`` library (and we
 could as well pass ``logic.o``) we could be passing switches to link any other
@@ -212,12 +213,12 @@ Create a ``host.html`` file with the following content:
 Create a ``calculator.nim`` file with the following content (or reuse the one
 from the previous section):
 
-.. code-block:: nim
-
+  ```nim
   proc addTwoIntegers(a, b: int): int {.importc.}
 
   when isMainModule:
     echo addTwoIntegers(3, 7)
+  ```
 
 Compile the Nim code to JavaScript with `nim js -o:calculator.js
 calculator.nim`:cmd: and open ``host.html`` in a browser. If the browser supports
@@ -253,18 +254,17 @@ Use `--nimMainPrefix:MyLib` and the function to call is named `MyLibNimMain`.
 
 Create a ``fib.nim`` file with the following content:
 
-.. code-block:: nim
-
+  ```nim
   proc fib(a: cint): cint {.exportc.} =
     if a <= 2:
       result = 1
     else:
       result = fib(a - 1) + fib(a - 2)
+  ```
 
 Create a ``maths.c`` file with the following content:
 
-.. code-block:: c
-
+  ```c
   #include <stdio.h>
 
   int fib(int a);
@@ -277,15 +277,16 @@ Create a ``maths.c`` file with the following content:
       printf("Fib of %d is %d\n", f, fib(f));
     return 0;
   }
+  ```
 
 Now you can run the following Unix like commands to first generate C sources
 from the Nim code, then link them into a static binary along your main C
 program:
 
-.. code:: cmd
-
+  ```cmd
   nim c --noMain --noLinking fib.nim
   gcc -o m -I$HOME/.cache/nim/fib_d -Ipath/to/nim/lib $HOME/.cache/nim/fib_d/*.c maths.c
+  ```
 
 The first command runs the Nim compiler with three special options to avoid
 generating a `main()`:c: function in the generated files and to avoid linking the
@@ -297,10 +298,10 @@ have to tell the C compiler where to find Nim's ``nimbase.h`` header file.
 Instead of depending on the generation of the individual ``.c`` files you can
 also ask the Nim compiler to generate a statically linked library:
 
-.. code:: cmd
-
+  ```cmd
   nim c --app:staticLib --noMain fib.nim
   gcc -o m -Inimcache -Ipath/to/nim/lib maths.c libfib.nim.a
+  ```
 
 The Nim compiler will handle linking the source files generated in the
 ``nimcache`` directory into the ``libfib.nim.a`` static library, which you can
@@ -313,25 +314,25 @@ use `-ldl`:option: too to link in required dlopen functionality.
 
 Create a ``mhost.html`` file with the following content:
 
-.. code-block::
-
+  ```
   <html><body>
   <script type="text/javascript" src="fib.js"></script>
   <script type="text/javascript">
   alert("Fib for 9 is " + fib(9));
   </script>
   </body></html>
+  ```
 
 Create a ``fib.nim`` file with the following content (or reuse the one
 from the previous section):
 
-.. code-block:: nim
-
+  ```nim
   proc fib(a: cint): cint {.exportc.} =
     if a <= 2:
       result = 1
     else:
       result = fib(a - 1) + fib(a - 2)
+  ```
 
 Compile the Nim code to JavaScript with `nim js -o:fib.js fib.nim`:cmd: and
 open ``mhost.html`` in a browser. If the browser supports javascript, you
@@ -378,10 +379,10 @@ from being freed with `GC_ref <system.html#GC_ref,string>`_ and `GC_unref
 A similar thing happens with C code invoking Nim code which returns a
 `cstring`. Consider the following proc:
 
-.. code-block:: nim
-
+  ```nim
   proc gimme(): cstring {.exportc.} =
     result = "Hey there C code! " & $rand(100)
+  ```
 
 Since Nim's reference counting mechanism is not aware of the C code, once the
 `gimme` proc has finished it can reclaim the memory of the `cstring`.
diff --git a/doc/contributing.md b/doc/contributing.md
index 51d1d5065..4295623df 100644
--- a/doc/contributing.md
+++ b/doc/contributing.md
@@ -59,8 +59,7 @@ things like `echo "done"`. Don't use `unittest.suite` and `unittest.test`.
 
 Sample test:
 
-.. code-block:: nim
-
+  ```nim
   block: # foo
     doAssert foo(1) == 10
 
@@ -76,6 +75,7 @@ Sample test:
                         @[false, false], @[false, false]]
     # doAssert with `not` can now be done as follows:
     doAssert not (1 == 2)
+  ```
 
 Always refer to a GitHub issue using the following exact syntax: ``bug #1234`` as shown
 above, so that it's consistent and easier to search or for tooling. Some browser
@@ -110,8 +110,7 @@ For a full spec, see here: ``testament/specs.nim``
 
 An example of a test:
 
-.. code-block:: nim
-
+  ```nim
   discard """
     errormsg: "type mismatch: got (PTest)"
   """
@@ -123,6 +122,7 @@ An example of a test:
 
   var buf: PTest
   buf.test()
+  ```
 
 
 Running tests
@@ -130,9 +130,9 @@ Running tests
 
 You can run the tests with
 
-.. code-block:: cmd
-
+  ```cmd
   ./koch tests
+  ```
 
 which will run a good subset of tests. Some tests may fail. If you
 only want to see the output of failing tests, go for
@@ -145,17 +145,17 @@ You can also run only a single category of tests. A category is a subdirectory
 in the ``tests/`` directory. There are a couple of special categories; for a
 list of these, see ``testament/categories.nim``, at the bottom.
 
-.. code:: cmd
-
+  ```cmd
   ./koch tests c lib # compiles / runs stdlib modules, including `isMainModule` tests
   ./koch tests c megatest # runs a set of tests that can be combined into 1
+  ```
 
 To run a single test:
 
-.. code:: cmd
-
+  ```cmd
   ./koch test run <category>/<name>    # e.g.: tuples/ttuples_issues
   ./koch test run tests/stdlib/tos.nim # can also provide relative path
+  ```
 
 For reproducible tests (to reproduce an environment more similar to the one
 run by Continuous Integration on github actions/azure pipelines), you may want to disable your
@@ -174,25 +174,25 @@ The tester can compare two test runs. First, you need to create a
 reference test. You'll also need to the commit id, because that's what
 the tester needs to know in order to compare the two.
 
-.. code:: cmd
-
+  ```cmd
   git checkout devel
   DEVEL_COMMIT=$(git rev-parse HEAD)
   ./koch tests
+  ```
 
 Then switch over to your changes and run the tester again.
 
-.. code:: cmd
-
+  ```cmd
   git checkout your-changes
   ./koch tests
+  ```
 
 Then you can ask the tester to create a ``testresults.html`` which will
 tell you if any new tests passed/failed.
 
-.. code:: cmd
-
+  ```cmd
   ./koch tests --print html $DEVEL_COMMIT
+  ```
 
 
 Deprecation
@@ -201,8 +201,7 @@ Deprecation
 Backward compatibility is important, so instead of a rename you need to deprecate
 the old name and introduce a new name:
 
-.. code-block:: nim
-
+  ```nim
   # for routines (proc/template/macro/iterator) and types:
   proc oldProc(a: int, b: float): bool {.deprecated:
       "deprecated since v1.2.3; use `newImpl: string -> int` instead".} = discard
@@ -214,6 +213,7 @@ the old name and introduce a new name:
   # (likewise with object types and their fields):
   type Bar {.deprecated.} = enum bar0, bar1
   type Barz  = enum baz0, baz1 {.deprecated.}, baz2
+  ```
 
 
 See also `Deprecated <manual.html#pragmas-deprecated-pragma>`_
@@ -234,12 +234,13 @@ test cases (typically 1 to 3 `assert` statements, depending on complexity).
 These `runnableExamples` are automatically run by `nim doc mymodule.nim`:cmd:
 as well as `testament`:cmd: and guarantee they stay in sync.
 
-.. code-block:: nim
+  ```nim
   proc addBar*(a: string): string =
     ## Adds "Bar" to `a`.
     runnableExamples:
       assert "baz".addBar == "bazBar"
     result = a & "Bar"
+  ```
 
 See `parentDir <os.html#parentDir,string>`_ example.
 
@@ -247,47 +248,49 @@ The RestructuredText Nim uses has a special syntax for including code snippets
 embedded in documentation; these are not run by `nim doc`:cmd: and therefore are
 not guaranteed to stay in sync, so `runnableExamples` is almost always preferred:
 
-.. code-block:: nim
-
+  ````nim
   proc someProc*(): string =
     ## Returns "something"
     ##
-    ## .. code-block::
-    ##  echo someProc() # "something"
+    ##   ```
+    ##   echo someProc() # "something"
+    ##   ```
     result = "something" # single-hash comments do not produce documentation
+  ````
 
-The ``.. code-block:: nim`` followed by a newline and an indentation instructs the
+The \`\`\` followed by a newline and an indentation instructs the
 `nim doc`:cmd: command to produce syntax-highlighted example code with the
-documentation (``.. code-block::`` is sufficient from inside a nim module).
+documentation (\`\`\` is sufficient inside a ``.nim`` module, while from
+a ``.md`` one needs to set the language explicitly as \`\`\`nim).
 
 When forward declaration is used, the documentation should be included with the
 first appearance of the proc.
 
-.. code-block:: nim
-
+  ```nim
   proc hello*(): string
     ## Put documentation here
   proc nothing() = discard
   proc hello*(): string =
     ## ignore this
     echo "hello"
+  ```
 
 The preferred documentation style is to begin with a capital letter and use
 the third-person singular. That is, between:
 
-.. code-block:: nim
-
+  ```nim
   proc hello*(): string =
     ## Returns "hello"
     result = "hello"
+  ```
 
 or
 
-.. code-block:: nim
-
+  ```nim
   proc hello*(): string =
     ## say hello
     result = "hello"
+  ```
 
 the first is preferred.
 
@@ -296,8 +299,9 @@ in the postfix form for uniformity, that is after \`text in backticks\`.
 For example an ``:idx:`` role for referencing a topic ("SQLite" in the
 example below) from `Nim Index`_ can be used in doc comment this way:
 
-.. code-block:: nim
+  ```nim
   ## A higher level `SQLite`:idx: database wrapper.
+  ```
 
 .. _`Nim Index`: https://nim-lang.org/docs/theindex.html
 
@@ -355,50 +359,50 @@ New `defined(foo)` symbols need to be prefixed by the nimble package name, or
 by `nim` for symbols in nim sources (e.g. compiler, standard library). This is
 to avoid name conflicts across packages.
 
-.. code-block:: nim
-
+  ```nim
   # if in nim sources
   when defined(allocStats): discard # bad, can cause conflicts
   when defined(nimAllocStats): discard # preferred
   # if in a package `cligen`:
   when defined(debug): discard # bad, can cause conflicts
   when defined(cligenDebug): discard # preferred
+  ```
 
 .. _noimplicitbool:
 Take advantage of no implicit bool conversion
 
-.. code-block:: nim
-
+  ```nim
   doAssert isValid() == true
   doAssert isValid() # preferred
+  ```
 
 .. _design_for_mcs:
 Design with method call syntax chaining in mind
 
-.. code-block:: nim
-
+  ```nim
   proc foo(cond: bool, lines: seq[string]) # bad
   proc foo(lines: seq[string], cond: bool) # preferred
   # can be called as: `getLines().foo(false)`
+  ```
 
 .. _avoid_quit:
 Use exceptions (including `assert` / `doAssert`) instead of `quit`
 rationale: https://forum.nim-lang.org/t/4089
 
-.. code-block:: nim
-
+  ```nim
   quit() # bad in almost all cases
   doAssert() # preferred
+  ```
 
 .. _tests_use_doAssert:
 Use `doAssert` (or `unittest.check`, `unittest.require`), not `assert` in all
 tests so they'll be enabled even with `--assertions:off`:option:.
 
-.. code-block:: nim
-
+  ```nim
   block: # foo
     assert foo() # bad
     doAssert foo() # preferred
+  ```
 
 .. _runnableExamples_use_assert:
 An exception to the above rule is `runnableExamples` and ``code-block`` rst blocks
@@ -407,33 +411,33 @@ instead of `doAssert`. Note that `nim doc -d:danger main`:cmd: won't pass `-d:da
 `runnableExamples`, but `nim doc --doccmd:-d:danger main`:cmd: would, and so would the
 second example below:
 
-.. code-block:: nim
-
+  ```nim
   runnableExamples:
     doAssert foo() # bad
     assert foo() # preferred
 
   runnableExamples("-d:danger"):
     doAssert foo() # `assert` would be disabled here, so `doAssert` makes more sense
+  ```
 
 .. _delegate_printing:
 Delegate printing to caller: return `string` instead of calling `echo`
 rationale: it's more flexible (e.g. allows the caller to call custom printing,
 including prepending location info, writing to log files, etc).
 
-.. code-block:: nim
-
+  ```nim
   proc foo() = echo "bar" # bad
   proc foo(): string = "bar" # preferred (usually)
+  ```
 
 .. _use_Option:
 [Ongoing debate] Consider using Option instead of return bool + var argument,
 unless stack allocation is needed (e.g. for efficiency).
 
-.. code-block:: nim
-
+  ```nim
   proc foo(a: var Bar): bool
   proc foo(): Option[Bar]
+  ```
 
 .. _use_doAssert_not_echo:
 Tests (including in testament) should always prefer assertions over `echo`,
@@ -441,10 +445,10 @@ except when that's not possible. It's more precise, easier for readers and
 maintainers to where expected values refer to. See for example
 https://github.com/nim-lang/Nim/pull/9335 and https://forum.nim-lang.org/t/4089
 
-.. code-block:: nim
-
+  ```nim
   echo foo() # adds a line for testament in `output:` block inside `discard`.
   doAssert foo() == [1, 2] # preferred, except when not possible to do so.
+  ```
 
 
 The `git`:cmd: stuff
@@ -480,10 +484,10 @@ General commit rules
    Always check your changes for whitespace errors using `git diff --check`:cmd:
    or add the following ``pre-commit`` hook:
 
-   .. code:: cmd
-
-      #!/bin/sh
-      git diff --check --cached || exit $?
+     ```cmd
+     #!/bin/sh
+     git diff --check --cached || exit $?
+     ```
 5. Describe your commit and use your common sense.
    Example commit message::
 
@@ -565,10 +569,10 @@ Code reviews
    doesn't help much as it doesn't highlight moves. Instead, you can use something
    like this, see visual results `here <https://github.com/nim-lang/Nim/pull/10431#issuecomment-456968196>`_:
 
-   .. code:: cmd
-
-      git fetch origin pull/10431/head && git checkout FETCH_HEAD
-      git diff --color-moved-ws=allow-indentation-change --color-moved=blocks HEAD^
+     ```cmd
+     git fetch origin pull/10431/head && git checkout FETCH_HEAD
+     git diff --color-moved-ws=allow-indentation-change --color-moved=blocks HEAD^
+     ```
 
 3. In addition, you can view GitHub-like diffs locally to identify what was changed
    within a code block using `diff-highlight`:cmd: or `diff-so-fancy`:cmd:, e.g.:
diff --git a/doc/destructors.md b/doc/destructors.md
index c98e94536..612c47926 100644
--- a/doc/destructors.md
+++ b/doc/destructors.md
@@ -30,8 +30,7 @@ Motivating example
 With the language mechanisms described here, a custom seq could be
 written as:
 
-.. code-block:: nim
-
+  ```nim
   type
     myseq*[T] = object
       len, cap: int
@@ -91,7 +90,7 @@ written as:
     for i in 0..<result.len: result.data[i] = elems[i]
 
   proc len*[T](x: myseq[T]): int {.inline.} = x.len
-
+  ```
 
 
 Lifetime-tracking hooks
@@ -119,20 +118,18 @@ to return.
 
 The prototype of this hook for a type `T` needs to be:
 
-.. code-block:: nim
-
+  ```nim
   proc `=destroy`(x: var T)
-
+  ```
 
 The general pattern in `=destroy` looks like:
 
-.. code-block:: nim
-
+  ```nim
   proc `=destroy`(x: var T) =
     # first check if 'x' was moved to somewhere else:
     if x.field != nil:
       freeResource(x.field)
-
+  ```
 
 
 `=sink` hook
@@ -149,20 +146,19 @@ provide `=destroy` and `=copy`, the compiler will take care of the rest.
 
 The prototype of this hook for a type `T` needs to be:
 
-.. code-block:: nim
-
+  ```nim
   proc `=sink`(dest: var T; source: T)
-
+  ```
 
 The general pattern in `=sink` looks like:
 
-.. code-block:: nim
+  ```nim
 
   proc `=sink`(dest: var T; source: T) =
     `=destroy`(dest)
     wasMoved(dest)
     dest.field = source.field
-
+  ```
 
 **Note**: `=sink` does not need to check for self-assignments.
 How self-assignments are handled is explained later in this document.
@@ -177,29 +173,27 @@ operations.
 
 The prototype of this hook for a type `T` needs to be:
 
-.. code-block:: nim
-
+  ```nim
   proc `=copy`(dest: var T; source: T)
-
+  ```
 
 The general pattern in `=copy` looks like:
 
-.. code-block:: nim
-
+  ```nim
   proc `=copy`(dest: var T; source: T) =
     # protect against self-assignments:
     if dest.field != source.field:
       `=destroy`(dest)
       wasMoved(dest)
       dest.field = duplicateResource(source.field)
-
+  ```
 
 The `=copy` proc can be marked with the `{.error.}` pragma. Then any assignment
 that otherwise would lead to a copy is prevented at compile-time. This looks like:
 
-.. code-block:: nim
-
+  ```nim
   proc `=copy`(dest: var T; source: T) {.error.}
+  ```
 
 but a custom error message (e.g., `{.error: "custom error".}`) will not be emitted
 by the compiler. Notice that there is no `=` before the `{.error.}` pragma.
@@ -215,9 +209,9 @@ memory or resources, but memory safety is not compromised.
 
 The prototype of this hook for a type `T` needs to be:
 
-.. code-block:: nim
-
+  ```nim
   proc `=trace`(dest: var T; env: pointer)
+  ```
 
 `env` is used by ORC to keep track of its internal state, it should be passed around
 to calls of the built-in `=trace` operation.
@@ -233,8 +227,7 @@ prevent the automatic creation.
 
 The general pattern in using `=destroy` with `=trace` looks like:
 
-.. code-block:: nim
-
+  ```nim
   type
     Test[T] = object
       size: Natural
@@ -255,6 +248,7 @@ The general pattern in using `=destroy` with `=trace` looks like:
       for i in 0 ..< dest.size: `=trace`(dest.arr[i], env)
 
   # following may be other custom "hooks" as required...
+  ```
 
 **Note**: The `=trace` hooks (which are only used by `--mm:orc`) are currently more experimental and less refined
 than the other hooks.
@@ -307,8 +301,7 @@ not a linear type system.
 The employed static analysis is limited and only concerned with local variables;
 however, object and tuple fields are treated as separate entities:
 
-.. code-block:: nim
-
+  ```nim
   proc consume(x: sink Obj) = discard "no implementation"
 
   proc main =
@@ -316,16 +309,16 @@ however, object and tuple fields are treated as separate entities:
     consume tup[0]
     # ok, only tup[0] was consumed, tup[1] is still alive:
     echo tup[1]
-
+  ```
 
 Sometimes it is required to explicitly `move` a value into its final position:
 
-.. code-block:: nim
-
+  ```nim
   proc main =
     var dest, src: array[10, string]
     # ...
     for i in 0..high(dest): dest[i] = move(src[i])
+  ```
 
 An implementation is allowed, but not required to implement even more move
 optimizations (and the current implementation does not).
@@ -344,11 +337,10 @@ use `{.push sinkInference: on.}` ... `{.pop.}`.
 The `.nosinks`:idx: pragma can be used to disable this inference
 for a single routine:
 
-.. code-block:: nim
-
+  ```nim
   proc addX(x: T; child: T) {.nosinks.} =
     x.s.add child
-
+  ```
 
 The details of the inference algorithm are currently undocumented.
 
@@ -456,8 +448,7 @@ The complex case looks like a variant of `x = f(x)`, we consider
 `x = select(rand() < 0.5, x, y)` here:
 
 
-.. code-block:: nim
-
+  ```nim
   proc select(cond: bool; a, b: sink string): string =
     if cond:
       result = a # moves a into result
@@ -469,13 +460,11 @@ The complex case looks like a variant of `x = f(x)`, we consider
     var y = "xyz"
     # possible self-assignment:
     x = select(true, x, y)
-
+  ```
 
 Is transformed into:
 
-
-.. code-block:: nim
-
+  ```nim
   proc select(cond: bool; a, b: sink string): string =
     try:
       if cond:
@@ -506,6 +495,7 @@ Is transformed into:
     finally:
       `=destroy`(y)
       `=destroy`(x)
+  ```
 
 As can be manually verified, this transformation is correct for
 self-assignments.
@@ -527,8 +517,7 @@ that the pointer does not outlive its origin. No destructor call is injected
 for expressions of type `lent T` or of type `var T`.
 
 
-.. code-block:: nim
-
+  ```nim
   type
     Tree = object
       kids: seq[Tree]
@@ -553,6 +542,7 @@ for expressions of type `lent T` or of type `var T`.
     # everything turned into moves:
     let t = construct(@[construct(@[]), construct(@[])])
     echo t[0] # accessor does not copy the element!
+  ```
 
 
 The cursor pragma
@@ -564,12 +554,12 @@ This means that cyclic structures cannot be freed
 immediately (`--mm:orc`:option: ships with a cycle collector).
 With the `cursor` pragma one can break up cycles declaratively:
 
-.. code-block:: nim
-
+  ```nim
   type
     Node = ref object
       left: Node # owning ref
       right {.cursor.}: Node # non-owning ref
+  ```
 
 But please notice that this is not C++'s weak_ptr, it means the right field is not
 involved in the reference counting, it is a raw pointer without runtime checks.
@@ -578,13 +568,12 @@ Automatic reference counting also has the disadvantage that it introduces overhe
 when iterating over linked structures. The `cursor` pragma can also be used
 to avoid this overhead:
 
-.. code-block:: nim
-
+  ```nim
   var it {.cursor.} = listRoot
   while it != nil:
     use(it)
     it = it.next
-
+  ```
 
 In fact, `cursor` more generally prevents object construction/destruction pairs
 and so can also be useful in other contexts. The alternative solution would be to
@@ -609,13 +598,13 @@ words, we do a compile-time copy-on-write analysis.
 This means that "borrowed" views can be written naturally and without explicit pointer
 indirections:
 
-.. code-block:: nim
-
+  ```nim
   proc main(tab: Table[string, string]) =
     let v = tab["key"] # inferred as cursor because 'tab' is not mutated.
     # no copy into 'v', no destruction of 'v'.
     use(v)
     useItAgain(v)
+  ```
 
 
 Hook lifting
@@ -639,8 +628,7 @@ Hook generation
 
 The ability to override a hook leads to a phase ordering problem:
 
-.. code-block:: nim
-
+  ```nim
   type
     Foo[T] = object
 
@@ -651,7 +639,7 @@ The ability to override a hook leads to a phase ordering problem:
 
   proc `=destroy`[T](f: var Foo[T]) =
     discard
-
+  ```
 
 The solution is to define ``proc `=destroy`[T](f: var Foo[T])`` before
 it is used. The compiler generates implicit
@@ -674,8 +662,7 @@ The experimental `nodestroy`:idx: pragma inhibits hook injections. This can be
 used to specialize the object traversal in order to avoid deep recursions:
 
 
-.. code-block:: nim
-
+  ```nim
   type Node = ref object
     x, y: int32
     left, right: Node
@@ -695,6 +682,7 @@ used to specialize the object traversal in order to avoid deep recursions:
     # notice how even the destructor for 's' is not called implicitly
     # anymore thanks to .nodestroy, so we have to call it on our own:
     `=destroy`(s)
+  ```
 
 
 As can be seen from the example, this solution is hardly sufficient and
@@ -712,19 +700,20 @@ The copy operation is deferred until the first write.
 
 For example:
 
-.. code-block:: nim
+  ```nim
   var x = "abc"  # no copy
   var y = x      # no copy
   y[0] = 'h'     # copy
-
+  ```
 
 The abstraction fails for `addr x` because whether the address is going to be used for mutations is unknown.
 `prepareMutation` needs to be called before the "address of" operation. For example:
 
-.. code-block:: nim
+  ```nim
   var x = "abc"
   var y = x
 
   prepareMutation(y)
   moveMem(addr y[0], addr x[0], 3)
   assert y == "abc"
+  ```
diff --git a/doc/manual.md b/doc/manual.md
index 380cddf2e..0b5098428 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -1306,12 +1306,12 @@ as `MyEnum.value`:
 
     OtherEnum {.pure.} = enum
       valueX, valueY, valueZ, amb
-  ```
 
 
   echo valueA # MyEnum.valueA
   echo amb    # Error: Unclear whether it's MyEnum.amb or OtherEnum.amb
   echo MyEnum.amb # OK.
+  ```
 
 To implement bit fields with enums see `Bit fields <#set-type-bit-fields>`_
 
@@ -2186,7 +2186,7 @@ Unfortunately, `d + 12.Dollar` is not allowed either,
 because `+` is defined for `int` (among others), not for `Dollar`. So
 a `+` for dollars needs to be defined:
 
-  ```
+  ```nim
   proc `+` (x, y: Dollar): Dollar =
     result = Dollar(int(x) + int(y))
   ```
@@ -2194,7 +2194,7 @@ a `+` for dollars needs to be defined:
 It does not make sense to multiply a dollar with a dollar, but with a
 number without unit; and the same holds for division:
 
-  ```
+  ```nim
   proc `*` (x: Dollar, y: int): Dollar =
     result = Dollar(int(x) * y)