Markdown code blocks part 6 (#20292)

This commit is contained in:
Andrey Makarov 2022-09-01 02:39:02 +03:00 • committed by GitHub
commit 0f555110e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 365 additions and 357 deletions

View file

@ -227,11 +227,10 @@ proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
## Named parameters are special because a named parameter can be ## Named parameters are special because a named parameter can be
## gensym'ed and then they have '\`<number>' suffix that we need to ## gensym'ed and then they have '\`<number>' suffix that we need to
## ignore, see compiler / evaltempl.nim, snippet: ## ignore, see compiler / evaltempl.nim, snippet:
## ## ```
## .. code-block:: nim
##
## result.add newIdentNode(getIdent(c.ic, x.name.s & "\`gensym" & $x.id), ## result.add newIdentNode(getIdent(c.ic, x.name.s & "\`gensym" & $x.id),
## if c.instLines: actual.info else: templ.info) ## if c.instLines: actual.info else: templ.info)
## ```
for i in 1..<list.len: for i in 1..<list.len:
let it = list[i].sym let it = list[i].sym
if it.name.id == ident.id or if it.name.id == ident.id or

View file

@ -550,11 +550,10 @@ proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
## For example we have: ## For example we have:
## ## ```
## .. code-block:: nim
## proc myMap[T,S](sIn: seq[T], f: proc(x: T): S): seq[S] = ... ## proc myMap[T,S](sIn: seq[T], f: proc(x: T): S): seq[S] = ...
## proc innerProc[Q,W](q: Q): W = ... ## proc innerProc[Q,W](q: Q): W = ...
## ## ```
## And we want to match: myMap(@[1,2,3], innerProc) ## And we want to match: myMap(@[1,2,3], innerProc)
## This proc (procParamTypeRel) will do the following steps in ## This proc (procParamTypeRel) will do the following steps in
## three different calls: ## three different calls:

View file

@ -15,11 +15,10 @@
# this doesn't matter. However it matters for strings and other complex # this doesn't matter. However it matters for strings and other complex
# types that use the 'node' field; the reason is that slots are # types that use the 'node' field; the reason is that slots are
# re-used in a register based VM. Example: # re-used in a register based VM. Example:
# # ```nim
#.. code-block:: nim # let s = a & b # no matter what, create fresh node
# let s = a & b # no matter what, create fresh node # s = a & b # no matter what, keep the node
# s = a & b # no matter what, keep the node # ```
#
# Also *stores* into non-temporary memory need to perform deep copies: # Also *stores* into non-temporary memory need to perform deep copies:
# a.b = x.y # a.b = x.y
# We used to generate opcAsgn for the *load* of 'x.y' but this is clearly # We used to generate opcAsgn for the *load* of 'x.y' but this is clearly

View file

@ -201,10 +201,9 @@ template `or`*(x, y: NimNode): NimNode =
## Evaluate `x` and when it is not an empty node, return ## Evaluate `x` and when it is not an empty node, return
## it. Otherwise evaluate to `y`. Can be used to chain several ## it. Otherwise evaluate to `y`. Can be used to chain several
## expressions to get the first expression that is not empty. ## expressions to get the first expression that is not empty.
## ## ```
## .. code-block:: nim
##
## let node = mightBeEmpty() or mightAlsoBeEmpty() or fallbackNode ## let node = mightBeEmpty() or mightAlsoBeEmpty() or fallbackNode
## ```
let arg = x let arg = x
if arg != nil and arg.kind != nnkEmpty: if arg != nil and arg.kind != nnkEmpty:
@ -545,11 +544,10 @@ proc getAst*(macroOrTemplate: untyped): NimNode {.magic: "ExpandToAst", noSideEf
## Obtains the AST nodes returned from a macro or template invocation. ## Obtains the AST nodes returned from a macro or template invocation.
## See also `genasts.genAst`. ## See also `genasts.genAst`.
## Example: ## Example:
## ## ```
## .. code-block:: nim
##
## macro FooMacro() = ## macro FooMacro() =
## var ast = getAst(BarTemplate()) ## var ast = getAst(BarTemplate())
## ```
proc quote*(bl: typed, op = "``"): NimNode {.magic: "QuoteAst", noSideEffect.} = proc quote*(bl: typed, op = "``"): NimNode {.magic: "QuoteAst", noSideEffect.} =
## Quasi-quoting operator. ## Quasi-quoting operator.
@ -1003,18 +1001,18 @@ macro dumpTree*(s: untyped): untyped = echo s.treeRepr
## a certain expression/statement. ## a certain expression/statement.
## ##
## For example: ## For example:
## ## ```
## .. code-block:: nim ## dumpTree:
## dumpTree: ## echo "Hello, World!"
## echo "Hello, World!" ## ```
## ##
## Outputs: ## Outputs:
## ## ```
## .. code-block:: ## StmtList
## StmtList ## Command
## Command ## Ident "echo"
## Ident "echo" ## StrLit "Hello, World!"
## StrLit "Hello, World!" ## ```
## ##
## Also see `dumpAstGen` and `dumpLisp`. ## Also see `dumpAstGen` and `dumpLisp`.
@ -1027,18 +1025,18 @@ macro dumpLisp*(s: untyped): untyped = echo s.lispRepr(indented = true)
## a certain expression/statement. ## a certain expression/statement.
## ##
## For example: ## For example:
## ## ```
## .. code-block:: nim ## dumpLisp:
## dumpLisp: ## echo "Hello, World!"
## echo "Hello, World!" ## ```
## ##
## Outputs: ## Outputs:
## ## ```
## .. code-block:: ## (StmtList
## (StmtList ## (Command
## (Command ## (Ident "echo")
## (Ident "echo") ## (StrLit "Hello, World!")))
## (StrLit "Hello, World!"))) ## ```
## ##
## Also see `dumpAstGen` and `dumpTree`. ## Also see `dumpAstGen` and `dumpTree`.
@ -1050,20 +1048,20 @@ macro dumpAstGen*(s: untyped): untyped = echo s.astGenRepr
## outputs and then copying the snippets into the macro for modification. ## outputs and then copying the snippets into the macro for modification.
## ##
## For example: ## For example:
## ## ```
## .. code-block:: nim ## dumpAstGen:
## dumpAstGen: ## echo "Hello, World!"
## echo "Hello, World!" ## ```
## ##
## Outputs: ## Outputs:
## ## ```
## .. code-block:: nim ## nnkStmtList.newTree(
## nnkStmtList.newTree( ## nnkCommand.newTree(
## nnkCommand.newTree( ## newIdentNode("echo"),
## newIdentNode("echo"), ## newLit("Hello, World!")
## newLit("Hello, World!") ## )
## ) ## )
## ) ## ```
## ##
## Also see `dumpTree` and `dumpLisp`. ## Also see `dumpTree` and `dumpLisp`.
@ -1128,23 +1126,22 @@ proc newIdentDefs*(name, kind: NimNode;
## `let` or `var` blocks may have an empty `kind` node if the ## `let` or `var` blocks may have an empty `kind` node if the
## identifier is being assigned a value. Example: ## identifier is being assigned a value. Example:
## ##
## .. code-block:: nim ## ```
##
## var varSection = newNimNode(nnkVarSection).add( ## var varSection = newNimNode(nnkVarSection).add(
## newIdentDefs(ident("a"), ident("string")), ## newIdentDefs(ident("a"), ident("string")),
## newIdentDefs(ident("b"), newEmptyNode(), newLit(3))) ## newIdentDefs(ident("b"), newEmptyNode(), newLit(3)))
## # --> var ## # --> var
## # a: string ## # a: string
## # b = 3 ## # b = 3
## ```
## ##
## If you need to create multiple identifiers you need to use the lower level ## If you need to create multiple identifiers you need to use the lower level
## `newNimNode`: ## `newNimNode`:
## ## ```
## .. code-block:: nim
##
## result = newNimNode(nnkIdentDefs).add( ## result = newNimNode(nnkIdentDefs).add(
## ident("a"), ident("b"), ident("c"), ident("string"), ## ident("a"), ident("b"), ident("c"), ident("string"),
## newStrLitNode("Hello")) ## newStrLitNode("Hello"))
## ```
newNimNode(nnkIdentDefs).add(name, kind, default) newNimNode(nnkIdentDefs).add(name, kind, default)
proc newNilLit*(): NimNode = proc newNilLit*(): NimNode =
@ -1191,14 +1188,12 @@ proc newProc*(name = newEmptyNode();
proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]): NimNode = proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]): NimNode =
## Constructor for `if` statements. ## Constructor for `if` statements.
## ## ```
## .. code-block:: nim ## newIfStmt(
## ## (Ident, StmtList),
## newIfStmt( ## ...
## (Ident, StmtList), ## )
## ... ## ```
## )
##
result = newNimNode(nnkIfStmt) result = newNimNode(nnkIfStmt)
if len(branches) < 1: if len(branches) < 1:
error("If statement must have at least one branch") error("If statement must have at least one branch")
@ -1209,17 +1204,15 @@ proc newEnum*(name: NimNode, fields: openArray[NimNode],
public, pure: bool): NimNode = public, pure: bool): NimNode =
## Creates a new enum. `name` must be an ident. Fields are allowed to be ## Creates a new enum. `name` must be an ident. Fields are allowed to be
## either idents or EnumFieldDef ## either idents or EnumFieldDef:
## ## ```
## .. code-block:: nim ## newEnum(
## ## name = ident("Colors"),
## newEnum( ## fields = [ident("Blue"), ident("Red")],
## name = ident("Colors"), ## public = true, pure = false)
## fields = [ident("Blue"), ident("Red")],
## public = true, pure = false)
##
## # type Colors* = Blue Red
## ##
## # type Colors* = Blue Red
## ```
expectKind name, nnkIdent expectKind name, nnkIdent
if len(fields) < 1: if len(fields) < 1:
@ -1383,10 +1376,10 @@ iterator children*(n: NimNode): NimNode {.inline.} =
template findChild*(n: NimNode; cond: untyped): NimNode {.dirty.} = template findChild*(n: NimNode; cond: untyped): NimNode {.dirty.} =
## Find the first child node matching condition (or nil). ## Find the first child node matching condition (or nil).
## ## ```
## .. code-block:: nim
## var res = findChild(n, it.kind == nnkPostfix and ## var res = findChild(n, it.kind == nnkPostfix and
## it.basename.ident == ident"foo") ## it.basename.ident == ident"foo")
## ```
block: block:
var res: NimNode var res: NimNode
for it in n.children: for it in n.children:
@ -1491,7 +1484,7 @@ macro expandMacros*(body: typed): untyped =
## ##
## For instance, ## For instance,
## ##
## .. code-block:: nim ## ```
## import std/[sugar, macros] ## import std/[sugar, macros]
## ##
## let ## let
@ -1499,6 +1492,7 @@ macro expandMacros*(body: typed): untyped =
## y = 20 ## y = 20
## expandMacros: ## expandMacros:
## dump(x + y) ## dump(x + y)
## ```
## ##
## will actually dump `x + y`, but at the same time will print at ## will actually dump `x + y`, but at the same time will print at
## compile time the expansion of the `dump` macro, which in this ## compile time the expansion of the `dump` macro, which in this
@ -1608,7 +1602,7 @@ macro hasCustomPragma*(n: typed, cp: typed{nkSym}): untyped =
## ##
## See also `getCustomPragmaVal`_. ## See also `getCustomPragmaVal`_.
## ##
## .. code-block:: nim ## ```
## template myAttr() {.pragma.} ## template myAttr() {.pragma.}
## type ## type
## MyObj = object ## MyObj = object
@ -1619,6 +1613,7 @@ macro hasCustomPragma*(n: typed, cp: typed{nkSym}): untyped =
## var o: MyObj ## var o: MyObj
## assert(o.myField.hasCustomPragma(myAttr)) ## assert(o.myField.hasCustomPragma(myAttr))
## assert(myProc.hasCustomPragma(myAttr)) ## assert(myProc.hasCustomPragma(myAttr))
## ```
let pragmaNode = customPragmaNode(n) let pragmaNode = customPragmaNode(n)
for p in pragmaNode: for p in pragmaNode:
if (p.kind == nnkSym and p == cp) or if (p.kind == nnkSym and p == cp) or
@ -1632,7 +1627,7 @@ macro getCustomPragmaVal*(n: typed, cp: typed{nkSym}): untyped =
## ##
## See also `hasCustomPragma`_. ## See also `hasCustomPragma`_.
## ##
## .. code-block:: nim ## ```
## template serializationKey(key: string) {.pragma.} ## template serializationKey(key: string) {.pragma.}
## type ## type
## MyObj {.serializationKey: "mo".} = object ## MyObj {.serializationKey: "mo".} = object
@ -1641,6 +1636,7 @@ macro getCustomPragmaVal*(n: typed, cp: typed{nkSym}): untyped =
## assert(o.myField.getCustomPragmaVal(serializationKey) == "mf") ## assert(o.myField.getCustomPragmaVal(serializationKey) == "mf")
## assert(o.getCustomPragmaVal(serializationKey) == "mo") ## assert(o.getCustomPragmaVal(serializationKey) == "mo")
## assert(MyObj.getCustomPragmaVal(serializationKey) == "mo") ## assert(MyObj.getCustomPragmaVal(serializationKey) == "mo")
## ```
result = nil result = nil
let pragmaNode = customPragmaNode(n) let pragmaNode = customPragmaNode(n)
for p in pragmaNode: for p in pragmaNode:
@ -1727,25 +1723,26 @@ proc extractDocCommentsAndRunnables*(n: NimNode): NimNode =
## runnableExamples in `a`, stopping at the first child that is neither. ## runnableExamples in `a`, stopping at the first child that is neither.
## Example: ## Example:
## ##
## .. code-block:: nim ## ```
## import std/macros ## import std/macros
## macro transf(a): untyped = ## macro transf(a): untyped =
## result = quote do: ## result = quote do:
## proc fun2*() = discard ## proc fun2*() = discard
## let header = extractDocCommentsAndRunnables(a.body) ## let header = extractDocCommentsAndRunnables(a.body)
## # correct usage: rest is appended ## # correct usage: rest is appended
## result.body = header ## result.body = header
## result.body.add quote do: discard # just an example ## result.body.add quote do: discard # just an example
## # incorrect usage: nesting inside a nnkStmtList: ## # incorrect usage: nesting inside a nnkStmtList:
## # result.body = quote do: (`header`; discard) ## # result.body = quote do: (`header`; discard)
## ##
## proc fun*() {.transf.} = ## proc fun*() {.transf.} =
## ## first comment ## ## first comment
## runnableExamples: discard ## runnableExamples: discard
## runnableExamples: discard ## runnableExamples: discard
## ## last comment ## ## last comment
## discard # first statement after doc comments + runnableExamples ## discard # first statement after doc comments + runnableExamples
## ## not docgen'd ## ## not docgen'd
## ```
result = newStmtList() result = newStmtList()
for ni in n: for ni in n:

