diff options
author | Araq <rumpf_a@web.de> | 2014-07-22 20:23:28 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-07-22 20:23:28 +0200 |
commit | 821fe72ff55866737c5b1d9f356b8d142f8836c3 (patch) | |
tree | 28c3eaaccc8772529e1818f8287854c4e93494b7 | |
parent | 725cf0e22d4f8185e8b6d182f7e8a959b77e049a (diff) | |
parent | 479b2c629610c7377db788b9de6025d02147df45 (diff) | |
download | Nim-821fe72ff55866737c5b1d9f356b8d142f8836c3.tar.gz |
Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
-rw-r--r-- | doc/manual.txt | 6 | ||||
-rw-r--r-- | lib/pure/collections/sequtils.nim | 3 | ||||
-rw-r--r-- | lib/pure/parsecfg.nim | 3 | ||||
-rw-r--r-- | lib/pure/parseurl.nim | 4 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 276 | ||||
-rw-r--r-- | lib/pure/uri.nim | 350 | ||||
-rw-r--r-- | lib/system.nim | 26 | ||||
-rw-r--r-- | tests/stdlib/testequivalence.nim | 1 | ||||
-rw-r--r-- | web/index.txt | 2 | ||||
-rw-r--r-- | web/news.txt | 4 | ||||
-rw-r--r-- | web/nimrod.ini | 2 |
11 files changed, 549 insertions, 128 deletions
diff --git a/doc/manual.txt b/doc/manual.txt index 32b0541e9..54c1477e8 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -4970,9 +4970,9 @@ or ``ref T`` or ``ptr T`` this means no locations are modified. It is a static error to mark a proc/iterator to have no side effect if the compiler cannot verify this. -As a special semantic rule, the built-in ``debugEcho`` pretends to be free of -side effects, so that it can be used for debugging routines marked as -``noSideEffect``. +As a special semantic rule, the built-in `debugEcho <system.html#debugEcho>`_ +pretends to be free of side effects, so that it can be used for debugging +routines marked as ``noSideEffect``. **Future directions**: ``func`` may become a keyword and syntactic sugar for a proc with no side effects: diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index e760c5e02..c50c4165b 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -186,7 +186,7 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) = ## ## .. code-block:: nimrod ## var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1] - ## filter(floats, proc(x: float): bool = x > 10) + ## keepIf(floats, proc(x: float): bool = x > 10) ## assert floats == @[13.0, 12.5, 10.1] var pos = 0 for i in 0 .. <len(seq1): @@ -388,6 +388,7 @@ template mapIt*(seq1, typ, pred: expr): expr = ## let ## nums = @[1, 2, 3, 4] ## strings = nums.mapIt(string, $(4 * it)) + ## assert strings == @["4", "8", "12", "16"] var result {.gensym.}: seq[typ] = @[] for it {.inject.} in items(seq1): result.add(pred) diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index 727a8efd8..1d61a967b 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -350,7 +350,8 @@ proc next*(c: var TCfgParser): TCfgEvent {.rtl, extern: "npc$1".} = rawGetTok(c, c.tok) if c.tok.kind == tkBracketRi: rawGetTok(c, c.tok) - else: + else: + reset(result) result.kind = cfgError result.msg = errorStr(c, "']' expected, but found: " & c.tok.literal) of tkInvalid, tkEquals, tkColon, tkBracketRi: diff --git a/lib/pure/parseurl.nim b/lib/pure/parseurl.nim index 357d1df0f..67c6de905 100644 --- a/lib/pure/parseurl.nim +++ b/lib/pure/parseurl.nim @@ -20,7 +20,7 @@ type scheme, username, password, hostname, port, path, query, anchor: string] -proc parseUrl*(url: string): TUrl = +proc parseUrl*(url: string): TUrl {.deprecated.} = var i = 0 var scheme, username, password: string = "" @@ -86,7 +86,7 @@ proc parseUrl*(url: string): TUrl = return (scheme, username, password, hostname, port, path, query, anchor) -proc `$`*(u: TUrl): string = +proc `$`*(u: TUrl): string {.deprecated.} = ## turns the URL `u` into its string representation. result = "" if u.scheme.len > 0: diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 51392ba50..6f8924d83 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -48,9 +48,11 @@ const ## the set of characters a newline terminator can start with AllChars* = {'\x00'..'\xFF'} - ## A set with all the possible characters. Not very useful by its own, you - ## can use it to create *inverted* sets to make the ``find()`` proc find - ## **invalid** characters in strings. Example: + ## A set with all the possible characters. + ## + ## Not very useful by its own, you can use it to create *inverted* sets to + ## make the `find() proc <#find,string,set[char],int>`_ find **invalid** + ## characters in strings. Example: ## ## .. code-block:: nimrod ## let invalid = AllChars - Digits @@ -59,8 +61,11 @@ const proc toLower*(c: char): char {.noSideEffect, procvar, rtl, extern: "nsuToLowerChar".} = - ## Converts `c` into lower case. This works only for the letters A-Z. - ## See `unicode.toLower` for a version that works for any Unicode character. + ## Converts `c` into lower case. + ## + ## This works only for the letters ``A-Z``. See `unicode.toLower + ## <unicode.html#toLower>`_ for a version that works for any Unicode + ## character. if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A'))) else: @@ -68,16 +73,22 @@ proc toLower*(c: char): char {.noSideEffect, procvar, proc toLower*(s: string): string {.noSideEffect, procvar, rtl, extern: "nsuToLowerStr".} = - ## Converts `s` into lower case. This works only for the letters A-Z. - ## See `unicode.toLower` for a version that works for any Unicode character. + ## Converts `s` into lower case. + ## + ## This works only for the letters ``A-Z``. See `unicode.toLower + ## <unicode.html#toLower>`_ for a version that works for any Unicode + ## character. result = newString(len(s)) for i in 0..len(s) - 1: result[i] = toLower(s[i]) proc toUpper*(c: char): char {.noSideEffect, procvar, rtl, extern: "nsuToUpperChar".} = - ## Converts `c` into upper case. This works only for the letters a-z. - ## See `unicode.toUpper` for a version that works for any Unicode character. + ## Converts `c` into upper case. + ## + ## This works only for the letters ``A-Z``. See `unicode.toUpper + ## <unicode.html#toUpper>`_ for a version that works for any Unicode + ## character. if c in {'a'..'z'}: result = chr(ord(c) - (ord('a') - ord('A'))) else: @@ -85,8 +96,11 @@ proc toUpper*(c: char): char {.noSideEffect, procvar, proc toUpper*(s: string): string {.noSideEffect, procvar, rtl, extern: "nsuToUpperStr".} = - ## Converts `s` into upper case. This works only for the letters a-z. - ## See `unicode.toUpper` for a version that works for any Unicode character. + ## Converts `s` into upper case. + ## + ## This works only for the letters ``A-Z``. See `unicode.toUpper + ## <unicode.html#toUpper>`_ for a version that works for any Unicode + ## character. result = newString(len(s)) for i in 0..len(s) - 1: result[i] = toUpper(s[i]) @@ -94,13 +108,16 @@ proc toUpper*(s: string): string {.noSideEffect, procvar, proc capitalize*(s: string): string {.noSideEffect, procvar, rtl, extern: "nsuCapitalize".} = ## Converts the first character of `s` into upper case. - ## This works only for the letters a-z. + ## + ## This works only for the letters ``A-Z``. result = toUpper(s[0]) & substr(s, 1) proc normalize*(s: string): string {.noSideEffect, procvar, rtl, extern: "nsuNormalize".} = - ## Normalizes the string `s`. That means to convert it to lower case and - ## remove any '_'. This is needed for Nimrod identifiers for example. + ## Normalizes the string `s`. + ## + ## That means to convert it to lower case and remove any '_'. This is needed + ## for Nimrod identifiers for example. result = newString(s.len) var j = 0 for i in 0..len(s) - 1: @@ -155,6 +172,7 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect, rtl, extern: "nsuStrip", operator: 5.} = ## Strips whitespace from `s` and returns the resulting string. + ## ## If `leading` is true, leading whitespace is stripped. ## If `trailing` is true, trailing whitespace is stripped. const @@ -169,8 +187,10 @@ proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect, result = substr(s, first, last) proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} = - ## Converts a character `c` to its octal representation. The resulting - ## string may not have a leading zero. Its length is always exactly 3. + ## Converts a character `c` to its octal representation. + ## + ## The resulting string may not have a leading zero. Its length is always + ## exactly 3. result = newString(3) var val = ord(c) for i in countdown(2, 0): @@ -280,9 +300,11 @@ iterator split*(s: string, sep: string): string = inc(last, sep.len) iterator splitLines*(s: string): string = - ## Splits the string `s` into its containing lines. Every newline - ## combination (CR, LF, CR-LF) is supported. The result strings contain - ## no trailing ``\n``. + ## Splits the string `s` into its containing lines. + ## + ## Every `character literal <manual.html#character-literals>`_ newline + ## combination (CR, LF, CR-LF) is supported. The result strings contain no + ## trailing ``\n``. ## ## Example: ## @@ -315,13 +337,25 @@ iterator splitLines*(s: string): string = proc splitLines*(s: string): seq[string] {.noSideEffect, rtl, extern: "nsuSplitLines".} = - ## The same as the `splitLines` iterator, but is a proc that returns a - ## sequence of substrings. + ## The same as the `splitLines <#splitLines.i,string>`_ iterator, but is a + ## proc that returns a sequence of substrings. accumulateResult(splitLines(s)) proc countLines*(s: string): int {.noSideEffect, rtl, extern: "nsuCountLines".} = - ## same as ``len(splitLines(s))``, but much more efficient. + ## Returns the number of new line separators in the string `s`. + ## + ## This is the same as ``len(splitLines(s))``, but much more efficient + ## because it doesn't modify the string creating temporal objects. Every + ## `character literal <manual.html#character-literals>`_ newline combination + ## (CR, LF, CR-LF) is supported. + ## + ## Despite its name this proc might not actually return the *number of lines* + ## in `s` because the concept of what a line is can vary. For example, a + ## string like ``Hello world`` is a line of text, but the proc will return a + ## value of zero because there are no newline separators. Also, text editors + ## usually don't count trailing newline characters in a text file as a new + ## empty line, but this proc will. var i = 0 while i < s.len: case s[i] @@ -334,28 +368,30 @@ proc countLines*(s: string): int {.noSideEffect, proc split*(s: string, seps: set[char] = Whitespace): seq[string] {. noSideEffect, rtl, extern: "nsuSplitCharSet".} = - ## The same as the `split` iterator, but is a proc that returns a - ## sequence of substrings. + ## The same as the `split iterator <#split.i,string,set[char]>`_, but is a + ## proc that returns a sequence of substrings. accumulateResult(split(s, seps)) proc split*(s: string, sep: char): seq[string] {.noSideEffect, rtl, extern: "nsuSplitChar".} = - ## The same as the `split` iterator, but is a proc that returns a sequence - ## of substrings. + ## The same as the `split iterator <#split.i,string,char>`_, but is a proc + ## that returns a sequence of substrings. accumulateResult(split(s, sep)) proc split*(s: string, sep: string): seq[string] {.noSideEffect, rtl, extern: "nsuSplitString".} = ## Splits the string `s` into substrings using a string separator. ## - ## Substrings are separated by the string `sep`. + ## Substrings are separated by the string `sep`. This is a wrapper around the + ## `split iterator <#split.i,string,string>`_. accumulateResult(split(s, sep)) proc toHex*(x: BiggestInt, len: int): string {.noSideEffect, rtl, extern: "nsuToHex".} = - ## Converts `x` to its hexadecimal representation. The resulting string - ## will be exactly `len` characters long. No prefix like ``0x`` - ## is generated. `x` is treated as an unsigned value. + ## Converts `x` to its hexadecimal representation. + ## + ## The resulting string will be exactly `len` characters long. No prefix like + ## ``0x`` is generated. `x` is treated as an unsigned value. const HexChars = "0123456789ABCDEF" var @@ -367,9 +403,10 @@ proc toHex*(x: BiggestInt, len: int): string {.noSideEffect, proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect, rtl, extern: "nsuIntToStr".} = - ## Converts `x` to its decimal representation. The resulting string - ## will be minimally `minchars` characters long. This is achieved by - ## adding leading zeros. + ## Converts `x` to its decimal representation. + ## + ## The resulting string will be minimally `minchars` characters long. This is + ## achieved by adding leading zeros. result = $abs(x) for i in 1 .. minchars - len(result): result = '0' & result @@ -378,16 +415,18 @@ proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect, proc parseInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseInt".} = - ## Parses a decimal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. + ## Parses a decimal integer value contained in `s`. + ## + ## If `s` is not a valid integer, `EInvalidValue` is raised. var L = parseutils.parseInt(s, result, 0) if L != s.len or L == 0: raise newException(EInvalidValue, "invalid integer: " & s) proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, rtl, extern: "nsuParseBiggestInt".} = - ## Parses a decimal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. + ## Parses a decimal integer value contained in `s`. + ## + ## If `s` is not a valid integer, `EInvalidValue` is raised. var L = parseutils.parseBiggestInt(s, result, 0) if L != s.len or L == 0: raise newException(EInvalidValue, "invalid integer: " & s) @@ -403,10 +442,11 @@ proc parseFloat*(s: string): float {.noSideEffect, procvar, proc parseHexInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseHexInt".} = - ## Parses a hexadecimal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. `s` can have one of the - ## following optional prefixes: ``0x``, ``0X``, ``#``. - ## Underscores within `s` are ignored. + ## Parses a hexadecimal integer value contained in `s`. + ## + ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one + ## of the following optional prefixes: ``0x``, ``0X``, ``#``. Underscores + ## within `s` are ignored. var i = 0 if s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2) elif s[i] == '#': inc(i) @@ -426,26 +466,32 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar, else: raise newException(EInvalidValue, "invalid integer: " & s) proc parseBool*(s: string): bool = - ## Parses a value into a `bool`. If ``s`` is one of the following values: - ## ``y, yes, true, 1, on``, then returns `true`. If ``s`` is one of the - ## following values: ``n, no, false, 0, off``, then returns `false`. - ## If ``s`` is something else a ``EInvalidValue`` exception is raised. + ## Parses a value into a `bool`. + ## + ## If ``s`` is one of the following values: ``y, yes, true, 1, on``, then + ## returns `true`. If ``s`` is one of the following values: ``n, no, false, + ## 0, off``, then returns `false`. If ``s`` is something else a + ## ``EInvalidValue`` exception is raised. case normalize(s) of "y", "yes", "true", "1", "on": result = true of "n", "no", "false", "0", "off": result = false else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) proc parseEnum*[T: enum](s: string): T = - ## parses an enum ``T``. Raises ``EInvalidValue`` for an invalid value in - ## `s`. The comparison is done in a style insensitive way. + ## Parses an enum ``T``. + ## + ## Raises ``EInvalidValue`` for an invalid value in `s`. The comparison is + ## done in a style insensitive way. for e in low(T)..high(T): if cmpIgnoreStyle(s, $e) == 0: return e raise newException(EInvalidValue, "invalid enum value: " & s) proc parseEnum*[T: enum](s: string, default: T): T = - ## parses an enum ``T``. Uses `default` for an invalid value in - ## `s`. The comparison is done in a style insensitive way. + ## Parses an enum ``T``. + ## + ## Uses `default` for an invalid value in `s`. The comparison is done in a + ## style insensitive way. for e in low(T)..high(T): if cmpIgnoreStyle(s, $e) == 0: return e @@ -475,10 +521,11 @@ proc repeatStr*(count: int, s: string): string {.noSideEffect, proc align*(s: string, count: int, padding = ' '): string {. noSideEffect, rtl, extern: "nsuAlignString".} = ## Aligns a string `s` with `padding`, so that is of length `count`. + ## ## `padding` characters (by default spaces) are added before `s` resulting in ## right alignment. If ``s.len >= count``, no spaces are added and `s` is - ## returned unchanged. If you need to left align a string use the - ## ``repeatChar`` proc. Example: + ## returned unchanged. If you need to left align a string use the `repeatChar + ## proc <#repeatChar>`_. Example: ## ## .. code-block:: nimrod ## assert align("abc", 4) == " abc" @@ -532,7 +579,7 @@ proc wordWrap*(s: string, maxLineWidth = 80, seps: set[char] = Whitespace, newLine = "\n"): string {. noSideEffect, rtl, extern: "nsuWordWrap".} = - ## word wraps `s`. + ## Word wraps `s`. result = newStringOfCap(s.len + s.len shr 6) var spaceLeft = maxLineWidth var lastSep = "" @@ -564,7 +611,7 @@ proc wordWrap*(s: string, maxLineWidth = 80, proc unindent*(s: string, eatAllIndent = false): string {. noSideEffect, rtl, extern: "nsuUnindent".} = - ## unindents `s`. + ## Unindents `s`. result = newStringOfCap(s.len) var i = 0 var pattern = true @@ -592,6 +639,7 @@ proc unindent*(s: string, eatAllIndent = false): string {. proc startsWith*(s, prefix: string): bool {.noSideEffect, rtl, extern: "nsuStartsWith".} = ## Returns true iff ``s`` starts with ``prefix``. + ## ## If ``prefix == ""`` true is returned. var i = 0 while true: @@ -602,6 +650,7 @@ proc startsWith*(s, prefix: string): bool {.noSideEffect, proc endsWith*(s, suffix: string): bool {.noSideEffect, rtl, extern: "nsuEndsWith".} = ## Returns true iff ``s`` ends with ``suffix``. + ## ## If ``suffix == ""`` true is returned. var i = 0 var j = len(s) - len(suffix) @@ -613,6 +662,7 @@ proc endsWith*(s, suffix: string): bool {.noSideEffect, proc continuesWith*(s, substr: string, start: int): bool {.noSideEffect, rtl, extern: "nsuContinuesWith".} = ## Returns true iff ``s`` continues with ``substr`` at position ``start``. + ## ## If ``substr == ""`` true is returned. var i = 0 while true: @@ -622,6 +672,8 @@ proc continuesWith*(s, substr: string, start: int): bool {.noSideEffect, proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, inline.} = + ## Adds a separator to `dest` only if its length is bigger than `startLen`. + ## ## A shorthand for: ## ## .. code-block:: nimrod @@ -641,15 +693,15 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, if dest.len > startLen: add(dest, sep) proc allCharsInSet*(s: string, theSet: TCharSet): bool = - ## returns true iff each character of `s` is in the set `theSet`. + ## Returns true iff each character of `s` is in the set `theSet`. for c in items(s): if c notin theSet: return false return true proc abbrev*(s: string, possibilities: openArray[string]): int = - ## returns the index of the first item in `possibilities` if not - ## ambiguous; -1 if no item has been found; -2 if multiple items - ## match. + ## Returns the index of the first item in `possibilities` if not ambiguous. + ## + ## Returns -1 if no item has been found and -2 if multiple items match. result = -1 # none found for i in 0..possibilities.len-1: if possibilities[i].startsWith(s): @@ -663,7 +715,7 @@ proc abbrev*(s: string, possibilities: openArray[string]): int = proc join*(a: openArray[string], sep: string): string {. noSideEffect, rtl, extern: "nsuJoinSep".} = - ## concatenates all strings in `a` separating them with `sep`. + ## Concatenates all strings in `a` separating them with `sep`. if len(a) > 0: var L = sep.len * (a.len-1) for i in 0..high(a): inc(L, a[i].len) @@ -677,7 +729,7 @@ proc join*(a: openArray[string], sep: string): string {. proc join*(a: openArray[string]): string {. noSideEffect, rtl, extern: "nsuJoin".} = - ## concatenates all strings in `a`. + ## Concatenates all strings in `a`. if len(a) > 0: var L = 0 for i in 0..high(a): inc(L, a[i].len) @@ -695,7 +747,7 @@ proc preprocessSub(sub: string, a: var TSkipTable) = for i in 0..m-1: a[sub[i]] = m-i proc findAux(s, sub: string, start: int, a: TSkipTable): int = - # fast "quick search" algorithm: + # Fast "quick search" algorithm: var m = len(sub) n = len(s) @@ -711,32 +763,36 @@ proc findAux(s, sub: string, start: int, a: TSkipTable): int = proc find*(s, sub: string, start: int = 0): int {.noSideEffect, rtl, extern: "nsuFindStr", operator: 6.} = - ## Searches for `sub` in `s` starting at position `start`. Searching is - ## case-sensitive. If `sub` is not in `s`, -1 is returned. + ## Searches for `sub` in `s` starting at position `start`. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. var a {.noinit.}: TSkipTable preprocessSub(sub, a) result = findAux(s, sub, start, a) proc find*(s: string, sub: char, start: int = 0): int {.noSideEffect, rtl, extern: "nsuFindChar".} = - ## Searches for `sub` in `s` starting at position `start`. Searching is - ## case-sensitive. If `sub` is not in `s`, -1 is returned. + ## Searches for `sub` in `s` starting at position `start`. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. for i in start..len(s)-1: if sub == s[i]: return i return -1 proc find*(s: string, chars: set[char], start: int = 0): int {.noSideEffect, rtl, extern: "nsuFindCharSet".} = - ## Searches for `chars` in `s` starting at position `start`. If `s` contains - ## none of the characters in `chars`, -1 is returned. + ## Searches for `chars` in `s` starting at position `start`. + ## + ## If `s` contains none of the characters in `chars`, -1 is returned. for i in start..s.len-1: if s[i] in chars: return i return -1 proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = ## Searches for `sub` in `s` in reverse, starting at `start` and going - ## backwards to 0. Searching is case-sensitive. If `sub` is not in `s`, -1 is - ## returned. + ## backwards to 0. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. let realStart = if start == -1: s.len else: start for i in countdown(realStart-sub.len, 0): for j in 0..sub.len-1: @@ -748,10 +804,11 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = return -1 proc quoteIfContainsWhite*(s: string): string {.deprecated.} = - ## returns ``'"' & s & '"'`` if `s` contains a space and does not - ## start with a quote, else returns `s` - ## DEPRECATED as it was confused for shell quoting function. - ## For this application use osproc.quoteShell. + ## Returns ``'"' & s & '"'`` if `s` contains a space and does not + ## start with a quote, else returns `s`. + ## + ## **DEPRECATED** as it was confused for shell quoting function. For this + ## application use `osproc.quoteShell <osproc.html#quoteShell>`_. if find(s, {' ', '\t'}) >= 0 and s[0] != '"': result = '"' & s & '"' else: @@ -787,7 +844,9 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect, proc replace*(s: string, sub, by: char): string {.noSideEffect, rtl, extern: "nsuReplaceChar".} = - ## optimized version for characters. + ## Replaces `sub` in `s` by the character `by`. + ## + ## Optimized version of `replace <#replace,string,string>`_ for characters. result = newString(s.len) var i = 0 while i < s.len: @@ -797,9 +856,11 @@ proc replace*(s: string, sub, by: char): string {.noSideEffect, proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, rtl, extern: "nsuReplaceWord".} = - ## Replaces `sub` in `s` by the string `by`. Each occurance of `sub` - ## has to be surrounded by word boundaries (comparable to ``\\w`` in - ## regular expressions), otherwise it is not replaced. + ## Replaces `sub` in `s` by the string `by`. + ## + ## Each occurance of `sub` has to be surrounded by word boundaries + ## (comparable to ``\\w`` in regular expressions), otherwise it is not + ## replaced. const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} var a {.noinit.}: TSkipTable result = "" @@ -822,8 +883,9 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, proc delete*(s: var string, first, last: int) {.noSideEffect, rtl, extern: "nsuDelete".} = - ## Deletes in `s` the characters at position `first` .. `last`. This modifies - ## `s` itself, it does not return a copy. + ## Deletes in `s` the characters at position `first` .. `last`. + ## + ## This modifies `s` itself, it does not return a copy. var i = first var j = last+1 var newLen = len(s)-j+i @@ -835,10 +897,11 @@ proc delete*(s: var string, first, last: int) {.noSideEffect, proc parseOctInt*(s: string): int {.noSideEffect, rtl, extern: "nsuParseOctInt".} = - ## Parses an octal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. `s` can have one of the - ## following optional prefixes: ``0o``, ``0O``. - ## Underscores within `s` are ignored. + ## Parses an octal integer value contained in `s`. + ## + ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one + ## of the following optional prefixes: ``0o``, ``0O``. Underscores within + ## `s` are ignored. var i = 0 if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2) while true: @@ -852,8 +915,10 @@ proc parseOctInt*(s: string): int {.noSideEffect, proc toOct*(x: BiggestInt, len: int): string {.noSideEffect, rtl, extern: "nsuToOct".} = - ## converts `x` into its octal representation. The resulting string is - ## always `len` characters long. No leading ``0o`` prefix is generated. + ## Converts `x` into its octal representation. + ## + ## The resulting string is always `len` characters long. No leading ``0o`` + ## prefix is generated. var mask: BiggestInt = 7 shift: BiggestInt = 0 @@ -866,8 +931,10 @@ proc toOct*(x: BiggestInt, len: int): string {.noSideEffect, proc toBin*(x: BiggestInt, len: int): string {.noSideEffect, rtl, extern: "nsuToBin".} = - ## converts `x` into its binary representation. The resulting string is - ## always `len` characters long. No leading ``0b`` prefix is generated. + ## Converts `x` into its binary representation. + ## + ## The resulting string is always `len` characters long. No leading ``0b`` + ## prefix is generated. var mask: BiggestInt = 1 shift: BiggestInt = 0 @@ -880,7 +947,8 @@ proc toBin*(x: BiggestInt, len: int): string {.noSideEffect, proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect, rtl, extern: "nsuInsertSep".} = - ## inserts the separator `sep` after `digits` digits from right to left. + ## Inserts the separator `sep` after `digits` digits from right to left. + ## ## Even though the algorithm works with any string `s`, it is only useful ## if `s` contains a number. ## Example: ``insertSep("1000000") == "1_000_000"`` @@ -899,7 +967,9 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect, proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, rtl, extern: "nsuEscape".} = - ## Escapes a string `s`. This does these operations (at the same time): + ## Escapes a string `s`. + ## + ## This does these operations (at the same time): ## * replaces any ``\`` by ``\\`` ## * replaces any ``'`` by ``\'`` ## * replaces any ``"`` by ``\"`` @@ -923,11 +993,13 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, rtl, extern: "nsuUnescape".} = - ## Unescapes a string `s`. This complements ``escape`` as it performs the - ## opposite operations. + ## Unescapes a string `s`. + ## + ## This complements `escape <#escape>`_ as it performs the opposite + ## operations. ## - ## If `s` does not begin with ``prefix`` and end with ``suffix`` a EInvalidValue - ## exception will be raised. + ## If `s` does not begin with ``prefix`` and end with ``suffix`` a + ## EInvalidValue exception will be raised. result = newStringOfCap(s.len) var i = 0 if s[0 .. prefix.len-1] != prefix: @@ -961,9 +1033,10 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, proc validIdentifier*(s: string): bool {.noSideEffect, rtl, extern: "nsuValidIdentifier".} = - ## returns true if `s` is a valid identifier. A valid identifier starts - ## with a character of the set `IdentStartChars` and is followed by any - ## number of characters of the set `IdentChars`. + ## Returns true if `s` is a valid identifier. + ## + ## A valid identifier starts with a character of the set `IdentStartChars` + ## and is followed by any number of characters of the set `IdentChars`. if s[0] in IdentStartChars: for i in 1..s.len-1: if s[i] notin IdentChars: return false @@ -971,9 +1044,10 @@ proc validIdentifier*(s: string): bool {.noSideEffect, proc editDistance*(a, b: string): int {.noSideEffect, rtl, extern: "nsuEditDistance".} = - ## returns the edit distance between `a` and `b`. This uses the - ## `Levenshtein`:idx: distance algorithm with only a linear memory overhead. - ## This implementation is highly optimized! + ## Returns the edit distance between `a` and `b`. + ## + ## This uses the `Levenshtein`:idx: distance algorithm with only a linear + ## memory overhead. This implementation is highly optimized! var len1 = a.len var len2 = b.len if len1 > len2: @@ -1072,7 +1146,7 @@ type proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, precision: range[0..32] = 16): string {. noSideEffect, operator: 2, rtl, extern: "nsu$1".} = - ## converts a floating point value `f` to a string. + ## Converts a floating point value `f` to a string. ## ## If ``format == ffDecimal`` then precision is the number of digits to ## be printed after the decimal point. @@ -1103,7 +1177,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, proc formatFloat*(f: float, format: TFloatFormat = ffDefault, precision: range[0..32] = 16): string {. noSideEffect, operator: 2, rtl, extern: "nsu$1".} = - ## converts a floating point value `f` to a string. + ## Converts a floating point value `f` to a string. ## ## If ``format == ffDecimal`` then precision is the number of digits to ## be printed after the decimal point. @@ -1198,6 +1272,8 @@ proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {. proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, rtl, extern: "nsuFormatOpenArray".} = + ## Interpolates a format string with the values from `a`. + ## ## The `substitution`:idx: operator performs string substitutions in ## `formatstr` and returns a modified `formatstr`. This is often called ## `string interpolation`:idx:. diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index ee1226a35..7ec823033 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -7,17 +7,24 @@ # distribution, for details about the copyright. # -## **Note**: This module will be deprecated in the future and merged into a -## new ``url`` module. +## This module implements URI parsing as specified by RFC 3986. -import strutils +import strutils, parseutils type TUrl* = distinct string -proc `$`*(url: TUrl): string = return string(url) + TUri* = object + scheme*, username*, password*: string + hostname*, port*, path*, query*, anchor*: string -proc `/`*(a, b: TUrl): TUrl = +proc `$`*(url: TUrl): string {.deprecated.} = + ## **Deprecated since 0.9.6**: Use ``TUri`` instead. + return string(url) + +proc `/`*(a, b: TUrl): TUrl {.deprecated.} = ## Joins two URLs together, separating them with / if needed. + ## + ## **Deprecated since 0.9.6**: Use ``TUri`` instead. var urlS = $a var bS = $b if urlS == "": return b @@ -29,9 +36,338 @@ proc `/`*(a, b: TUrl): TUrl = urlS.add(bs) result = TUrl(urlS) -proc add*(url: var TUrl, a: TUrl) = +proc add*(url: var TUrl, a: TUrl) {.deprecated.} = ## Appends url to url. + ## + ## **Deprecated since 0.9.6**: Use ``TUri`` instead. url = url / a +proc parseAuthority(authority: string, result: var TUri) = + var i = 0 + var inPort = false + while true: + case authority[i] + of '@': + result.password = result.port + result.port = "" + result.username = result.hostname + result.hostname = "" + inPort = false + of ':': + inPort = true + of '\0': break + else: + if inPort: + result.port.add(authority[i]) + else: + result.hostname.add(authority[i]) + i.inc + +proc parsePath(uri: string, i: var int, result: var TUri) = + + i.inc parseUntil(uri, result.path, {'?', '#'}, i) + + # The 'mailto' scheme's PATH actually contains the hostname/username + if result.scheme.ToLower() == "mailto": + parseAuthority(result.path, result) + result.path = "" + + if uri[i] == '?': + i.inc # Skip '?' + i.inc parseUntil(uri, result.query, {'#'}, i) + + if uri[i] == '#': + i.inc # Skip '#' + i.inc parseUntil(uri, result.anchor, {}, i) + +proc initUri(): TUri = + result = TUri(scheme: "", username: "", password: "", hostname: "", port: "", + path: "", query: "", anchor: "") + +proc parseUri*(uri: string): TUri = + ## Parses a URI. + result = initUri() + + var i = 0 + + # Check if this is a reference URI (relative URI) + if uri[i] == '/': + parsePath(uri, i, result) + return + + # Scheme + i.inc parseWhile(uri, result.scheme, Letters + Digits + {'+', '-', '.'}, i) + if uri[i] != ':': + # Assume this is a reference URI (relative URI) + i = 0 + result.scheme = "" + parsePath(uri, i, result) + return + i.inc # Skip ':' + + # Authority + if uri[i] == '/' and uri[i+1] == '/': + i.inc(2) # Skip // + var authority = "" + i.inc parseUntil(uri, authority, {'/', '?', '#'}, i) + if authority == "": + raise newException(EInvalidValue, "Expected authority got nothing.") + parseAuthority(authority, result) + + # Path + parsePath(uri, i, result) + +proc removeDotSegments(path: string): string = + var collection: seq[string] = @[] + let endsWithSlash = path[path.len-1] == '/' + var i = 0 + var currentSegment = "" + while true: + case path[i] + of '/': + collection.add(currentSegment) + currentSegment = "" + of '.': + if path[i+1] == '.' and path[i+2] == '/': + if collection.len > 0: + discard collection.pop() + i.inc 3 + continue + elif path[i+1] == '/': + i.inc 2 + continue + currentSegment.add path[i] + of '\0': + if currentSegment != "": + collection.add currentSegment + break + else: + currentSegment.add path[i] + i.inc + + result = collection.join("/") + if endsWithSlash: result.add '/' + +proc merge(base, reference: TUri): string = + # http://tools.ietf.org/html/rfc3986#section-5.2.3 + if base.hostname != "" and base.path == "": + '/' & reference.path + else: + let lastSegment = rfind(base.path, "/") + if lastSegment == -1: + reference.path + else: + base.path[0 .. lastSegment] & reference.path + +proc combine*(base: TUri, reference: TUri): TUri = + ## Combines a base URI with a reference URI. + ## + ## This uses the algorithm specified in + ## `section 5.2.2 of RFC 3986 <http://tools.ietf.org/html/rfc3986#section-5.2.2>`_. + ## + ## This means that the slashes inside the base URI's path as well as reference + ## URI's path affect the resulting URI. + ## + ## For building URIs you may wish to use \`/\` instead. + ## + ## Examples: + ## + ## .. code-block:: nimrod + ## let foo = combine(parseUri("http://example.com/foo/bar"), parseUri("/baz")) + ## assert foo.path == "/baz" + ## + ## let bar = combine(parseUri("http://example.com/foo/bar"), parseUri("baz")) + ## assert foo.path == "/foo/baz" + ## + ## let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz")) + ## assert foo.path == "/foo/bar/baz" + + template setAuthority(dest, src: expr): stmt = + dest.hostname = src.hostname + dest.username = src.username + dest.port = src.port + dest.password = src.password + + result = initUri() + if reference.scheme != base.scheme and reference.scheme != "": + result = reference + result.path = removeDotSegments(result.path) + else: + if reference.hostname != "": + setAuthority(result, reference) + result.path = removeDotSegments(reference.path) + result.query = reference.query + else: + if reference.path == "": + result.path = base.path + if reference.query != "": + result.query = reference.query + else: + result.query = base.query + else: + if reference.path.startsWith("/"): + result.path = removeDotSegments(reference.path) + else: + result.path = removeDotSegments(merge(base, reference)) + result.query = reference.query + setAuthority(result, base) + result.scheme = base.scheme + result.anchor = reference.anchor + +proc combine*(uris: varargs[TUri]): TUri = + ## Combines multiple URIs together. + result = uris[0] + for i in 1 .. <uris.len: + result = combine(result, uris[i]) + +proc `/`*(x: TUri, path: string): TUri = + ## Concatenates the path specified to the specified URI's path. + ## + ## Contrary to the ``combine`` procedure you do not have to worry about + ## the slashes at the beginning and end of the path and URI's path + ## respectively. + ## + ## Examples: + ## + ## .. code-block:: nimrod + ## let foo = parseUri("http://example.com/foo/bar") / parseUri("/baz") + ## assert foo.path == "/foo/bar/baz" + ## + ## let bar = parseUri("http://example.com/foo/bar") / parseUri("baz") + ## assert foo.path == "/foo/bar/baz" + ## + ## let bar = parseUri("http://example.com/foo/bar/") / parseUri("baz") + ## assert foo.path == "/foo/bar/baz" + result = x + if result.path[result.path.len-1] == '/': + if path[0] == '/': + result.path.add(path[1 .. path.len-1]) + else: + result.path.add(path) + else: + if path[0] != '/': + result.path.add '/' + result.path.add(path) + +proc `$`*(u: TUri): string = + ## Returns the string representation of the specified URI object. + result = "" + if u.scheme.len > 0: + result.add(u.scheme) + result.add("://") + if u.username.len > 0: + result.add(u.username) + if u.password.len > 0: + result.add(":") + result.add(u.password) + result.add("@") + result.add(u.hostname) + if u.port.len > 0: + result.add(":") + result.add(u.port) + if u.path.len > 0: + if u.path[0] != '/': result.add("/") + result.add(u.path) + result.add(u.query) + result.add(u.anchor) + when isMainModule: - assert($("http://".TUrl / "localhost:5000".TUrl) == "http://localhost:5000") + block: + let test = parseUri("http://localhost:8080/test") + doAssert test.scheme == "http" + doAssert test.port == "8080" + doAssert test.path == "/test" + doAssert test.hostname == "localhost" + + block: + let test = parseUri("foo://username:password@example.com:8042/over/there" & + "/index.dtb?type=animal&name=narwhal#nose") + doAssert test.scheme == "foo" + doAssert test.username == "username" + doAssert test.password == "password" + doAssert test.hostname == "example.com" + doAssert test.port == "8042" + doAssert test.path == "/over/there/index.dtb" + doAssert test.query == "type=animal&name=narwhal" + doAssert test.anchor == "nose" + + block: + let test = parseUri("urn:example:animal:ferret:nose") + doAssert test.scheme == "urn" + doAssert test.path == "example:animal:ferret:nose" + + block: + let test = parseUri("mailto:username@example.com?subject=Topic") + doAssert test.scheme == "mailto" + doAssert test.username == "username" + doAssert test.hostname == "example.com" + doAssert test.query == "subject=Topic" + + block: + let test = parseUri("magnet:?xt=urn:sha1:72hsga62ba515sbd62&dn=foobar") + doAssert test.scheme == "magnet" + doAssert test.query == "xt=urn:sha1:72hsga62ba515sbd62&dn=foobar" + + block: + let test = parseUri("/test/foo/bar?q=2#asdf") + doAssert test.scheme == "" + doAssert test.path == "/test/foo/bar" + doAssert test.query == "q=2" + doAssert test.anchor == "asdf" + + block: + let test = parseUri("test/no/slash") + doAssert test.path == "test/no/slash" + + # Remove dot segments tests + block: + doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz" + + # Combine tests + block: + let concat = combine(parseUri("http://google.com/foo/bar/"), parseUri("baz")) + doAssert concat.path == "/foo/bar/baz" + doAssert concat.hostname == "google.com" + doAssert concat.scheme == "http" + + block: + let concat = combine(parseUri("http://google.com/foo"), parseUri("/baz")) + doAssert concat.path == "/baz" + doAssert concat.hostname == "google.com" + doAssert concat.scheme == "http" + + block: + let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar")) + doAssert concat.path == "/foo/bar" + + block: + let concat = combine(parseUri("http://google.com/foo/test"), parseUri("/bar")) + doAssert concat.path == "/bar" + + block: + let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar")) + doAssert concat.path == "/foo/bar" + + block: + let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar")) + doAssert concat.path == "/foo/test/bar" + + block: + let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/")) + doAssert concat.path == "/foo/test/bar/" + + block: + let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"), + parseUri("baz")) + doAssert concat.path == "/foo/test/bar/baz" + + # `/` tests + block: + let test = parseUri("http://example.com/foo") / "bar/asd" + doAssert test.path == "/foo/bar/asd" + + block: + let test = parseUri("http://example.com/foo/") / "/bar/asd" + doAssert test.path == "/foo/bar/asd" + + diff --git a/lib/system.nim b/lib/system.nim index 0a16efbb5..753205777 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -783,7 +783,7 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = result = s.a <= value and value <= s.b template `in` * (x, y: expr): expr {.immediate.} = contains(y, x) - ## Suger for contains + ## Sugar for contains ## ## .. code-block:: Nimrod ## assert(1 in (1..3) == true) @@ -1052,7 +1052,7 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = ## containers should also call their adding proc `add` for consistency. ## Generic code becomes much easier to write if the Nimrod naming scheme is ## respected. - var xl = x.len + let xl = x.len setLen(x, xl + y.len) for i in 0..high(y): x[xl+i] = y[i] @@ -1066,20 +1066,20 @@ proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".} proc del*[T](x: var seq[T], i: int) {.noSideEffect.} = ## deletes the item at index `i` by putting ``x[high(x)]`` into position `i`. ## This is an O(1) operation. - var xl = x.len + let xl = x.len shallowCopy(x[i], x[xl-1]) setLen(x, xl-1) proc delete*[T](x: var seq[T], i: int) {.noSideEffect.} = ## deletes the item at index `i` by moving ``x[i+1..]`` by one position. ## This is an O(n) operation. - var xl = x.len + let xl = x.len for j in i..xl-2: shallowCopy(x[j], x[j+1]) setLen(x, xl-1) proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} = ## inserts `item` into `x` at position `i`. - var xl = x.len + let xl = x.len setLen(x, xl+1) var j = xl-1 while j >= i: @@ -2026,19 +2026,25 @@ elif hostOS != "standalone": {.pop.} proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [FWriteIO], gcsafe.} - ## special built-in that takes a variable number of arguments. Each argument + ## Writes and flushes the parameters to the standard output. + ## + ## Special built-in that takes a variable number of arguments. Each argument ## is converted to a string via ``$``, so it works for user-defined ## types that have an overloaded ``$`` operator. ## It is roughly equivalent to ``writeln(stdout, x); flush(stdout)``, but ## available for the JavaScript target too. + ## ## Unlike other IO operations this is guaranteed to be thread-safe as - ## ``echo`` is very often used for debugging convenience. + ## ``echo`` is very often used for debugging convenience. If you want to use + ## ``echo`` inside a `proc without side effects + ## <manual.html#nosideeffect-pragma>`_ you can use `debugEcho <#debugEcho>`_ + ## instead. proc debugEcho*[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect, tags: [], raises: [].} - ## Same as ``echo``, but as a special semantic rule, ``debugEcho`` pretends - ## to be free of side effects, so that it can be used for debugging routines - ## marked as ``noSideEffect``. + ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho`` + ## pretends to be free of side effects, so that it can be used for debugging + ## routines marked as `noSideEffect <manual.html#nosideeffect-pragma>`_. template newException*(exceptn: typedesc, message: string): expr = ## creates an exception object of type ``exceptn`` and sets its ``msg`` field diff --git a/tests/stdlib/testequivalence.nim b/tests/stdlib/testequivalence.nim index 7c5d9e3e9..7acaad340 100644 --- a/tests/stdlib/testequivalence.nim +++ b/tests/stdlib/testequivalence.nim @@ -1,7 +1,6 @@ discard """ output: '''''' """ -import unittest import sets doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "equivalent or subset") diff --git a/web/index.txt b/web/index.txt index c3459d56b..947ebb706 100644 --- a/web/index.txt +++ b/web/index.txt @@ -101,5 +101,5 @@ Roadmap to 1.0 ============== Please have a look at -this `wiki page <https://github.com/Araq/Nimrod/wiki/Feature-Matrix>`_ for +this `wiki page <https://github.com/Araq/Nimrod/wiki/Roadmap>`_ for an up-to-date overview. diff --git a/web/news.txt b/web/news.txt index a913c94ad..62a923dcd 100644 --- a/web/news.txt +++ b/web/news.txt @@ -18,6 +18,8 @@ News - ``pas2nim`` moved into its own repository and is now a Babel package. - ``system.$`` for floating point types now produces a human friendly string representation. + - ``uri.TUrl`` as well as the ``parseurl`` module are now deprecated in favour + of the new ``TUri`` type in the ``uri`` module. Library Additions ----------------- @@ -26,7 +28,7 @@ News - Added module ``threadpool``. - ``sequtils.distnct`` has been renamed to ``sequtils.deduplicate``. - Added ``algorithm.reversed`` - + - Added ``uri.combine`` and ``uri.parseUri``. 2014-04-21 Version 0.9.4 released ================================= diff --git a/web/nimrod.ini b/web/nimrod.ini index 7b0a91c19..544446b11 100644 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -37,7 +37,7 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" [Documentation] doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters" -doc: "tools;c2nim;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" +doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" pdf: "manual;lib;tut1;tut2;nimrodc;niminst;gc" srcdoc2: "system.nim;impure/graphics;wrappers/sdl" srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" |