Markdown code blocks migration part 8 (#22478)

This commit is contained in:
Andrey Makarov
2023-08-14 22:27:36 -06:00
committed by GitHub
parent 1927ae72d0
commit a660c17d30
46 changed files with 725 additions and 629 deletions

View File

@@ -110,16 +110,16 @@ proc respond*(req: Request, code: HttpCode, content: string,
## This procedure will **not** close the client socket.
##
## Example:
##
## .. code-block:: Nim
## import std/json
## proc handler(req: Request) {.async.} =
## if req.url.path == "/hello-world":
## let msg = %* {"message": "Hello World"}
## let headers = newHttpHeaders([("Content-Type","application/json")])
## await req.respond(Http200, $msg, headers)
## else:
## await req.respond(Http404, "Not Found")
## ```Nim
## import std/json
## proc handler(req: Request) {.async.} =
## if req.url.path == "/hello-world":
## let msg = %* {"message": "Hello World"}
## let headers = newHttpHeaders([("Content-Type","application/json")])
## await req.respond(Http200, $msg, headers)
## else:
## await req.respond(Http404, "Not Found")
## ```
var msg = "HTTP/1.1 " & $code & "\c\L"
if headers != nil:

View File

@@ -25,7 +25,9 @@
## `difference <#difference,HashSet[A],HashSet[A]>`_, and
## `symmetric difference <#symmetricDifference,HashSet[A],HashSet[A]>`_
##
## .. code-block::
## **Examples:**
##
## ```Nim
## echo toHashSet([9, 5, 1]) # {9, 1, 5}
## echo toOrderedSet([9, 5, 1]) # {9, 5, 1}
##
@@ -37,7 +39,7 @@
## echo s1 - s2 # {1, 9}
## echo s1 * s2 # {5}
## echo s1 -+- s2 # {9, 1, 3, 7}
##
## ```
##
## Note: The data types declared here have *value semantics*: This means
## that `=` performs a copy of the set.
@@ -249,7 +251,7 @@ iterator items*[A](s: HashSet[A]): A =
## If you need a sequence with the elements you can use `sequtils.toSeq
## template <sequtils.html#toSeq.t,untyped>`_.
##
## .. code-block::
## ```Nim
## type
## pair = tuple[a, b: int]
## var
@@ -262,6 +264,7 @@ iterator items*[A](s: HashSet[A]): A =
## assert a.len == 2
## echo b
## # --> {(a: 1, b: 3), (a: 0, b: 4)}
## ```
let length = s.len
for h in 0 .. high(s.data):
if isFilled(s.data[h].hcode):
@@ -586,12 +589,12 @@ proc `$`*[A](s: HashSet[A]): string =
## any moment and values are not escaped.
##
## **Examples:**
##
## .. code-block::
## ```Nim
## echo toHashSet([2, 4, 5])
## # --> {2, 4, 5}
## echo toHashSet(["no", "esc'aping", "is \" provided"])
## # --> {no, esc'aping, is " provided}
## ```
dollarImpl()
@@ -874,12 +877,12 @@ proc `$`*[A](s: OrderedSet[A]): string =
## any moment and values are not escaped.
##
## **Examples:**
##
## .. code-block::
## ```Nim
## echo toOrderedSet([2, 4, 5])
## # --> {2, 4, 5}
## echo toOrderedSet(["no", "esc'aping", "is \" provided"])
## # --> {no, esc'aping, is " provided}
## ```
dollarImpl()
@@ -890,7 +893,7 @@ iterator items*[A](s: OrderedSet[A]): A =
## If you need a sequence with the elements you can use `sequtils.toSeq
## template <sequtils.html#toSeq.t,untyped>`_.
##
## .. code-block::
## ```Nim
## var a = initOrderedSet[int]()
## for value in [9, 2, 1, 5, 1, 8, 4, 2]:
## a.incl(value)
@@ -902,6 +905,7 @@ iterator items*[A](s: OrderedSet[A]): A =
## # --> Got 5
## # --> Got 8
## # --> Got 4
## ```
let length = s.len
forAllOrderedPairs:
yield s.data[h].key

View File

@@ -191,8 +191,7 @@ proc withKey*[A, B](t: var SharedTable[A, B], key: A,
##
## Example usage:
##
## .. code-block:: nim
##
## ```nim
## # If value exists, decrement it.
## # If it becomes zero or less, delete the key
## t.withKey(1'i64) do (k: int64, v: var int, pairExists: var bool):
@@ -200,6 +199,7 @@ proc withKey*[A, B](t: var SharedTable[A, B], key: A,
## dec v
## if v <= 0:
## pairExists = false
## ```
withLock t:
var hc: Hash
var index = rawGet(t, key, hc)

View File

@@ -136,14 +136,11 @@ runnableExamples:
## a more complex object as a key you will be greeted by a strange compiler
## error:
##
## .. code::
##
## Error: type mismatch: got (Person)
## but expected one of:
## hashes.hash(x: openArray[A]): Hash
## hashes.hash(x: int): Hash
## hashes.hash(x: float): Hash
## …
## Error: type mismatch: got (Person)
## but expected one of:
## hashes.hash(x: openArray[A]): Hash
## hashes.hash(x: int): Hash
## hashes.hash(x: float): Hash
##
## What is happening here is that the types used for table keys require to have
## a `hash()` proc which will convert them to a `Hash <hashes.html#Hash>`_
@@ -678,7 +675,7 @@ iterator pairs*[A, B](t: Table[A, B]): (A, B) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## let a = {
## 'o': [1, 5, 7, 9],
## 'e': [2, 4, 6, 8]
@@ -692,6 +689,7 @@ iterator pairs*[A, B](t: Table[A, B]): (A, B) =
## # value: [2, 4, 6, 8]
## # key: o
## # value: [1, 5, 7, 9]
## ```
let L = len(t)
for h in 0 .. high(t.data):
if isFilled(t.data[h].hcode):
@@ -1127,7 +1125,7 @@ iterator pairs*[A, B](t: TableRef[A, B]): (A, B) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## let a = {
## 'o': [1, 5, 7, 9],
## 'e': [2, 4, 6, 8]
@@ -1141,6 +1139,7 @@ iterator pairs*[A, B](t: TableRef[A, B]): (A, B) =
## # value: [2, 4, 6, 8]
## # key: o
## # value: [1, 5, 7, 9]
## ```
let L = len(t)
for h in 0 .. high(t.data):
if isFilled(t.data[h].hcode):
@@ -1703,7 +1702,7 @@ iterator pairs*[A, B](t: OrderedTable[A, B]): (A, B) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## let a = {
## 'o': [1, 5, 7, 9],
## 'e': [2, 4, 6, 8]
@@ -1717,6 +1716,7 @@ iterator pairs*[A, B](t: OrderedTable[A, B]): (A, B) =
## # value: [1, 5, 7, 9]
## # key: e
## # value: [2, 4, 6, 8]
## ```
let L = len(t)
forAllOrderedPairs:
@@ -2113,7 +2113,7 @@ iterator pairs*[A, B](t: OrderedTableRef[A, B]): (A, B) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## let a = {
## 'o': [1, 5, 7, 9],
## 'e': [2, 4, 6, 8]
@@ -2127,6 +2127,7 @@ iterator pairs*[A, B](t: OrderedTableRef[A, B]): (A, B) =
## # value: [1, 5, 7, 9]
## # key: e
## # value: [2, 4, 6, 8]
## ```
let L = len(t)
forAllOrderedPairs:
@@ -2526,7 +2527,7 @@ iterator pairs*[A](t: CountTable[A]): (A, int) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## let a = toCountTable("abracadabra")
##
## for k, v in pairs(a):
@@ -2543,6 +2544,7 @@ iterator pairs*[A](t: CountTable[A]): (A, int) =
## # value: 1
## # key: r
## # value: 2
## ```
let L = len(t)
for h in 0 .. high(t.data):
if t.data[h].val != 0:
@@ -2806,7 +2808,7 @@ iterator pairs*[A](t: CountTableRef[A]): (A, int) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## let a = newCountTable("abracadabra")
##
## for k, v in pairs(a):
@@ -2823,6 +2825,7 @@ iterator pairs*[A](t: CountTableRef[A]): (A, int) =
## # value: 1
## # key: r
## # value: 2
## ```
let L = len(t)
for h in 0 .. high(t.data):
if t.data[h].val != 0:
@@ -2915,4 +2918,4 @@ proc hash*[K,V](s: OrderedTable[K,V]): Hash =
proc hash*[V](s: CountTable[V]): Hash =
for p in pairs(s):
result = result xor hash(p)
result = !$result
result = !$result

View File

@@ -18,13 +18,14 @@ type
proc `==`*(a, b: Color): bool {.borrow.}
## Compares two colors.
##
## .. code-block::
## ```Nim
## var
## a = Color(0xff_00_ff)
## b = colFuchsia
## c = Color(0x00_ff_cc)
## assert a == b
## assert not (a == c)
## ```
template extract(a: Color, r, g, b: untyped) =
var r = a.int shr 16 and 0xff

View File

@@ -18,12 +18,11 @@
##
## The above output could be the result of a code snippet like:
##
## .. code-block:: nim
##
## ```nim
## if detectOs(Ubuntu):
## foreignDep "lbiblas-dev"
## foreignDep "libvoodoo"
##
## ```
##
## See `packaging <packaging.html>`_ for hints on distributing Nim using OS packages.

View File

@@ -30,9 +30,10 @@
## Examples
## ========
##
## .. code-block:: Nim
## ```Nim
## var nim = "Nim"
## echo h1(a(href="https://nim-lang.org", nim))
## ```
##
## Writes the string:
##

View File

@@ -12,10 +12,9 @@
##
## It can be used to parse a wild HTML document and output it as valid XHTML
## document (well, if you are lucky):
##
## .. code-block:: Nim
##
## ```Nim
## echo loadHtml("mydirty.html")
## ```
##
## Every tag in the resulting tree is in lower case.
##
@@ -29,9 +28,7 @@
## and write back the modified version. In this case we look for hyperlinks
## ending with the extension `.rst` and convert them to `.html`.
##
## .. code-block:: Nim
## :test:
##
## ```Nim test
## import std/htmlparser
## import std/xmltree # To use '$' for XmlNode
## import std/strtabs # To access XmlAttributes
@@ -48,6 +45,7 @@
## a.attrs["href"] = dir / filename & ".html"
##
## writeFile("output.html", $html)
## ```
import strutils, streams, parsexml, xmltree, unicode, strtabs

View File

@@ -18,18 +18,19 @@
## This example uses HTTP GET to retrieve
## `http://google.com`:
##
## .. code-block:: Nim
## ```Nim
## import std/httpclient
## var client = newHttpClient()
## try:
## echo client.getContent("http://google.com")
## finally:
## client.close()
## ```
##
## The same action can also be performed asynchronously, simply use the
## `AsyncHttpClient`:
##
## .. code-block:: Nim
## ```Nim
## import std/[asyncdispatch, httpclient]
##
## proc asyncProc(): Future[string] {.async.} =
@@ -40,6 +41,7 @@
## client.close()
##
## echo waitFor asyncProc()
## ```
##
## The functionality implemented by `HttpClient` and `AsyncHttpClient`
## is the same, so you can use whichever one suits you best in the examples
@@ -59,7 +61,7 @@
## uses `multipart/form-data` as the `Content-Type` to send the HTML to be
## validated to the server.
##
## .. code-block:: Nim
## ```Nim
## var client = newHttpClient()
## var data = newMultipartData()
## data["output"] = "soap12"
@@ -69,13 +71,14 @@
## echo client.postContent("http://validator.w3.org/check", multipart=data)
## finally:
## client.close()
## ```
##
## To stream files from disk when performing the request, use `addFiles`.
##
## **Note:** This will allocate a new `Mimetypes` database every time you call
## it, you can pass your own via the `mimeDb` parameter to avoid this.
##
## .. code-block:: Nim
## ```Nim
## let mimes = newMimetypes()
## var client = newHttpClient()
## var data = newMultipartData()
@@ -84,12 +87,13 @@
## echo client.postContent("http://validator.w3.org/check", multipart=data)
## finally:
## client.close()
## ```
##
## You can also make post requests with custom headers.
## This example sets `Content-Type` to `application/json`
## and uses a json object for the body
##
## .. code-block:: Nim
## ```Nim
## import std/[httpclient, json]
##
## let client = newHttpClient()
@@ -102,6 +106,7 @@
## echo response.status
## finally:
## client.close()
## ```
##
## Progress reporting
## ==================
@@ -110,27 +115,29 @@
## This callback will be executed every second with information about the
## progress of the HTTP request.
##
## .. code-block:: Nim
## import std/[asyncdispatch, httpclient]
## ```Nim
## import std/[asyncdispatch, httpclient]
##
## proc onProgressChanged(total, progress, speed: BiggestInt) {.async.} =
## echo("Downloaded ", progress, " of ", total)
## echo("Current rate: ", speed div 1000, "kb/s")
## proc onProgressChanged(total, progress, speed: BiggestInt) {.async.} =
## echo("Downloaded ", progress, " of ", total)
## echo("Current rate: ", speed div 1000, "kb/s")
##
## proc asyncProc() {.async.} =
## var client = newAsyncHttpClient()
## client.onProgressChanged = onProgressChanged
## try:
## discard await client.getContent("http://speedtest-ams2.digitalocean.com/100mb.test")
## finally:
## client.close()
## proc asyncProc() {.async.} =
## var client = newAsyncHttpClient()
## client.onProgressChanged = onProgressChanged
## try:
## discard await client.getContent("http://speedtest-ams2.digitalocean.com/100mb.test")
## finally:
## client.close()
##
## waitFor asyncProc()
## waitFor asyncProc()
## ```
##
## If you would like to remove the callback simply set it to `nil`.
##
## .. code-block:: Nim
## ```Nim
## client.onProgressChanged = nil
## ```
##
## .. warning:: The `total` reported by httpclient may be 0 in some cases.
##
@@ -152,9 +159,10 @@
##
## Example of setting SSL verification parameters in a new client:
##
## .. code-block:: Nim
## import httpclient
## var client = newHttpClient(sslContext=newContext(verifyMode=CVerifyPeer))
## ```Nim
## import httpclient
## var client = newHttpClient(sslContext=newContext(verifyMode=CVerifyPeer))
## ```
##
## There are three options for verify mode:
##
@@ -183,10 +191,11 @@
##
## Here is how to set a timeout when creating an `HttpClient` instance:
##
## .. code-block:: Nim
## import std/httpclient
## ```Nim
## import std/httpclient
##
## let client = newHttpClient(timeout = 42)
## let client = newHttpClient(timeout = 42)
## ```
##
## Proxy
## =====
@@ -197,36 +206,39 @@
##
## Some examples on how to configure a Proxy for `HttpClient`:
##
## .. code-block:: Nim
## import std/httpclient
## ```Nim
## import std/httpclient
##
## let myProxy = newProxy("http://myproxy.network")
## let client = newHttpClient(proxy = myProxy)
## let myProxy = newProxy("http://myproxy.network")
## let client = newHttpClient(proxy = myProxy)
## ```
##
## Use proxies with basic authentication:
##
## .. code-block:: Nim
## import std/httpclient
##
## let myProxy = newProxy("http://myproxy.network", auth="user:password")
## let client = newHttpClient(proxy = myProxy)
## ```Nim
## import std/httpclient
##
## let myProxy = newProxy("http://myproxy.network", auth="user:password")
## let client = newHttpClient(proxy = myProxy)
## ```
##
## Get Proxy URL from environment variables:
##
## .. code-block:: Nim
## import std/httpclient
## ```Nim
## import std/httpclient
##
## var url = ""
## try:
## if existsEnv("http_proxy"):
## url = getEnv("http_proxy")
## elif existsEnv("https_proxy"):
## url = getEnv("https_proxy")
## except ValueError:
## echo "Unable to parse proxy from environment variables."
## var url = ""
## try:
## if existsEnv("http_proxy"):
## url = getEnv("http_proxy")
## elif existsEnv("https_proxy"):
## url = getEnv("https_proxy")
## except ValueError:
## echo "Unable to parse proxy from environment variables."
##
## let myProxy = newProxy(url = url)
## let client = newHttpClient(proxy = myProxy)
## let myProxy = newProxy(url = url)
## let client = newHttpClient(proxy = myProxy)
## ```
##
## Redirects
## =========
@@ -237,10 +249,11 @@
##
## Here you can see an example about how to set the `maxRedirects` of `HttpClient`:
##
## .. code-block:: Nim
## import std/httpclient
## ```Nim
## import std/httpclient
##
## let client = newHttpClient(maxRedirects = 0)
## let client = newHttpClient(maxRedirects = 0)
## ```
##
import std/private/since
@@ -429,8 +442,9 @@ proc add*(p: MultipartData, xs: MultipartEntries): MultipartData
## Add a list of multipart entries to the multipart data `p`. All values are
## added without a filename and without a content type.
##
## .. code-block:: Nim
## ```Nim
## data.add({"action": "login", "format": "json"})
## ```
for name, content in xs.items:
p.add(name, content)
result = p
@@ -439,8 +453,9 @@ proc newMultipartData*(xs: MultipartEntries): MultipartData =
## Create a new multipart data object and fill it with the entries `xs`
## directly.
##
## .. code-block:: Nim
## ```Nim
## var data = newMultipartData({"action": "login", "format": "json"})
## ```
result = MultipartData()
for entry in xs:
result.add(entry.name, entry.content)
@@ -455,8 +470,9 @@ proc addFiles*(p: MultipartData, xs: openArray[tuple[name, file: string]],
## Raises an `IOError` if the file cannot be opened or reading fails. To
## manually specify file content, filename and MIME type, use `[]=` instead.
##
## .. code-block:: Nim
## ```Nim
## data.addFiles({"uploaded_file": "public/test.html"})
## ```
for name, file in xs.items:
var contentType: string
let (_, fName, ext) = splitFile(file)
@@ -470,8 +486,9 @@ proc `[]=`*(p: MultipartData, name, content: string) {.inline.} =
## Add a multipart entry to the multipart data `p`. The value is added
## without a filename and without a content type.
##
## .. code-block:: Nim
## ```Nim
## data["username"] = "NimUser"
## ```
p.add(name, content)
proc `[]=`*(p: MultipartData, name: string,
@@ -479,9 +496,10 @@ proc `[]=`*(p: MultipartData, name: string,
## Add a file to the multipart data `p`, specifying filename, contentType
## and content manually.
##
## .. code-block:: Nim
## ```Nim
## data["uploaded_file"] = ("test.html", "text/html",
## "<html><head></head><body><p>test</p></body></html>")
## ```
p.add(name, file.content, file.name, file.contentType, useStream = false)
proc getBoundary(p: MultipartData): string =
@@ -688,15 +706,15 @@ proc close*(client: HttpClient | AsyncHttpClient) =
client.connected = false
proc getSocket*(client: HttpClient): Socket {.inline.} =
## Get network socket, useful if you want to find out more details about the connection
## Get network socket, useful if you want to find out more details about the connection.
##
## this example shows info about local and remote endpoints
## This example shows info about local and remote endpoints:
##
## .. code-block:: Nim
## ```Nim
## if client.connected:
## echo client.getSocket.getLocalAddr
## echo client.getSocket.getPeerAddr
##
## ```
return client.socket
proc getSocket*(client: AsyncHttpClient): AsyncSocket {.inline.} =

View File

@@ -41,13 +41,14 @@
## For a `JsonNode` who's kind is `JObject`, you can access its fields using
## the `[]` operator. The following example shows how to do this:
##
## .. code-block:: Nim
## ```Nim
## import std/json
##
## let jsonNode = parseJson("""{"key": 3.14}""")
##
## doAssert jsonNode.kind == JObject
## doAssert jsonNode["key"].kind == JFloat
## ```
##
## Reading values
## --------------
@@ -62,12 +63,13 @@
##
## To retrieve the value of `"key"` you can do the following:
##
## .. code-block:: Nim
## ```Nim
## import std/json
##
## let jsonNode = parseJson("""{"key": 3.14}""")
##
## doAssert jsonNode["key"].getFloat() == 3.14
## ```
##
## **Important:** The `[]` operator will raise an exception when the
## specified field does not exist.
@@ -79,7 +81,7 @@
## when the field is not found. The `get`-family of procedures will return a
## type's default value when called on `nil`.
##
## .. code-block:: Nim
## ```Nim
## import std/json
##
## let jsonNode = parseJson("{}")
@@ -88,6 +90,7 @@
## doAssert jsonNode{"nope"}.getFloat() == 0
## doAssert jsonNode{"nope"}.getStr() == ""
## doAssert jsonNode{"nope"}.getBool() == false
## ```
##
## Using default values
## --------------------
@@ -95,7 +98,7 @@
## The `get`-family helpers also accept an additional parameter which allow
## you to fallback to a default value should the key's values be `null`:
##
## .. code-block:: Nim
## ```Nim
## import std/json
##
## let jsonNode = parseJson("""{"key": 3.14, "key2": null}""")
@@ -103,6 +106,7 @@
## doAssert jsonNode["key"].getFloat(6.28) == 3.14
## doAssert jsonNode["key2"].getFloat(3.14) == 3.14
## doAssert jsonNode{"nope"}.getFloat(3.14) == 3.14 # note the {}
## ```
##
## Unmarshalling
## -------------
@@ -113,7 +117,7 @@
## Note: Use `Option <options.html#Option>`_ for keys sometimes missing in json
## responses, and backticks around keys with a reserved keyword as name.
##
## .. code-block:: Nim
## ```Nim
## import std/json
## import std/options
##
@@ -127,6 +131,7 @@
## let user = to(userJson, User)
## if user.`type`.isSome():
## assert user.`type`.get() != "robot"
## ```
##
## Creating JSON
## =============
@@ -134,7 +139,7 @@
## This module can also be used to comfortably create JSON using the `%*`
## operator:
##
## .. code-block:: nim
## ```nim
## import std/json
##
## var hisName = "John"
@@ -148,6 +153,7 @@
## var j2 = %* {"name": "Isaac", "books": ["Robot Dreams"]}
## j2["details"] = %* {"age":35, "pi":3.1415}
## echo j2
## ```
##
## See also: std/jsonutils for hookable json serialization/deserialization
## of arbitrary types.

View File

@@ -17,10 +17,11 @@
##
## To get started, first create a logger:
##
## .. code-block::
## ```Nim
## import std/logging
##
## var logger = newConsoleLogger()
## ```
##
## The logger that was created above logs to the console, but this module
## also provides loggers that log to files, such as the
@@ -30,9 +31,10 @@
## Once a logger has been created, call its `log proc
## <#log.e,ConsoleLogger,Level,varargs[string,]>`_ to log a message:
##
## .. code-block::
## ```Nim
## logger.log(lvlInfo, "a log message")
## # Output: INFO a log message
## ```
##
## The ``INFO`` within the output is the result of a format string being
## prepended to the message, and it will differ depending on the message's
@@ -58,7 +60,7 @@
## used with the `addHandler proc<#addHandler,Logger>`_, which is demonstrated
## in the following example:
##
## .. code-block::
## ```Nim
## import std/logging
##
## var consoleLog = newConsoleLogger()
@@ -68,17 +70,19 @@
## addHandler(consoleLog)
## addHandler(fileLog)
## addHandler(rollingLog)
## ```
##
## After doing this, use either the `log template
## <#log.t,Level,varargs[string,]>`_ or one of the level-specific templates,
## such as the `error template<#error.t,varargs[string,]>`_, to log messages
## to all registered handlers at once.
##
## .. code-block::
## ```Nim
## # This example uses the loggers created above
## log(lvlError, "an error occurred")
## error("an error occurred") # Equivalent to the above line
## info("something normal happened") # Will not be written to errors.log
## ```
##
## Note that a message's level is still checked against each handler's
## ``levelThreshold`` and the global log filter.
@@ -116,12 +120,13 @@
##
## The following example illustrates how to use format strings:
##
## .. code-block::
## ```Nim
## import std/logging
##
## var logger = newConsoleLogger(fmtStr="[$time] - $levelname: ")
## logger.log(lvlInfo, "this is a message")
## # Output: [19:50:13] - INFO: this is a message
## ```
##
## Notes when using multiple threads
## ---------------------------------
@@ -372,10 +377,11 @@ method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var consoleLog = newConsoleLogger()
## consoleLog.log(lvlInfo, "this is a message")
## consoleLog.log(lvlError, "error code is: ", 404)
## ```
if level >= logging.level and level >= logger.levelThreshold:
let ln = substituteLog(logger.fmtStr, level, args)
when defined(js):
@@ -414,10 +420,11 @@ proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr,
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var normalLog = newConsoleLogger()
## var formatLog = newConsoleLogger(fmtStr=verboseFmtStr)
## var errorLog = newConsoleLogger(levelThreshold=lvlError, useStderr=true)
## ```
new result
result.fmtStr = fmtStr
result.levelThreshold = levelThreshold
@@ -450,10 +457,11 @@ when not defined(js):
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var fileLog = newFileLogger("messages.log")
## fileLog.log(lvlInfo, "this is a message")
## fileLog.log(lvlError, "error code is: ", 404)
## ```
if level >= logging.level and level >= logger.levelThreshold:
writeLine(logger.file, substituteLog(logger.fmtStr, level, args))
if level >= logger.flushThreshold: flushFile(logger.file)
@@ -481,7 +489,7 @@ when not defined(js):
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var messages = open("messages.log", fmWrite)
## var formatted = open("formatted.log", fmWrite)
## var errors = open("errors.log", fmWrite)
@@ -489,6 +497,7 @@ when not defined(js):
## var normalLog = newFileLogger(messages)
## var formatLog = newFileLogger(formatted, fmtStr=verboseFmtStr)
## var errorLog = newFileLogger(errors, levelThreshold=lvlError)
## ```
new(result)
result.file = file
result.levelThreshold = levelThreshold
@@ -519,10 +528,11 @@ when not defined(js):
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var normalLog = newFileLogger("messages.log")
## var formatLog = newFileLogger("formatted.log", fmtStr=verboseFmtStr)
## var errorLog = newFileLogger("errors.log", levelThreshold=lvlError)
## ```
let file = open(filename, mode, bufSize = bufSize)
newFileLogger(file, levelThreshold, fmtStr, flushThreshold)
@@ -579,11 +589,12 @@ when not defined(js):
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var normalLog = newRollingFileLogger("messages.log")
## var formatLog = newRollingFileLogger("formatted.log", fmtStr=verboseFmtStr)
## var shortLog = newRollingFileLogger("short.log", maxLines=200)
## var errorLog = newRollingFileLogger("errors.log", levelThreshold=lvlError)
## ```
new(result)
result.levelThreshold = levelThreshold
result.fmtStr = fmtStr
@@ -633,10 +644,11 @@ when not defined(js):
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var rollingLog = newRollingFileLogger("messages.log")
## rollingLog.log(lvlInfo, "this is a message")
## rollingLog.log(lvlError, "error code is: ", 404)
## ```
if level >= logging.level and level >= logger.levelThreshold:
if logger.curLine >= logger.maxLines:
logger.file.close()
@@ -666,11 +678,12 @@ template log*(level: Level, args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## log(lvlInfo, "This is an example.")
## ```
##
## See also:
## * `debug template<#debug.t,varargs[string,]>`_
@@ -695,11 +708,12 @@ template debug*(args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## debug("myProc called with arguments: foo, 5")
## ```
##
## See also:
## * `log template<#log.t,Level,varargs[string,]>`_
@@ -716,11 +730,12 @@ template info*(args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## info("Application started successfully.")
## ```
##
## See also:
## * `log template<#log.t,Level,varargs[string,]>`_
@@ -737,11 +752,12 @@ template notice*(args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## notice("An important operation has completed.")
## ```
##
## See also:
## * `log template<#log.t,Level,varargs[string,]>`_
@@ -757,11 +773,12 @@ template warn*(args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## warn("The previous operation took too long to process.")
## ```
##
## See also:
## * `log template<#log.t,Level,varargs[string,]>`_
@@ -779,11 +796,12 @@ template error*(args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## error("An exception occurred while processing the form.")
## ```
##
## See also:
## * `log template<#log.t,Level,varargs[string,]>`_
@@ -800,11 +818,12 @@ template fatal*(args: varargs[string, `$`]) =
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var logger = newConsoleLogger()
## addHandler(logger)
##
## fatal("Can't open database -- exiting.")
## ```
##
## See also:
## * `log template<#log.t,Level,varargs[string,]>`_

View File

@@ -150,7 +150,7 @@ proc open*(filename: string, mode: FileMode = fmRead,
##
## Example:
##
## .. code-block:: nim
## ```nim
## var
## mm, mm_full, mm_half: MemFile
##
@@ -162,6 +162,7 @@ proc open*(filename: string, mode: FileMode = fmRead,
##
## # Read the first 512 bytes
## mm_half = memfiles.open("/tmp/test.mmap", mode = fmReadWrite, mappedSize = 512)
## ```
# The file can be resized only when write mode is used:
if mode == fmAppend:
@@ -443,13 +444,13 @@ iterator memSlices*(mfile: MemFile, delim = '\l', eat = '\r'): MemSlice {.inline
## functions, not str* functions).
##
## Example:
##
## .. code-block:: nim
## ```nim
## var count = 0
## for slice in memSlices(memfiles.open("foo")):
## if slice.size > 0 and cast[cstring](slice.data)[0] != '#':
## inc(count)
## echo count
## ```
proc c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
importc: "memchr", header: "<string.h>".}
@@ -479,11 +480,11 @@ iterator lines*(mfile: MemFile, buf: var string, delim = '\l',
## <#memSlices.i,MemFile,char,char>`_, but Nim strings are returned.
##
## Example:
##
## .. code-block:: nim
## ```nim
## var buffer: string = ""
## for line in lines(memfiles.open("foo"), buffer):
## echo line
## ```
for ms in memSlices(mfile, delim, eat):
setLen(buf, ms.size)
@@ -498,10 +499,10 @@ iterator lines*(mfile: MemFile, delim = '\l', eat = '\r'): string {.inline.} =
## <#memSlices.i,MemFile,char,char>`_, but Nim strings are returned.
##
## Example:
##
## .. code-block:: nim
## ```nim
## for line in lines(memfiles.open("foo")):
## echo line
## ```
var buf = newStringOfCap(80)
for line in lines(mfile, buf, delim, eat):

View File

@@ -53,7 +53,7 @@ Pattern matching
supports pattern matching on `Option`s, with the `Some(<pattern>)` and
`None()` patterns.
.. code-block:: nim
```nim
{.experimental: "caseStmtMacros".}
import fusion/matching
@@ -65,6 +65,7 @@ supports pattern matching on `Option`s, with the `Some(<pattern>)` and
assert false
assertMatch(some(some(none(int))), Some(Some(None())))
```
]##
# xxx pending https://github.com/timotheecour/Nim/issues/376 use `runnableExamples` and `whichModule`

View File

@@ -411,9 +411,9 @@ proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
## <osproc.html#execProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_.
##
## **Examples:**
##
## .. code-block::
## ```Nim
## discard execShellCmd("ls -la")
## ```
result = exitStatusLikeShell(c_system(command))
proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
@@ -482,18 +482,18 @@ proc inclFilePermissions*(filename: string,
permissions: set[FilePermission]) {.
rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect], noWeirdTarget.} =
## A convenience proc for:
##
## .. code-block:: nim
## ```nim
## setFilePermissions(filename, getFilePermissions(filename)+permissions)
## ```
setFilePermissions(filename, getFilePermissions(filename)+permissions)
proc exclFilePermissions*(filename: string,
permissions: set[FilePermission]) {.
rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect], noWeirdTarget.} =
## A convenience proc for:
##
## .. code-block:: nim
## ```nim
## setFilePermissions(filename, getFilePermissions(filename)-permissions)
## ```
setFilePermissions(filename, getFilePermissions(filename)-permissions)
when not weirdTarget and (defined(freebsd) or defined(dragonfly) or defined(netbsd)):

View File

@@ -91,12 +91,12 @@ proc execProcess*(command: string, workingDir: string = "",
## * `execCmd proc <#execCmd,string>`_
##
## Example:
##
## .. code-block:: Nim
## let outp = execProcess("nim", args=["c", "-r", "mytestfile.nim"], options={poUsePath})
## let outp_shell = execProcess("nim c -r mytestfile.nim")
## # Note: outp may have an interleave of text from the nim compile
## # and any output from mytestfile when it runs
## ```Nim
## let outp = execProcess("nim", args=["c", "-r", "mytestfile.nim"], options={poUsePath})
## let outp_shell = execProcess("nim c -r mytestfile.nim")
## # Note: outp may have an interleave of text from the nim compile
## # and any output from mytestfile when it runs
## ```
proc execCmd*(command: string): int {.rtl, extern: "nosp$1",
tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
@@ -113,9 +113,9 @@ proc execCmd*(command: string): int {.rtl, extern: "nosp$1",
## <#execProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_
##
## Example:
##
## .. code-block:: Nim
## let errC = execCmd("nim c -r mytestfile.nim")
## ```Nim
## let errC = execCmd("nim c -r mytestfile.nim")
## ```
proc startProcess*(command: string, workingDir: string = "",
args: openArray[string] = [], env: StringTableRef = nil,
@@ -465,8 +465,7 @@ iterator lines*(p: Process, keepNewLines = false): string {.since: (1, 3), raise
## * `readLines proc <#readLines,Process>`_
##
## Example:
##
## .. code-block:: Nim
## ```Nim
## const opts = {poUsePath, poDaemon, poStdErrToStdOut}
## var ps: seq[Process]
## for prog in ["a", "b"]: # run 2 progs in parallel
@@ -478,6 +477,7 @@ iterator lines*(p: Process, keepNewLines = false): string {.since: (1, 3), raise
## i.inc
## if i > 100: break
## p.close
## ```
var outp = p.outputStream
var line = newStringOfCap(120)
while outp.readLine(line):
@@ -495,8 +495,7 @@ proc readLines*(p: Process): (seq[string], int) {.since: (1, 3),
## * `lines iterator <#lines.i,Process>`_
##
## Example:
##
## .. code-block:: Nim
## ```Nim
## const opts = {poUsePath, poDaemon, poStdErrToStdOut}
## var ps: seq[Process]
## for prog in ["a", "b"]: # run 2 progs in parallel
@@ -506,6 +505,7 @@ proc readLines*(p: Process): (seq[string], int) {.since: (1, 3),
## if exCode != 0:
## for line in lines: echo line
## p.close
## ```
for line in p.lines: result[0].add(line)
result[1] = p.peekExitCode
@@ -1587,8 +1587,7 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = {
## <#execProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_
##
## Example:
##
## .. code-block:: Nim
## ```Nim
## var result = execCmdEx("nim r --hints:off -", options = {}, input = "echo 3*4")
## import std/[strutils, strtabs]
## stripLineEnd(result[0]) ## portable way to remove trailing newline, if any
@@ -1597,6 +1596,7 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = {
## when defined(posix):
## assert execCmdEx("echo $FO", env = newStringTable({"FO": "B"})) == ("B\n", 0)
## assert execCmdEx("echo $PWD", workingDir = "/") == ("/\n", 0)
## ```
when (NimMajor, NimMinor, NimPatch) < (1, 3, 5):
doAssert input.len == 0

View File

@@ -45,9 +45,7 @@ runnableExamples("-r:off"):
## Configuration file example
]##
##
## .. code-block:: nim
##
## ```none
## charset = "utf-8"
## [Package]
## name = "hello"
@@ -55,6 +53,7 @@ runnableExamples("-r:off"):
## [Author]
## name = "nim-lang"
## website = "nim-lang.org"
## ```
##[
## Creating a configuration file

View File

@@ -13,7 +13,7 @@
## Basic usage
## ===========
##
## .. code-block:: nim
## ```nim
## import std/parsecsv
## from std/os import paramStr
## from std/streams import newFileStream
@@ -29,11 +29,12 @@
## for val in items(x.row):
## echo "##", val, "##"
## close(x)
## ```
##
## For CSV files with a header row, the header can be read and then used as a
## reference for item access with `rowEntry <#rowEntry,CsvParser,string>`_:
##
## .. code-block:: nim
## ```nim
## import std/parsecsv
##
## # Prepare a file
@@ -52,6 +53,7 @@
## for col in items(p.headers):
## echo "##", col, ":", p.rowEntry(col), "##"
## p.close()
## ```
##
## See also
## ========

View File

@@ -48,7 +48,7 @@
##
## Here is an example:
##
## .. code-block::
## ```Nim
## import std/parseopt
##
## var p = initOptParser("-ab -e:5 --foo --bar=20 file.txt")
@@ -71,6 +71,7 @@
## # Option: foo
## # Option and value: bar, 20
## # Argument: file.txt
## ```
##
## The `getopt iterator<#getopt.i,OptParser>`_, which is provided for
## convenience, can be used to iterate through all command line options as well.
@@ -80,7 +81,8 @@
## Then set the variable to the new value while parsing.
##
## Here is an example:
## .. code-block::
##
## ```Nim
## import std/parseopt
##
## var varName: string = "defaultValue"
@@ -95,6 +97,7 @@
## varName = val # do input sanitization in production systems
## of cmdEnd:
## discard
## ```
##
## `shortNoVal` and `longNoVal`
## ============================
@@ -119,7 +122,7 @@
## `shortNoVal` and `longNoVal`, which is the default, and providing
## arguments for those two parameters:
##
## .. code-block::
## ```Nim
## import std/parseopt
##
## proc printToken(kind: CmdLineKind, key: string, val: string) =
@@ -153,6 +156,7 @@
## # Output:
## # Option and value: j, 4
## # Option and value: first, bar
## ```
##
## See also
## ========
@@ -387,14 +391,14 @@ when declared(quoteShellCommand):
## * `remainingArgs proc<#remainingArgs,OptParser>`_
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var p = initOptParser("--left -r:2 -- foo.txt bar.txt")
## while true:
## p.next()
## if p.kind == cmdLongOption and p.key == "": # Look for "--"
## break
## doAssert p.cmdLineRest == "foo.txt bar.txt"
## ```
result = p.cmds[p.idx .. ^1].quoteShellCommand
proc remainingArgs*(p: OptParser): seq[string] {.rtl, extern: "npo$1".} =
@@ -404,14 +408,14 @@ proc remainingArgs*(p: OptParser): seq[string] {.rtl, extern: "npo$1".} =
## * `cmdLineRest proc<#cmdLineRest,OptParser>`_
##
## **Examples:**
##
## .. code-block::
## ```Nim
## var p = initOptParser("--left -r:2 -- foo.txt bar.txt")
## while true:
## p.next()
## if p.kind == cmdLongOption and p.key == "": # Look for "--"
## break
## doAssert p.remainingArgs == @["foo.txt", "bar.txt"]
## ```
result = @[]
for i in p.idx..<p.cmds.len: result.add p.cmds[i]
@@ -428,7 +432,7 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key,
##
## **Examples:**
##
## .. code-block::
## ```Nim
## # these are placeholders, of course
## proc writeHelp() = discard
## proc writeVersion() = discard
@@ -448,6 +452,7 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key,
## if filename == "":
## # no filename has been given, so we show the help
## writeHelp()
## ```
p.pos = 0
p.idx = 0
while true:
@@ -477,8 +482,7 @@ iterator getopt*(cmdline: seq[string] = @[],
##
## **Examples:**
##
## .. code-block::
##
## ```Nim
## # these are placeholders, of course
## proc writeHelp() = discard
## proc writeVersion() = discard
@@ -498,6 +502,7 @@ iterator getopt*(cmdline: seq[string] = @[],
## if filename == "":
## # no filename has been written, so we show the help
## writeHelp()
## ```
var p = initOptParser(cmdline, shortNoVal = shortNoVal,
longNoVal = longNoVal)
while true:

View File

@@ -12,29 +12,28 @@
##
## To unpack raw bytes look at the `streams <streams.html>`_ module.
##
## .. code-block:: nim
## :test:
## ```nim test
## let logs = @["2019-01-10: OK_", "2019-01-11: FAIL_", "2019-01: aaaa"]
## var outp: seq[string]
##
## let logs = @["2019-01-10: OK_", "2019-01-11: FAIL_", "2019-01: aaaa"]
## var outp: seq[string]
## for log in logs:
## var res: string
## if parseUntil(log, res, ':') == 10: # YYYY-MM-DD == 10
## outp.add(res & " - " & captureBetween(log, ' ', '_'))
## doAssert outp == @["2019-01-10 - OK", "2019-01-11 - FAIL"]
## ```
##
## for log in logs:
## var res: string
## if parseUntil(log, res, ':') == 10: # YYYY-MM-DD == 10
## outp.add(res & " - " & captureBetween(log, ' ', '_'))
## doAssert outp == @["2019-01-10 - OK", "2019-01-11 - FAIL"]
## ```nim test
## from std/strutils import Digits, parseInt
##
## .. code-block:: nim
## :test:
## from std/strutils import Digits, parseInt
##
## let
## input1 = "2019 school start"
## input2 = "3 years back"
## startYear = input1[0 .. skipWhile(input1, Digits)-1] # 2019
## yearsBack = input2[0 .. skipWhile(input2, Digits)-1] # 3
## examYear = parseInt(startYear) + parseInt(yearsBack)
## doAssert "Examination is in " & $examYear == "Examination is in 2022"
## let
## input1 = "2019 school start"
## input2 = "3 years back"
## startYear = input1[0 .. skipWhile(input1, Digits)-1] # 2019
## yearsBack = input2[0 .. skipWhile(input2, Digits)-1] # 3
## examYear = parseInt(startYear) + parseInt(yearsBack)
## doAssert "Examination is in " & $examYear == "Examination is in 2022"
## ```
##
## **See also:**
## * `strutils module<strutils.html>`_ for combined and identical parsing proc's

View File

@@ -36,43 +36,43 @@ The file ``examples/htmltitle.nim`` demonstrates how to use the
XML parser to accomplish a simple task: To determine the title of an HTML
document.
.. code-block:: nim
```nim
# Example program to show the parsexml module
# This program reads an HTML file and writes its title to stdout.
# Errors and whitespace are ignored.
# Example program to show the parsexml module
# This program reads an HTML file and writes its title to stdout.
# Errors and whitespace are ignored.
import os, streams, parsexml, strutils
import os, streams, parsexml, strutils
if paramCount() < 1:
quit("Usage: htmltitle filename[.html]")
if paramCount() < 1:
quit("Usage: htmltitle filename[.html]")
var filename = addFileExt(paramStr(1), "html")
var s = newFileStream(filename, fmRead)
if s == nil: quit("cannot open the file " & filename)
var x: XmlParser
open(x, s, filename)
while true:
x.next()
case x.kind
of xmlElementStart:
if cmpIgnoreCase(x.elementName, "title") == 0:
var title = ""
x.next() # skip "<title>"
while x.kind == xmlCharData:
title.add(x.charData)
x.next()
if x.kind == xmlElementEnd and cmpIgnoreCase(x.elementName, "title") == 0:
echo("Title: " & title)
quit(0) # Success!
else:
echo(x.errorMsgExpected("/title"))
var filename = addFileExt(paramStr(1), "html")
var s = newFileStream(filename, fmRead)
if s == nil: quit("cannot open the file " & filename)
var x: XmlParser
open(x, s, filename)
while true:
x.next()
case x.kind
of xmlElementStart:
if cmpIgnoreCase(x.elementName, "title") == 0:
var title = ""
x.next() # skip "<title>"
while x.kind == xmlCharData:
title.add(x.charData)
x.next()
if x.kind == xmlElementEnd and cmpIgnoreCase(x.elementName, "title") == 0:
echo("Title: " & title)
quit(0) # Success!
else:
echo(x.errorMsgExpected("/title"))
of xmlEof: break # end of file reached
else: discard # ignore other events
of xmlEof: break # end of file reached
else: discard # ignore other events
x.close()
quit("Could not determine title!")
x.close()
quit("Could not determine title!")
```
]##
@@ -85,64 +85,64 @@ The file ``examples/htmlrefs.nim`` demonstrates how to use the
XML parser to accomplish another simple task: To determine all the links
an HTML document contains.
.. code-block:: nim
```nim
# Example program to show the new parsexml module
# This program reads an HTML file and writes all its used links to stdout.
# Errors and whitespace are ignored.
# Example program to show the new parsexml module
# This program reads an HTML file and writes all its used links to stdout.
# Errors and whitespace are ignored.
import os, streams, parsexml, strutils
import os, streams, parsexml, strutils
proc `=?=` (a, b: string): bool =
# little trick: define our own comparator that ignores case
return cmpIgnoreCase(a, b) == 0
proc `=?=` (a, b: string): bool =
# little trick: define our own comparator that ignores case
return cmpIgnoreCase(a, b) == 0
if paramCount() < 1:
quit("Usage: htmlrefs filename[.html]")
if paramCount() < 1:
quit("Usage: htmlrefs filename[.html]")
var links = 0 # count the number of links
var filename = addFileExt(paramStr(1), "html")
var s = newFileStream(filename, fmRead)
if s == nil: quit("cannot open the file " & filename)
var x: XmlParser
open(x, s, filename)
next(x) # get first event
block mainLoop:
while true:
case x.kind
of xmlElementOpen:
# the <a href = "xyz"> tag we are interested in always has an attribute,
# thus we search for ``xmlElementOpen`` and not for ``xmlElementStart``
if x.elementName =?= "a":
x.next()
if x.kind == xmlAttribute:
if x.attrKey =?= "href":
var link = x.attrValue
inc(links)
# skip until we have an ``xmlElementClose`` event
while true:
x.next()
case x.kind
of xmlEof: break mainLoop
of xmlElementClose: break
else: discard
x.next() # skip ``xmlElementClose``
# now we have the description for the ``a`` element
var desc = ""
while x.kind == xmlCharData:
desc.add(x.charData)
x.next()
echo(desc & ": " & link)
else:
x.next()
of xmlEof: break # end of file reached
of xmlError:
echo(errorMsg(x))
var links = 0 # count the number of links
var filename = addFileExt(paramStr(1), "html")
var s = newFileStream(filename, fmRead)
if s == nil: quit("cannot open the file " & filename)
var x: XmlParser
open(x, s, filename)
next(x) # get first event
block mainLoop:
while true:
case x.kind
of xmlElementOpen:
# the <a href = "xyz"> tag we are interested in always has an attribute,
# thus we search for ``xmlElementOpen`` and not for ``xmlElementStart``
if x.elementName =?= "a":
x.next()
else: x.next() # skip other events
if x.kind == xmlAttribute:
if x.attrKey =?= "href":
var link = x.attrValue
inc(links)
# skip until we have an ``xmlElementClose`` event
while true:
x.next()
case x.kind
of xmlEof: break mainLoop
of xmlElementClose: break
else: discard
x.next() # skip ``xmlElementClose``
# now we have the description for the ``a`` element
var desc = ""
while x.kind == xmlCharData:
desc.add(x.charData)
x.next()
echo(desc & ": " & link)
else:
x.next()
of xmlEof: break # end of file reached
of xmlError:
echo(errorMsg(x))
x.next()
else: x.next() # skip other events
echo($links & " link(s) found!")
x.close()
echo($links & " link(s) found!")
x.close()
```
]##

View File

@@ -889,7 +889,7 @@ macro mkHandlerTplts(handlers: untyped): untyped =
# Transforms the handler spec in *handlers* into handler templates.
# The AST structure of *handlers[0]*:
#
# .. code-block::
# ```
# StmtList
# Call
# Ident "pkNonTerminal"
@@ -910,6 +910,7 @@ macro mkHandlerTplts(handlers: untyped): untyped =
# StmtList
# <handler code block>
# ...
# ```
func mkEnter(hdName, body: NimNode): NimNode =
template helper(hdName, body) {.dirty.} =
template hdName(s, p, start) =
@@ -959,60 +960,61 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
## match, else the length of the total match. The following example code
## evaluates an arithmetic expression defined by a simple PEG:
##
## .. code-block:: nim
## import std/[strutils, pegs]
## ```nim
## import std/[strutils, pegs]
##
## let
## pegAst = """
## Expr <- Sum
## Sum <- Product (('+' / '-')Product)*
## Product <- Value (('*' / '/')Value)*
## Value <- [0-9]+ / '(' Expr ')'
## """.peg
## txt = "(5+3)/2-7*22"
## let
## pegAst = """
## Expr <- Sum
## Sum <- Product (('+' / '-')Product)*
## Product <- Value (('*' / '/')Value)*
## Value <- [0-9]+ / '(' Expr ')'
## """.peg
## txt = "(5+3)/2-7*22"
##
## var
## pStack: seq[string] = @[]
## valStack: seq[float] = @[]
## opStack = ""
## let
## parseArithExpr = pegAst.eventParser:
## pkNonTerminal:
## enter:
## pStack.add p.nt.name
## leave:
## pStack.setLen pStack.high
## if length > 0:
## let matchStr = s.substr(start, start+length-1)
## case p.nt.name
## of "Value":
## try:
## valStack.add matchStr.parseFloat
## echo valStack
## except ValueError:
## discard
## of "Sum", "Product":
## try:
## let val = matchStr.parseFloat
## except ValueError:
## if valStack.len > 1 and opStack.len > 0:
## valStack[^2] = case opStack[^1]
## of '+': valStack[^2] + valStack[^1]
## of '-': valStack[^2] - valStack[^1]
## of '*': valStack[^2] * valStack[^1]
## else: valStack[^2] / valStack[^1]
## valStack.setLen valStack.high
## echo valStack
## opStack.setLen opStack.high
## echo opStack
## pkChar:
## leave:
## if length == 1 and "Value" != pStack[^1]:
## let matchChar = s[start]
## opStack.add matchChar
## echo opStack
## var
## pStack: seq[string] = @[]
## valStack: seq[float] = @[]
## opStack = ""
## let
## parseArithExpr = pegAst.eventParser:
## pkNonTerminal:
## enter:
## pStack.add p.nt.name
## leave:
## pStack.setLen pStack.high
## if length > 0:
## let matchStr = s.substr(start, start+length-1)
## case p.nt.name
## of "Value":
## try:
## valStack.add matchStr.parseFloat
## echo valStack
## except ValueError:
## discard
## of "Sum", "Product":
## try:
## let val = matchStr.parseFloat
## except ValueError:
## if valStack.len > 1 and opStack.len > 0:
## valStack[^2] = case opStack[^1]
## of '+': valStack[^2] + valStack[^1]
## of '-': valStack[^2] - valStack[^1]
## of '*': valStack[^2] * valStack[^1]
## else: valStack[^2] / valStack[^1]
## valStack.setLen valStack.high
## echo valStack
## opStack.setLen opStack.high
## echo opStack
## pkChar:
## leave:
## if length == 1 and "Value" != pStack[^1]:
## let matchChar = s[start]
## opStack.add matchChar
## echo opStack
##
## let pLen = parseArithExpr(txt)
## let pLen = parseArithExpr(txt)
## ```
##
## The *handlers* parameter consists of code blocks for *PegKinds*,
## which define the grammar elements of interest. Each block can contain
@@ -1181,8 +1183,7 @@ template `=~`*(s: string, pattern: Peg): bool =
## This calls ``match`` with an implicit declared ``matches`` array that
## can be used in the scope of the ``=~`` call:
##
## .. code-block:: nim
##
## ```nim
## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}":
## # matches a key=value pair:
## echo("Key: ", matches[0])
@@ -1194,7 +1195,7 @@ template `=~`*(s: string, pattern: Peg): bool =
## echo("comment: ", matches[0])
## else:
## echo("syntax error")
##
## ```
bind MaxSubpatterns
when not declaredInScope(matches):
var matches {.inject.}: array[0..MaxSubpatterns-1, string]
@@ -1230,14 +1231,15 @@ func replacef*(s: string, sub: Peg, by: string): string {.
## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by`
## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples:
##
## .. code-block:: nim
## ```nim
## "var1=key; var2=key2".replacef(peg"{\ident}'='{\ident}", "$1<-$2$2")
## ```
##
## Results in:
##
## .. code-block:: nim
##
## ```nim
## "var1<-keykey; val2<-key2key2"
## ```
result = ""
var i = 0
var caps: array[0..MaxSubpatterns-1, string]
@@ -1305,8 +1307,7 @@ func replace*(s: string, sub: Peg, cb: proc(
## The callback proc receives the index of the current match (starting with 0),
## the count of captures and an open array with the captures of each match. Examples:
##
## .. code-block:: nim
##
## ```nim
## func handleMatches*(m: int, n: int, c: openArray[string]): string =
## result = ""
## if m > 0:
@@ -1318,12 +1319,13 @@ func replace*(s: string, sub: Peg, cb: proc(
##
## let s = "Var1=key1;var2=Key2; VAR3"
## echo s.replace(peg"{\ident}('='{\ident})* ';'* \s*", handleMatches)
## ```
##
## Results in:
##
## .. code-block:: nim
##
## ```nim
## "var1: 'key1', var2: 'Key2', var3: ''"
## ```
result = ""
var i = 0
var caps: array[0..MaxSubpatterns-1, string]
@@ -1361,18 +1363,19 @@ iterator split*(s: string, sep: Peg): string =
## Substrings are separated by the PEG `sep`.
## Examples:
##
## .. code-block:: nim
## ```nim
## for word in split("00232this02939is39an22example111", peg"\d+"):
## writeLine(stdout, word)
## ```
##
## Results in:
##
## .. code-block:: nim
## ```nim
## "this"
## "is"
## "an"
## "example"
##
## ```
var c: Captures
var
first = 0

View File

@@ -205,12 +205,11 @@ when defined(nimdoc):
## to `value`. This `value` can be modified in the scope of
## the `withData` call.
##
## .. code-block:: nim
##
## ```nim
## s.withData(fd, value) do:
## # block is executed only if `fd` registered in selector `s`
## value.uid = 1000
##
## ```
template withData*[T](s: Selector[T], fd: SocketHandle|int, value,
body1, body2: untyped) =
@@ -218,15 +217,14 @@ when defined(nimdoc):
## to `value`. This `value` can be modified in the scope of
## the `withData` call.
##
## .. code-block:: nim
##
## ```nim
## s.withData(fd, value) do:
## # block is executed only if `fd` registered in selector `s`.
## value.uid = 1000
## do:
## # block is executed if `fd` not registered in selector `s`.
## raise
##
## ```
proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} =
## Determines whether selector contains a file descriptor.

View File

@@ -27,67 +27,67 @@
## StringStream example
## --------------------
##
## .. code-block:: Nim
## ```Nim
## import std/streams
##
## import std/streams
## var strm = newStringStream("""The first line
## the second line
## the third line""")
##
## var strm = newStringStream("""The first line
## the second line
## the third line""")
## var line = ""
##
## var line = ""
## while strm.readLine(line):
## echo line
##
## while strm.readLine(line):
## echo line
## # Output:
## # The first line
## # the second line
## # the third line
##
## # Output:
## # The first line
## # the second line
## # the third line
##
## strm.close()
## strm.close()
## ```
##
## FileStream example
## ------------------
##
## Write file stream example:
##
## .. code-block:: Nim
## ```Nim
## import std/streams
##
## import std/streams
## var strm = newFileStream("somefile.txt", fmWrite)
## var line = ""
##
## var strm = newFileStream("somefile.txt", fmWrite)
## var line = ""
## if not isNil(strm):
## strm.writeLine("The first line")
## strm.writeLine("the second line")
## strm.writeLine("the third line")
## strm.close()
##
## if not isNil(strm):
## strm.writeLine("The first line")
## strm.writeLine("the second line")
## strm.writeLine("the third line")
## strm.close()
##
## # Output (somefile.txt):
## # The first line
## # the second line
## # the third line
## # Output (somefile.txt):
## # The first line
## # the second line
## # the third line
## ```
##
## Read file stream example:
##
## .. code-block:: Nim
## ```Nim
## import std/streams
##
## import std/streams
## var strm = newFileStream("somefile.txt", fmRead)
## var line = ""
##
## var strm = newFileStream("somefile.txt", fmRead)
## var line = ""
## if not isNil(strm):
## while strm.readLine(line):
## echo line
## strm.close()
##
## if not isNil(strm):
## while strm.readLine(line):
## echo line
## strm.close()
##
## # Output:
## # The first line
## # the second line
## # the third line
## # Output:
## # The first line
## # the second line
## # the third line
## ```
##
## See also
## ========
@@ -348,9 +348,9 @@ proc write*[T](s: Stream, x: T) =
## **Note:** Not available for JS backend. Use `write(Stream, string)
## <#write,Stream,string>`_ for now.
##
## .. code-block:: Nim
##
## s.writeData(s, unsafeAddr(x), sizeof(x))
## ```Nim
## s.writeData(s, unsafeAddr(x), sizeof(x))
## ```
runnableExamples:
var strm = newStringStream("")
strm.write("abcde")

View File

@@ -91,14 +91,14 @@ proc newPipeOutStream*[T](s: sink (ref T)): owned PipeOutStream[T] =
## when setPosition/getPosition is called or write operation is performed.
##
## Example:
##
## .. code-block:: Nim
## ```Nim
## import std/[osproc, streamwrapper]
## var
## p = startProcess(exePath)
## outStream = p.outputStream().newPipeOutStream()
## echo outStream.peekChar
## p.close()
## ```
assert s.readDataImpl != nil

View File

@@ -133,13 +133,14 @@ runnableExamples:
An expression like `&"{key} is {value:arg} {{z}}"` is transformed into:
.. code-block:: nim
```nim
var temp = newStringOfCap(educatedCapGuess)
temp.formatValue(key, "")
temp.add(" is ")
temp.formatValue(value, arg)
temp.add(" {z}")
temp
```
Parts of the string that are enclosed in the curly braces are interpreted
as Nim code. To escape a `{` or `}`, double it.
@@ -272,13 +273,14 @@ The available floating point presentation types are:
Because of the well defined order how templates and macros are
expanded, strformat cannot expand template arguments:
.. code-block:: nim
```nim
template myTemplate(arg: untyped): untyped =
echo "arg is: ", arg
echo &"--- {arg} ---"
let x = "abc"
myTemplate(x)
```
First the template `myTemplate` is expanded, where every identifier
`arg` is substituted with its argument. The `arg` inside the
@@ -289,12 +291,13 @@ identifier that cannot be resolved anymore.
The workaround for this is to bind the template argument to a new local variable.
.. code-block:: nim
```nim
template myTemplate(arg: untyped): untyped =
block:
let arg1 {.inject.} = arg
echo "arg is: ", arg1
echo &"--- {arg1} ---"
```
The use of `{.inject.}` here is necessary again because of template
expansion order and hygienic templates. But since we generally want to

View File

@@ -12,7 +12,7 @@ This module contains a `scanf`:idx: macro that can be used for extracting
substrings from an input string. This is often easier than regular expressions.
Some examples as an appetizer:
.. code-block:: nim
```nim
# check if input string matches a triple of integers:
const input = "(1,2,4)"
var x, y, z: int
@@ -26,6 +26,7 @@ Some examples as an appetizer:
var myfloat: float
if scanf(input, "$i-$i-$i $w$s$f", year, month, day, identifier, myfloat):
echo "yes, we have a match!"
```
As can be seen from the examples, strings are matched verbatim except for
substrings starting with ``$``. These constructions are available:
@@ -83,8 +84,7 @@ matches optional tokens without any result binding.
In this example, we define a helper proc ``someSep`` that skips some separators
which we then use in our scanf pattern to help us in the matching process:
.. code-block:: nim
```nim
proc someSep(input: string; start: int; seps: set[char] = {':','-','.'}): int =
# Note: The parameters and return value must match to what ``scanf`` requires
result = 0
@@ -92,11 +92,11 @@ which we then use in our scanf pattern to help us in the matching process:
if scanf(input, "$w$[someSep]$w", key, value):
...
```
It also possible to pass arguments to a user definable matcher:
.. code-block:: nim
```nim
proc ndigits(input: string; intVal: var int; start: int; n: int): int =
# matches exactly ``n`` digits. Matchers need to return 0 if nothing
# matched or otherwise the number of processed chars.
@@ -115,6 +115,7 @@ It also possible to pass arguments to a user definable matcher:
var year, month, day: int
if scanf("2013-01-03", "${ndigits(4)}-${ndigits(2)}-${ndigits(2)}$.", year, month, day):
...
```
The scanp macro
@@ -145,8 +146,7 @@ not implemented.
Simple example that parses the ``/etc/passwd`` file line by line:
.. code-block:: nim
```nim
const
etc_passwd = """root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
@@ -165,6 +165,7 @@ Simple example that parses the ``/etc/passwd`` file line by line:
result.add entry
else:
break
```
The ``scanp`` maps the grammar code into Nim code that performs the parsing.
The parsing is performed with the help of 3 helper templates that that can be
@@ -173,8 +174,7 @@ implemented for a custom type.
These templates need to be named ``atom`` and ``nxt``. ``atom`` should be
overloaded to handle both single characters and sets of character.
.. code-block:: nim
```nim
import std/streams
template atom(input: Stream; idx: int; c: char): bool =
@@ -190,11 +190,11 @@ overloaded to handle both single characters and sets of character.
if scanp(content, idx, +( ~{'\L', '\0'} -> entry.add(peekChar($input))), '\L'):
result.add entry
```
Calling ordinary Nim procs inside the macro is possible:
.. code-block:: nim
```nim
proc digits(s: string; intVal: var int; start: int): int =
var x = 0
while result+start < s.len and s[result+start] in {'0'..'9'} and s[result+start] != ':':
@@ -220,12 +220,12 @@ Calling ordinary Nim procs inside the macro is possible:
result.add login & " " & homedir
else:
break
```
When used for matching, keep in mind that likewise scanf, no backtracking
is performed.
.. code-block:: nim
```nim
proc skipUntil(s: string; until: string; unless = '\0'; start: int): int =
# Skips all characters until the string `until` is found. Returns 0
# if the char `unless` is found first or the end is reached.
@@ -256,12 +256,12 @@ is performed.
for r in collectLinks(body):
echo r
```
In this example both macros are combined seamlessly in order to maximise
efficiency and perform different checks.
.. code-block:: nim
```nim
iterator parseIps*(soup: string): string =
## ipv4 only!
const digits = {'0'..'9'}
@@ -279,7 +279,7 @@ efficiency and perform different checks.
yield buf
buf.setLen(0) # need to clear `buf` each time, cause it might contain garbage
idx.inc
```
]##

View File

@@ -129,11 +129,11 @@ const
## Not very useful by its own, you can use it to create *inverted* sets to
## make the `find func<#find,string,set[char],Natural,int>`_
## find **invalid** characters in strings. Example:
##
## .. code-block:: nim
## ```nim
## let invalid = AllChars - Digits
## doAssert "01234".find(invalid) == -1
## doAssert "01A34".find(invalid) == 2
## ```
func isAlphaAscii*(c: char): bool {.rtl, extern: "nsuIsAlphaAsciiChar".} =
## Checks whether or not character `c` is alphabetical.
@@ -423,14 +423,12 @@ iterator split*(s: string, sep: char, maxsplit: int = -1): string =
##
## Substrings are separated by the character `sep`.
## The code:
##
## .. code-block:: nim
## ```nim
## for word in split(";;this;is;an;;example;;;", ';'):
## writeLine(stdout, word)
##
## ```
## Results in:
##
## .. code-block::
## ```
## ""
## ""
## "this"
@@ -441,6 +439,7 @@ iterator split*(s: string, sep: char, maxsplit: int = -1): string =
## ""
## ""
## ""
## ```
##
## See also:
## * `rsplit iterator<#rsplit.i,string,char,int>`_
@@ -455,41 +454,46 @@ iterator split*(s: string, seps: set[char] = Whitespace,
##
## Substrings are separated by a substring containing only `seps`.
##
## .. code-block:: nim
## ```nim
## for word in split("this\lis an\texample"):
## writeLine(stdout, word)
## ```
##
## ...generates this output:
##
## .. code-block::
## ```
## "this"
## "is"
## "an"
## "example"
## ```
##
## And the following code:
##
## .. code-block:: nim
## ```nim
## for word in split("this:is;an$example", {';', ':', '$'}):
## writeLine(stdout, word)
## ```
##
## ...produces the same output as the first example. The code:
##
## .. code-block:: nim
## ```nim
## let date = "2012-11-20T22:08:08.398990"
## let separators = {' ', '-', ':', 'T'}
## for number in split(date, separators):
## writeLine(stdout, number)
## ```
##
## ...results in:
##
## .. code-block::
## ```
## "2012"
## "11"
## "20"
## "22"
## "08"
## "08.398990"
## ```
##
## .. note:: Empty separator set results in returning an original string,
## following the interpretation "split by no element".
@@ -507,16 +511,18 @@ iterator split*(s: string, sep: string, maxsplit: int = -1): string =
## Substrings are separated by the string `sep`.
## The code:
##
## .. code-block:: nim
## ```nim
## for word in split("thisDATAisDATAcorrupted", "DATA"):
## writeLine(stdout, word)
## ```
##
## Results in:
##
## .. code-block::
## ```
## "this"
## "is"
## "corrupted"
## ```
##
## .. note:: Empty separator string results in returning an original string,
## following the interpretation "split by no element".
@@ -561,15 +567,17 @@ iterator rsplit*(s: string, sep: char,
## string separator. Works exactly the same as `split iterator
## <#split.i,string,char,int>`_ except in reverse order.
##
## .. code-block:: nim
## ```nim
## for piece in "foo:bar".rsplit(':'):
## echo piece
## ```
##
## Results in:
##
## .. code-block:: nim
## ```
## "bar"
## "foo"
## ```
##
## Substrings are separated from the right by the char `sep`.
##
@@ -586,15 +594,17 @@ iterator rsplit*(s: string, seps: set[char] = Whitespace,
## string separator. Works exactly the same as `split iterator
## <#split.i,string,char,int>`_ except in reverse order.
##
## .. code-block:: nim
## ```nim
## for piece in "foo bar".rsplit(WhiteSpace):
## echo piece
## ```
##
## Results in:
##
## .. code-block:: nim
## ```
## "bar"
## "foo"
## ```
##
## Substrings are separated from the right by the set of chars `seps`
##
@@ -614,15 +624,17 @@ iterator rsplit*(s: string, sep: string, maxsplit: int = -1,
## string separator. Works exactly the same as `split iterator
## <#split.i,string,string,int>`_ except in reverse order.
##
## .. code-block:: nim
## ```nim
## for piece in "foothebar".rsplit("the"):
## echo piece
## ```
##
## Results in:
##
## .. code-block:: nim
## ```
## "bar"
## "foo"
## ```
##
## Substrings are separated from the right by the string `sep`
##
@@ -648,13 +660,14 @@ iterator splitLines*(s: string, keepEol = false): string =
##
## Example:
##
## .. code-block:: nim
## ```nim
## for line in splitLines("\nthis\nis\nan\n\nexample\n"):
## writeLine(stdout, line)
## ```
##
## Results in:
##
## .. code-block:: nim
## ```nim
## ""
## "this"
## "is"
@@ -662,6 +675,7 @@ iterator splitLines*(s: string, keepEol = false): string =
## ""
## "example"
## ""
## ```
##
## See also:
## * `splitWhitespace iterator<#splitWhitespace.i,string,int>`_
@@ -694,16 +708,17 @@ iterator splitWhitespace*(s: string, maxsplit: int = -1): string =
##
## The following code:
##
## .. code-block:: nim
## ```nim
## let s = " foo \t bar baz "
## for ms in [-1, 1, 2, 3]:
## echo "------ maxsplit = ", ms, ":"
## for item in s.splitWhitespace(maxsplit=ms):
## echo '"', item, '"'
## ```
##
## ...results in:
##
## .. code-block::
## ```
## ------ maxsplit = -1:
## "foo"
## "bar"
@@ -719,6 +734,7 @@ iterator splitWhitespace*(s: string, maxsplit: int = -1): string =
## "foo"
## "bar"
## "baz"
## ```
##
## See also:
## * `splitLines iterator<#splitLines.i,string>`_
@@ -797,13 +813,15 @@ func rsplit*(s: string, sep: char, maxsplit: int = -1): seq[string] {.rtl,
## For example, if a system had `#` as a delimiter, you could
## do the following to get the tail of the path:
##
## .. code-block:: nim
## ```nim
## var tailSplit = rsplit("Root#Object#Method#Index", '#', maxsplit=1)
## ```
##
## Results in `tailSplit` containing:
##
## .. code-block:: nim
## ```nim
## @["Root#Object#Method", "Index"]
## ```
##
## See also:
## * `rsplit iterator <#rsplit.i,string,char,int>`_
@@ -825,13 +843,15 @@ func rsplit*(s: string, seps: set[char] = Whitespace,
## For example, if a system had `#` as a delimiter, you could
## do the following to get the tail of the path:
##
## .. code-block:: nim
## ```nim
## var tailSplit = rsplit("Root#Object#Method#Index", {'#'}, maxsplit=1)
## ```
##
## Results in `tailSplit` containing:
##
## .. code-block:: nim
## ```nim
## @["Root#Object#Method", "Index"]
## ```
##
## .. note:: Empty separator set results in returning an original string,
## following the interpretation "split by no element".
@@ -855,13 +875,15 @@ func rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] {.rtl,
## For example, if a system had `#` as a delimiter, you could
## do the following to get the tail of the path:
##
## .. code-block:: nim
## ```nim
## var tailSplit = rsplit("Root#Object#Method#Index", "#", maxsplit=1)
## ```
##
## Results in `tailSplit` containing:
##
## .. code-block:: nim
## ```nim
## @["Root#Object#Method", "Index"]
## ```
##
## .. note:: Empty separator string results in returning an original string,
## following the interpretation "split by no element".
@@ -1786,8 +1808,9 @@ func addSep*(dest: var string, sep = ", ", startLen: Natural = 0) {.inline.} =
##
## A shorthand for:
##
## .. code-block:: nim
## ```nim
## if dest.len > startLen: add(dest, sep)
## ```
##
## This is often useful for generating some code where the items need to
## be *separated* by `sep`. `sep` is only added if `dest` is longer than
@@ -2634,13 +2657,13 @@ func formatEng*(f: BiggestFloat,
## decimal point or (if `trim` is true) the maximum number of digits to be
## shown.
##
## .. code-block:: nim
##
## ```nim
## formatEng(0, 2, trim=false) == "0.00"
## formatEng(0, 2) == "0"
## formatEng(0.053, 0) == "53e-3"
## formatEng(52731234, 2) == "52.73e6"
## formatEng(-52731234, 2) == "-52.73e6"
## ```
##
## If `siPrefix` is set to true, the number will be displayed with the SI
## prefix corresponding to the exponent. For example 4100 will be displayed
@@ -2655,8 +2678,7 @@ func formatEng*(f: BiggestFloat,
## different to appending the unit to the result as the location of the space
## is altered depending on whether there is an exponent.
##
## .. code-block:: nim
##
## ```nim
## formatEng(4100, siPrefix=true, unit="V") == "4.1 kV"
## formatEng(4.1, siPrefix=true, unit="V") == "4.1 V"
## formatEng(4.1, siPrefix=true) == "4.1" # Note lack of space
@@ -2666,6 +2688,7 @@ func formatEng*(f: BiggestFloat,
## formatEng(4100) == "4.1e3"
## formatEng(4100, unit="V") == "4.1e3 V"
## formatEng(4100, unit="", useUnitSpace=true) == "4.1e3 " # Space with useUnitSpace=true
## ```
##
## `decimalSep` is used as the decimal separator.
##
@@ -2829,13 +2852,15 @@ func `%`*(formatstr: string, a: openArray[string]): string {.rtl,
##
## This is best explained by an example:
##
## .. code-block:: nim
## ```nim
## "$1 eats $2." % ["The cat", "fish"]
## ```
##
## Results in:
##
## .. code-block:: nim
## ```nim
## "The cat eats fish."
## ```
##
## The substitution variables (the thing after the `$`) are enumerated
## from 1 to `a.len`.
@@ -2843,21 +2868,24 @@ func `%`*(formatstr: string, a: openArray[string]): string {.rtl,
## The notation `$#` can be used to refer to the next substitution
## variable:
##
## .. code-block:: nim
## ```nim
## "$# eats $#." % ["The cat", "fish"]
## ```
##
## Substitution variables can also be words (that is
## `[A-Za-z_]+[A-Za-z0-9_]*`) in which case the arguments in `a` with even
## indices are keys and with odd indices are the corresponding values.
## An example:
##
## .. code-block:: nim
## ```nim
## "$animal eats $food." % ["animal", "The cat", "food", "fish"]
## ```
##
## Results in:
##
## .. code-block:: nim
## ```nim
## "The cat eats fish."
## ```
##
## The variables are compared with `cmpIgnoreStyle`. `ValueError` is
## raised if an ill-formed format string has been passed to the `%` operator.
@@ -2955,13 +2983,14 @@ iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[
## Substrings are separated by a substring containing only `seps`.
## Example:
##
## .. code-block:: nim
## ```nim
## for word in tokenize(" this is an example "):
## writeLine(stdout, word)
## ```
##
## Results in:
##
## .. code-block:: nim
## ```nim
## (" ", true)
## ("this", false)
## (" ", true)
@@ -2971,6 +3000,7 @@ iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[
## (" ", true)
## ("example", false)
## (" ", true)
## ```
var i = 0
while true:
var j = i

View File

@@ -20,7 +20,7 @@
Examples
========
.. code-block:: nim
```nim
import std/[times, os]
# Simple benchmarking
let time = cpuTime()
@@ -37,6 +37,7 @@
# Arithmetic using TimeInterval
echo "One year from now : ", now() + 1.years
echo "One month from now : ", now() + 1.months
```
Parsing and Formatting Dates
============================
@@ -44,10 +45,10 @@
The `DateTime` type can be parsed and formatted using the different
`parse` and `format` procedures.
.. code-block:: nim
```nim
let dt = parse("2000-01-01", "yyyy-MM-dd")
echo dt.format("yyyy-MM-dd")
```
The different format patterns that are supported are documented below.
@@ -652,11 +653,10 @@ template eqImpl(a: Duration|Time, b: Duration|Time): bool =
const DurationZero* = Duration() ## \
## Zero value for durations. Useful for comparisons.
##
## .. code-block:: nim
##
## ```nim
## doAssert initDuration(seconds = 1) > DurationZero
## doAssert initDuration(seconds = 0) == DurationZero
## ```
proc initDuration*(nanoseconds, microseconds, milliseconds,
seconds, minutes, hours, days, weeks: int64 = 0): Duration =

View File

@@ -34,9 +34,9 @@
##
## Specify the test name as a command line argument.
##
## .. code::
##
## ```cmd
## nim c -r test "my test name" "another test"
## ```
##
## Multiple arguments can be used.
##
@@ -45,9 +45,9 @@
##
## Specify the suite name delimited by `"::"`.
##
## .. code::
##
## ```cmd
## nim c -r test "my test name::"
## ```
##
## Selecting tests by pattern
## ==========================
@@ -58,19 +58,18 @@
##
## Tests matching **any** of the arguments are executed.
##
## .. code::
##
## ```cmd
## nim c -r test fast_suite::mytest1 fast_suite::mytest2
## nim c -r test "fast_suite::mytest*"
## nim c -r test "auth*::" "crypto::hashing*"
## # Run suites starting with 'bug #' and standalone tests starting with '#'
## nim c -r test 'bug #*::' '::#*'
## ```
##
## Examples
## ========
##
## .. code:: nim
##
## ```nim
## suite "description for this stuff":
## echo "suite setup: run once before the tests"
##
@@ -96,6 +95,7 @@
## discard v[4]
##
## echo "suite teardown: run once after the tests"
## ```
##
## Limitations/Bugs
## ================
@@ -473,27 +473,26 @@ template suite*(name, body) {.dirty.} =
## common fixture (``setup``, ``teardown``). The fixture is executed
## for EACH test.
##
## .. code-block:: nim
## suite "test suite for addition":
## setup:
## let result = 4
## ```nim
## suite "test suite for addition":
## setup:
## let result = 4
##
## test "2 + 2 = 4":
## check(2+2 == result)
## test "2 + 2 = 4":
## check(2+2 == result)
##
## test "(2 + -2) != 4":
## check(2 + -2 != result)
## test "(2 + -2) != 4":
## check(2 + -2 != result)
##
## # No teardown needed
## # No teardown needed
## ```
##
## The suite will run the individual test cases in the order in which
## they were listed. With default global settings the above code prints:
##
## .. code-block::
##
## [Suite] test suite for addition
## [OK] 2 + 2 = 4
## [OK] (2 + -2) != 4
## [Suite] test suite for addition
## [OK] 2 + 2 = 4
## [OK] (2 + -2) != 4
bind formatters, ensureInitialized, suiteEnded
block:
@@ -528,17 +527,15 @@ when not declared(setProgramResult):
template test*(name, body) {.dirty.} =
## Define a single test case identified by `name`.
##
## .. code-block:: nim
##
## test "roses are red":
## let roses = "red"
## check(roses == "red")
## ```nim
## test "roses are red":
## let roses = "red"
## check(roses == "red")
## ```
##
## The above code outputs:
##
## .. code-block::
##
## [OK] roses are red
## [OK] roses are red
bind shouldRun, checkpoints, formatters, ensureInitialized, testEnded, exceptionTypeName, setProgramResult
ensureInitialized()
@@ -585,11 +582,11 @@ proc checkpoint*(msg: string) =
## Set a checkpoint identified by `msg`. Upon test failure all
## checkpoints encountered so far are printed out. Example:
##
## .. code-block:: nim
##
## checkpoint("Checkpoint A")
## check((42, "the Answer to life and everything") == (1, "a"))
## checkpoint("Checkpoint B")
## ```nim
## checkpoint("Checkpoint A")
## check((42, "the Answer to life and everything") == (1, "a"))
## checkpoint("Checkpoint B")
## ```
##
## outputs "Checkpoint A" once it fails.
checkpoints.add(msg)
@@ -601,11 +598,11 @@ template fail* =
## failed (change exit code and test status). This template is useful
## for debugging, but is otherwise mostly used internally. Example:
##
## .. code-block:: nim
##
## checkpoint("Checkpoint A")
## complicatedProcInThread()
## fail()
## ```nim
## checkpoint("Checkpoint A")
## complicatedProcInThread()
## fail()
## ```
##
## outputs "Checkpoint A" before quitting.
bind ensureInitialized, setProgramResult
@@ -633,11 +630,10 @@ template skip* =
## for reasons depending on outer environment,
## or certain application logic conditions or configurations.
## The test code is still executed.
##
## .. code-block:: nim
##
## if not isGLContextCreated():
## skip()
## ```nim
## if not isGLContextCreated():
## skip()
## ```
bind checkpoints
testStatusIMPL = TestStatus.SKIPPED

View File

@@ -935,8 +935,9 @@ proc xmlConstructor(a: NimNode): NimNode =
macro `<>`*(x: untyped): untyped =
## Constructor macro for XML. Example usage:
##
## .. code-block:: nim
## ```nim
## <>a(href="http://nim-lang.org", newText("Nim rules."))
## ```
##
## Produces an XML tree for:
##

View File

@@ -163,11 +163,12 @@ when defined(nimdoc):
##
## **Examples:**
##
## .. code-block:: nim
## ```nim
## when declared(paramCount):
## # Use paramCount() here
## else:
## # Do something else!
## ```
proc paramStr*(i: int): string {.tags: [ReadIOEffect].} =
## Returns the `i`-th `command line argument`:idx: given to the application.
@@ -195,11 +196,12 @@ when defined(nimdoc):
##
## **Examples:**
##
## .. code-block:: nim
## ```nim
## when declared(paramStr):
## # Use paramStr() here
## else:
## # Do something else!
## ```
elif defined(nimscript): discard
elif defined(nodejs):
@@ -296,11 +298,12 @@ when declared(paramCount) or defined(nimdoc):
##
## **Examples:**
##
## .. code-block:: nim
## ```nim
## when declared(commandLineParams):
## # Use commandLineParams() here
## else:
## # Do something else!
## ```
result = @[]
for i in 1..paramCount():
result.add(paramStr(i))

View File

@@ -19,7 +19,7 @@ const
# Inspired by https://engineering.fb.com/2013/03/15/developer-tools/three-optimization-tips-for-c
# Generates:
# .. code-block:: nim
# ```nim
# var res = ""
# for i in 0 .. 99:
# if i < 10:
@@ -27,6 +27,7 @@ const
# else:
# res.add $i
# doAssert res == digits100
# ```
proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.} =
buf[pos] = digits100[2 * digits]

View File

@@ -15,19 +15,19 @@ The emulation cannot be 100% faithful and to avoid adding too much complexity,
template since*(version: (int, int), body: untyped) {.dirty.} =
## Evaluates `body` if the ``(NimMajor, NimMinor)`` is greater than
## or equal to `version`. Usage:
##
## .. code-block:: Nim
## ```Nim
## proc fun*() {.since: (1, 3).}
## since (1, 3): fun()
## ```
when (NimMajor, NimMinor) >= version:
body
template since*(version: (int, int, int), body: untyped) {.dirty.} =
## Evaluates `body` if ``(NimMajor, NimMinor, NimPatch)`` is greater than
## or equal to `version`. Usage:
##
## .. code-block:: Nim
## ```Nim
## proc fun*() {.since: (1, 3, 1).}
## since (1, 3, 1): fun()
## ```
when (NimMajor, NimMinor, NimPatch) >= version:
body

View File

@@ -31,37 +31,38 @@
## Examples
## ========
##
## .. code-block:: Nim
## import std/socketstreams
## ```Nim
## import std/socketstreams
##
## var
## socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
## stream = newReadSocketStream(socket)
## socket.sendTo("127.0.0.1", Port(12345), "SOME REQUEST")
## echo stream.readLine() # Will call `recv`
## stream.setPosition(0)
## echo stream.readLine() # Will return the read line from the buffer
## stream.resetStream() # Buffer is now empty, position is 0
## echo stream.readLine() # Will call `recv` again
## stream.close() # Closes the socket
## var
## socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
## stream = newReadSocketStream(socket)
## socket.sendTo("127.0.0.1", Port(12345), "SOME REQUEST")
## echo stream.readLine() # Will call `recv`
## stream.setPosition(0)
## echo stream.readLine() # Will return the read line from the buffer
## stream.resetStream() # Buffer is now empty, position is 0
## echo stream.readLine() # Will call `recv` again
## stream.close() # Closes the socket
## ```
##
## .. code-block:: Nim
## ```Nim
## import std/socketstreams
##
## import std/socketstreams
##
## var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
## socket.connect("127.0.0.1", Port(12345))
## var sendStream = newWriteSocketStream(socket)
## sendStream.write "NOM"
## sendStream.setPosition(1)
## echo sendStream.peekStr(2) # OM
## sendStream.write "I"
## sendStream.setPosition(0)
## echo sendStream.readStr(3) # NIM
## echo sendStream.getPosition() # 3
## sendStream.flush() # This actually performs the writing to the socket
## sendStream.setPosition(1)
## sendStream.write "I" # Throws an error as we can't write into an already sent buffer
## var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
## socket.connect("127.0.0.1", Port(12345))
## var sendStream = newWriteSocketStream(socket)
## sendStream.write "NOM"
## sendStream.setPosition(1)
## echo sendStream.peekStr(2) # OM
## sendStream.write "I"
## sendStream.setPosition(0)
## echo sendStream.readStr(3) # NIM
## echo sendStream.getPosition() # 3
## sendStream.flush() # This actually performs the writing to the socket
## sendStream.setPosition(1)
## sendStream.write "I" # Throws an error as we can't write into an already sent buffer
## ```
import net, streams

View File

@@ -12,27 +12,27 @@
## Examples
## ========
##
## .. code-block:: Nim
## ```Nim
## import std/locks
##
## import std/locks
## var
## thr: array[0..4, Thread[tuple[a,b: int]]]
## L: Lock
##
## var
## thr: array[0..4, Thread[tuple[a,b: int]]]
## L: Lock
## proc threadFunc(interval: tuple[a,b: int]) {.thread.} =
## for i in interval.a..interval.b:
## acquire(L) # lock stdout
## echo i
## release(L)
##
## proc threadFunc(interval: tuple[a,b: int]) {.thread.} =
## for i in interval.a..interval.b:
## acquire(L) # lock stdout
## echo i
## release(L)
## initLock(L)
##
## initLock(L)
## for i in 0..high(thr):
## createThread(thr[i], threadFunc, (i*10, i*10+5))
## joinThreads(thr)
##
## for i in 0..high(thr):
## createThread(thr[i], threadFunc, (i*10, i*10+5))
## joinThreads(thr)
##
## deinitLock(L)
## deinitLock(L)
## ```

View File

@@ -2408,9 +2408,9 @@ when defined(nimV2):
proc repr*[T, U](x: HSlice[T, U]): string =
## Generic `repr` operator for slices that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## $(1 .. 5) == "1 .. 5"
## ```Nim
## $(1 .. 5) == "1 .. 5"
## ```
result = repr(x.a)
result.add(" .. ")
result.add(repr(x.b))

View File

@@ -26,7 +26,7 @@
## The following is a simple example of two different ways to use channels:
## blocking and non-blocking.
##
## .. code-block:: Nim
## ```Nim
## # Be sure to compile with --threads:on.
## # The channels and threads modules are part of system and should not be
## # imported.
@@ -87,6 +87,7 @@
##
## # Clean up the channel.
## chan.close()
## ```
##
## Sample output
## -------------
@@ -113,7 +114,7 @@
## using e.g. `system.allocShared0` and pass these pointers through thread
## arguments:
##
## .. code-block:: Nim
## ```Nim
## proc worker(channel: ptr Channel[string]) =
## let greeting = channel[].recv()
## echo greeting
@@ -135,6 +136,7 @@
## deallocShared(channel)
##
## localChannelExample() # "Hello from the main thread!"
## ```
when not declared(ThisIsSystem):
{.error: "You must not import this module explicitly".}

View File

@@ -41,9 +41,9 @@ proc `$`*(x: bool): string {.magic: "BoolToStr", noSideEffect.}
proc `$`*(x: char): string {.magic: "CharToStr", noSideEffect.}
## The stringify operator for a character argument. Returns `x`
## converted to a string.
##
## .. code-block:: Nim
## ```Nim
## assert $'c' == "c"
## ```
proc `$`*(x: cstring): string {.magic: "CStrToStr", noSideEffect.}
## The stringify operator for a CString argument. Returns `x`
@@ -67,19 +67,20 @@ proc `$`*(t: typedesc): string {.magic: "TypeTrait".}
## For more procedures dealing with `typedesc`, see
## `typetraits module <typetraits.html>`_.
##
## .. code-block:: Nim
## ```Nim
## doAssert $(typeof(42)) == "int"
## doAssert $(typeof("Foo")) == "string"
## static: doAssert $(typeof(@['A', 'B'])) == "seq[char]"
## ```
proc `$`*[T: tuple](x: T): string =
## Generic `$` operator for tuples that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(23, 45) == "(23, 45)"
## $(a: 23, b: 45) == "(a: 23, b: 45)"
## $() == "()"
## ```
tupleObjectDollar(result, x)
when not defined(nimPreviewSlimSystem):
@@ -108,25 +109,25 @@ proc collectionToString[T](x: T, prefix, separator, suffix: string): string =
proc `$`*[T](x: set[T]): string =
## Generic `$` operator for sets that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## ${23, 45} == "{23, 45}"
## ```
collectionToString(x, "{", ", ", "}")
proc `$`*[T](x: seq[T]): string =
## Generic `$` operator for seqs that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(@[23, 45]) == "@[23, 45]"
## ```
collectionToString(x, "@[", ", ", "]")
proc `$`*[T, U](x: HSlice[T, U]): string =
## Generic `$` operator for slices that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(1 .. 5) == "1 .. 5"
## ```
result = $x.a
result.add(" .. ")
result.add($x.b)
@@ -140,7 +141,7 @@ when not defined(nimNoArrayToString):
proc `$`*[T](x: openArray[T]): string =
## Generic `$` operator for openarrays that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(@[23, 45].toOpenArray(0, 1)) == "[23, 45]"
## ```
collectionToString(x, "[", ", ", "]")

View File

@@ -31,7 +31,7 @@ In Nim the compiler cannot always know if a reference
is stored on the stack or not. This is caused by var parameters.
Consider this example:
.. code-block:: Nim
```Nim
proc setRef(r: var ref TNode) =
new(r)
@@ -41,11 +41,12 @@ Consider this example:
setRef(r) # here we should not update the reference counts, because
# r is on the stack
setRef(r.left) # here we should update the refcounts!
```
We have to decide at runtime whether the reference is on the stack or not.
The generated code looks roughly like this:
.. code-block:: C
```C
void setref(TNode** ref) {
unsureAsgnRef(ref, newObj(TNode_TI, sizeof(TNode)))
}
@@ -53,6 +54,7 @@ The generated code looks roughly like this:
setRef(&r)
setRef(&r->left)
}
```
Note that for systems with a continuous stack (which most systems have)
the check whether the ref is on the stack is very cheap (only two

View File

@@ -89,10 +89,9 @@ proc patchFile*(package, filename, replacement: string) =
## The compiler also performs `path substitution <nimc.html#compiler-usage-commandminusline-switches>`_ on `replacement`.
##
## Example:
##
## .. code-block:: nim
##
## ```nim
## patchFile("stdlib", "asyncdispatch", "patches/replacement")
## ```
discard
proc getCommand*(): string =
@@ -159,20 +158,18 @@ proc strip(s: string): string =
template `--`*(key, val: untyped) =
## A shortcut for `switch <#switch,string,string>`_
## Example:
##
## .. code-block:: nim
##
## ```nim
## --path:somePath # same as switch("path", "somePath")
## --path:"someOtherPath" # same as switch("path", "someOtherPath")
## ```
switch(strip(astToStr(key)), strip(astToStr(val)))
template `--`*(key: untyped) =
## A shortcut for `switch <#switch,string,string>`_
## Example:
##
## .. code-block:: nim
##
## ```nim
## --listCmd # same as switch("listCmd")
## ```
switch(strip(astToStr(key)))
type
@@ -341,12 +338,12 @@ template withDir*(dir: string; body: untyped): untyped =
##
## If you need a permanent change, use the `cd() <#cd,string>`_ proc.
## Usage example:
##
## .. code-block:: nim
## ```nim
## # inside /some/path/
## withDir "foo":
## # move to /some/path/foo/
## # back in /some/path/
## ```
let curDir = getCurrentDir()
try:
cd(dir)
@@ -391,10 +388,10 @@ when not defined(nimble):
## Defines a task. Hidden tasks are supported via an empty description.
##
## Example:
##
## .. code-block:: nim
## task build, "default build is via the C backend":
## setCommand "c"
## ```nim
## task build, "default build is via the C backend":
## setCommand "c"
## ```
##
## For a task named `foo`, this template generates a `proc` named
## `fooTask`. This is useful if you need to call one task in
@@ -402,13 +399,14 @@ when not defined(nimble):
##
## Example:
##
## .. code-block:: nim
## task foo, "foo": # > nim foo
## echo "Running foo" # Running foo
## ```nim
## task foo, "foo": # > nim foo
## echo "Running foo" # Running foo
##
## task bar, "bar": # > nim bar
## echo "Running bar" # Running bar
## fooTask() # Running foo
## task bar, "bar": # > nim bar
## echo "Running bar" # Running bar
## fooTask() # Running foo
## ```
proc `name Task`*() =
setCommand "nop"
body

View File

@@ -38,8 +38,9 @@ proc repr*(x: char): string {.noSideEffect, raises: [].} =
## repr for a character argument. Returns `x`
## converted to an escaped string.
##
## .. code-block:: Nim
## ```Nim
## assert repr('c') == "'c'"
## ```
result.add '\''
# Elides string creations if not needed
if x in {'\\', '\0'..'\31', '\127'..'\255'}:
@@ -132,11 +133,11 @@ proc reprObject[T: tuple|object](res: var string, x: T) {.noSideEffect, raises:
proc repr*[T: tuple|object](x: T): string {.noSideEffect, raises: [].} =
## Generic `repr` operator for tuples that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(23, 45) == "(23, 45)"
## $(a: 23, b: 45) == "(a: 23, b: 45)"
## $() == "()"
## ```
when T is object:
result = $typeof(x)
reprObject(result, x)
@@ -164,17 +165,17 @@ proc collectionToRepr[T](x: T, prefix, separator, suffix: string): string {.noSi
proc repr*[T](x: set[T]): string =
## Generic `repr` operator for sets that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## ${23, 45} == "{23, 45}"
## ```
collectionToRepr(x, "{", ", ", "}")
proc repr*[T](x: seq[T]): string =
## Generic `repr` operator for seqs that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(@[23, 45]) == "@[23, 45]"
## ```
collectionToRepr(x, "@[", ", ", "]")
proc repr*[T, IDX](x: array[IDX, T]): string =
@@ -184,9 +185,9 @@ proc repr*[T, IDX](x: array[IDX, T]): string =
proc repr*[T](x: openArray[T]): string =
## Generic `repr` operator for openarrays that is lifted from the components
## of `x`. Example:
##
## .. code-block:: Nim
## ```Nim
## $(@[23, 45].toOpenArray(0, 1)) == "[23, 45]"
## ```
collectionToRepr(x, "[", ", ", "]")
proc repr*[T](x: UncheckedArray[T]): string =

View File

@@ -18,12 +18,13 @@
##
## Build and test examples:
##
## .. code-block::
## ```cmd
## ./bin/nim c -d:ssl -p:. -r tests/stdlib/tssl.nim
## ./bin/nim c -d:ssl --threads:on -p:. -r tests/stdlib/thttpclient_ssl.nim
## ./bin/nim c -d:ssl -p:. -r tests/untestable/tssl.nim
## ./bin/nim c -d:ssl -p:. --dynlibOverride:ssl --passl:-lcrypto --passl:-lssl -r tests/untestable/tssl.nim
## ./bin/nim r --putenv:NIM_TESTAMENT_REMOTE_NETWORKING:1 -d:ssl -p:testament/lib --threads:on tests/untestable/thttpclient_ssl_remotenetwork.nim
## ```
# https://www.feistyduck.com/library/openssl-cookbook/online/ch-testing-with-openssl.html
#

View File

@@ -693,11 +693,11 @@ proc newRecordGen(ctx: Context; typ: TypRef): PNode =
String `interpolation`:idx: / `format`:idx: inspired by
Python's ``f``-strings.
.. code-block:: nim
import strformat
let msg = "hello"
doAssert fmt"{msg}\n" == "hello\\n"
```nim
import strformat
let msg = "hello"
doAssert fmt"{msg}\n" == "hello\\n"
```
Because the literal is a raw string literal, the ``\n`` is not interpreted as
an escape sequence.

View File

@@ -699,11 +699,11 @@ proc newRecordGen(ctx: Context; typ: TypRef): PNode =
String `interpolation`:idx: / `format`:idx: inspired by
Python's ``f``-strings.
.. code-block:: nim
import strformat
let msg = "hello"
doAssert fmt"{msg}\n" == "hello\\n"
```nim
import strformat
let msg = "hello"
doAssert fmt"{msg}\n" == "hello\\n"
```
Because the literal is a raw string literal, the ``\n`` is not interpreted as
an escape sequence.

View File

@@ -143,27 +143,26 @@ proc extractErrorMsg(s: string; i: int; line: var int; col: var int; spec: var T
##
## Can parse a single message for a line:
##
## .. code-block:: nim
##
## ```nim
## proc generic_proc*[T] {.no_destroy, userPragma.} = #[tt.Error
## ^ 'generic_proc' should be: 'genericProc' [Name] ]#
## ```
##
## Can parse multiple messages for a line when they are separated by ';':
##
## .. code-block:: nim
##
## ```nim
## proc generic_proc*[T] {.no_destroy, userPragma.} = #[tt.Error
## ^ 'generic_proc' should be: 'genericProc' [Name]; tt.Error
## ^ 'no_destroy' should be: 'nodestroy' [Name]; tt.Error
## ^ 'userPragma' should be: 'user_pragma' [template declared in mstyleCheck.nim(10, 9)] [Name] ]#
## ```
##
## .. code-block:: nim
##
## ```nim
## proc generic_proc*[T] {.no_destroy, userPragma.} = #[tt.Error
## ^ 'generic_proc' should be: 'genericProc' [Name];
## tt.Error ^ 'no_destroy' should be: 'nodestroy' [Name];
## tt.Error ^ 'userPragma' should be: 'user_pragma' [template declared in mstyleCheck.nim(10, 9)] [Name] ]#
##
## ```
result = i + len(inlineErrorMarker)
inc col, len(inlineErrorMarker)
let msgLine = line

View File

@@ -168,14 +168,14 @@ template new_parsed_parameter*(tkind: Tparam_kind, expr): Tparsed_parameter =
## initialised with. The template figures out at compile time what field to
## assign the variable to, and thus you reduce code clutter and may use this
## to initialise single assignments variables in `let` blocks. Example:
##
## .. code-block:: nim
## ```nim
## let
## parsed_param1 = new_parsed_parameter(PK_FLOAT, 3.41)
## parsed_param2 = new_parsed_parameter(PK_BIGGEST_INT, 2358123 * 23123)
## # The following line doesn't compile due to
## # type mismatch: got <string> but expected 'int'
## #parsed_param3 = new_parsed_parameter(PK_INT, "231")
## ```
var result {.gensym.}: Tparsed_parameter
result.kind = tkind
when tkind == PK_EMPTY: discard