View file

@ -19,10 +19,9 @@
## All `db_*` modules support the same form of parameter substitution. ## All `db_*` modules support the same form of parameter substitution.
## That is, using the `?` (question mark) to signify the place where a ## That is, using the `?` (question mark) to signify the place where a
## value should be placed. For example: ## value should be placed. For example:
## ## ```
## .. code-block:: Nim ## sql"INSERT INTO myTable (colA, colB, colC) VALUES (?, ?, ?)"
## sql"INSERT INTO myTable (colA, colB, colC) VALUES (?, ?, ?)" ## ```
##
## ##
## Examples ## Examples
## ======== ## ========
@ -30,57 +29,60 @@
## Opening a connection to a database ## Opening a connection to a database
## ---------------------------------- ## ----------------------------------
## ##
## .. code-block:: Nim ## ```
## import std/db_mysql ## import std/db_mysql
## let db = open("localhost", "user", "password", "dbname") ## let db = open("localhost", "user", "password", "dbname")
## db.close() ## db.close()
## ```
## ##
## Creating a table ## Creating a table
## ---------------- ## ----------------
## ##
## .. code-block:: Nim ## ```
## db.exec(sql"DROP TABLE IF EXISTS myTable") ## db.exec(sql"DROP TABLE IF EXISTS myTable")
## db.exec(sql("""CREATE TABLE myTable ( ## db.exec(sql("""CREATE TABLE myTable (
## id integer, ## id integer,
## name varchar(50) not null)""")) ## name varchar(50) not null)"""))
## ```
## ##
## Inserting data ## Inserting data
## -------------- ## --------------
## ##
## .. code-block:: Nim ## ```
## db.exec(sql"INSERT INTO myTable (id, name) VALUES (0, ?)", ## db.exec(sql"INSERT INTO myTable (id, name) VALUES (0, ?)",
## "Dominik") ## "Dominik")
## ```
## ##
## Larger example ## Larger example
## -------------- ## --------------
## ##
## .. code-block:: Nim ## ```
## import std/[db_mysql, math]
## ##
## import std/[db_mysql, math] ## let theDb = open("localhost", "nim", "nim", "test")
## ##
## let theDb = open("localhost", "nim", "nim", "test") ## theDb.exec(sql"Drop table if exists myTestTbl")
## theDb.exec(sql("create table myTestTbl (" &
## " Id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, " &
## " Name VARCHAR(50) NOT NULL, " &
## " i INT(11), " &
## " f DECIMAL(18,10))"))
## ##
## theDb.exec(sql"Drop table if exists myTestTbl") ## theDb.exec(sql"START TRANSACTION")
## theDb.exec(sql("create table myTestTbl (" & ## for i in 1..1000:
## " Id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, " & ## theDb.exec(sql"INSERT INTO myTestTbl (name,i,f) VALUES (?,?,?)",
## " Name VARCHAR(50) NOT NULL, " & ## "Item#" & $i, i, sqrt(i.float))
## " i INT(11), " & ## theDb.exec(sql"COMMIT")
## " f DECIMAL(18,10))"))
## ##
## theDb.exec(sql"START TRANSACTION") ## for x in theDb.fastRows(sql"select * from myTestTbl"):
## for i in 1..1000: ## echo x
## theDb.exec(sql"INSERT INTO myTestTbl (name,i,f) VALUES (?,?,?)",
## "Item#" & $i, i, sqrt(i.float))
## theDb.exec(sql"COMMIT")
## ##
## for x in theDb.fastRows(sql"select * from myTestTbl"): ## let id = theDb.tryInsertId(sql"INSERT INTO myTestTbl (name,i,f) VALUES (?,?,?)",
## echo x ## "Item#1001", 1001, sqrt(1001.0))
## echo "Inserted item: ", theDb.getValue(sql"SELECT name FROM myTestTbl WHERE id=?", id)
## ##
## let id = theDb.tryInsertId(sql"INSERT INTO myTestTbl (name,i,f) VALUES (?,?,?)", ## theDb.close()
## "Item#1001", 1001, sqrt(1001.0)) ## ```
## echo "Inserted item: ", theDb.getValue(sql"SELECT name FROM myTestTbl WHERE id=?", id)
##
## theDb.close()
import strutils, mysql import strutils, mysql

File diff suppressed because it is too large Load diff