0 people like it.
Like the snippet!
Pushkin tree v 2.0
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
|
open System
open System.Text.RegularExpressions
open System.Net
open System.IO
open System.Text
open System.Runtime.Serialization
///Measures time spent in an eagerly executed function.
///Not gonna work with a lazy function, e.g. function returning a sequence (IEnumerable).
let time jobName job =
let startTime = DateTime.Now;
let returnValue = job()
let endTime = DateTime.Now;
printfn "%s took %d ms" jobName (int((endTime - startTime).TotalMilliseconds))
returnValue
let limitStringLength (string : string) maxLength =
if(string.Length > maxLength) then
string.Substring(0, maxLength-3) + "..."
else
string
///Default single match regex: "." matches any character, except "\n".
let regexSingleMatch text pattern =
Regex.Match(text, pattern).Groups.Item(1).Value
///Treats input as single line, so "." pattern mathces any character including "\n".
let regexSingleMatchSingleLine text pattern =
Regex.Match(text, pattern, RegexOptions.Singleline).Groups.Item(1).Value
let regexMatches text pattern =
seq { for m in Regex.Matches(text, pattern) -> m.Groups.Item(1).Value } |> Seq.toList
let regexReplace text pattern (replacement:string) =
Regex.Replace(text, pattern, replacement)
///Removes all occurrences of the given string from the given text
let regexRemove text pattern =
Regex.Replace(text, pattern, "")
///Merges 2 lists, calling merge function for the elements with equal keys.
///Function assumes that all keys in the second list are unique.
///Function assumes both lists are ordered ascending.
//NOTE: we specify return type for keyExtractor to prevent generic comparison to fire for keys
let rec orderedListsMerge xs ys (keyExtractor : 'a->int) merger =
match xs, ys with
| [],_ | _,[] -> []
| x::xs', y::ys' ->
let xkey = keyExtractor x
let ykey = keyExtractor y
if(xkey = ykey) then
//here we move xs forward, but keep ys the same,
//because we assume that next y have a different key while next x might still have the same key,
//without that assumption the results are incorrect
(merger x y) :: orderedListsMerge xs' ys keyExtractor merger
elif(xkey > ykey) then
orderedListsMerge xs ys' keyExtractor merger
else
orderedListsMerge xs' ys keyExtractor merger
///Requests HTML for the given URL using Windows-1251 encoding.
let webRequestHtmlWin1251 (url : string) =
let req = WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
//don't forget the Encoding, when you work with international documents
let reader = new StreamReader(stream, Encoding.GetEncoding("Windows-1251"))
let html = reader.ReadToEnd()
resp.Close()
html
///Removes html markup from the given text
let cleanupHtml text =
let htmlTagPattern = "<.+?>"
regexReplace text htmlTagPattern String.Empty
///Takes first line from the given text
let takeFirstLine text =
let firstLinePattern = "(.*)"
regexSingleMatch text firstLinePattern
///Extract HREFS only from the named links
let extractNamedHrefs html =
//I tried XmlDocument here, but it doesn't work
//as HTML can contain some "invalid" elements like
//
//Stand back now, I'm going to use regular expressions!
let hrefPattern = "<a name=.* href=\"(.+?)\">.*</a>"
regexMatches html hrefPattern
type Poem(poemHref : string, title : string, lines : seq<string>) =
let parsedLines = [ for line in lines -> line.Replace(" " , "") ]
let lineTokens = [ for line in lines -> regexMatches (line.ToLower()) "([а-я]+)" ]
let parsedTitle =
match title with
//Take first line as the title for untitled poems
| "* * *" -> (if (lines |> Seq.isEmpty) then "" else (lines |> Seq.nth 0))
| _ -> title
member this.Href = poemHref
member this.Lines = parsedLines
///Line tokens are Russian words comprising the line.
member this.LineTokens = lineTokens
member this.Title = parsedTitle
member this.SerializationInfo = (poemHref, title, lines)
//TODO: optimize to use sorted output for grouping
/// Transforms seq<key*data> to seq<key*seq<data>> ordered by key.
let extractKeySortAndGroupBy sequence =
sequence
|> Seq.groupBy fst
|> Seq.sortBy fst
|> Seq.map (fun (key, elements) -> (key, elements |> Seq.map (fun (key, data) -> data)))
///Builds inversed index of tokens in poems.
///Index structure is (token -> poem number -> (line number,position in line)).
let indexPoems (poems : list<Poem>) =
poems
|> List.mapi
(
fun poemNumber poem ->
poem.LineTokens
|> List.mapi
(
fun lineNumber tokens ->
tokens
|> List.mapi
(
fun position token ->
//nested tokens to simplify grouping later
(token, (poemNumber, (lineNumber, position)))
)
)
|> List.collect id
)
|> List.collect id
//now we have raw list of tuples, we will turn it into ordered inversed index
|> extractKeySortAndGroupBy
|> Seq.map
(
fun (token, tuples) ->
let poems =
tuples
|> extractKeySortAndGroupBy
|> Seq.map
(
fun (poemNumber, tuples) ->
let linesPositions =
tuples
|> Seq.sortBy ( fun (lineNumber,position) -> position)
|> Seq.sortBy ( fun (lineNumber,position) -> lineNumber) //sortBy is stable according to MSDN
|> Seq.toList
(poemNumber, linesPositions)
)
|> Seq.toList
(token, poems)
)
|> Seq.toList
///Token index is a subtree of the given index including only poems and lines with the given token in the given position.
let tokenIndex fullIndex filterToken filterPosition =
let (token, poems) =
fullIndex
|> List.find (fun(token, poems) -> token=filterToken)
poems
|> List.map
(
fun (poemNumber, linesPositions) ->
let filteredLines = linesPositions |> List.filter (fun (lineNumber, position) -> position = filterPosition)
(poemNumber, filteredLines)
)
|> List.filter (fun (poemNumber, linesPositions) -> not (Seq.isEmpty linesPositions))
///Intersect current index with token index.
///We will only keep tokens that occur in the poems and lines of the token index.
let intersectIndex currentIndex tokenIndex =
//function to merge lists of (lineNumber,position) from current index and token index
let mergeLinesPositions currentLinesPositions tokenLinesPositions =
let keyExtractor = fst
let merger = (fun (currentLineNumber, currentPosition) (_,_) -> (currentLineNumber, currentPosition))
orderedListsMerge currentLinesPositions tokenLinesPositions keyExtractor merger
//function to merge lists of (poemNumber, list(lineNumber,position)) from current index and token index
let mergePoems currentPoems tokenPoems =
let keyExtractor = fst
let merger = (fun (currentPoemNumber, currentLinesPositions) (_, tokenLinesPositions) -> (currentPoemNumber, mergeLinesPositions currentLinesPositions tokenLinesPositions))
orderedListsMerge currentPoems tokenPoems keyExtractor merger
|> List.filter (fun (poemNumber, linesPositions) -> not (List.isEmpty linesPositions))
currentIndex
|> List.map (fun (token, poems) -> (token, mergePoems poems tokenIndex))
|> List.filter (fun (token, poems) -> not (List.isEmpty poems))
///The function will return at most "count" terms that appear in the "findPosition" in the given index.
let queryIndex index findPosition count =
index
|> List.map
(
fun (token, poems) ->
let tokenFreq =
poems
|> List.sumBy
(
fun (_, linesPositions) ->
linesPositions
|> List.sumBy
(
fun (lineNumber, position) ->
if (position = findPosition) then 1 else 0
)
)
(token, tokenFreq)
)
|> Seq.filter (fun (token, tokenFreq) -> tokenFreq > 0)
|> Seq.sortBy (fun (token, tokenFreq) -> -tokenFreq)
// Seq.take fails if there is less than "count" elements
|> Seq.zip [1..count]
|> Seq.map (fun (index, element) -> element)
|> Seq.toList
///Acquire first poem for the given token and line position
let resolveSinglePoem index findToken findPosition =
let (token, poems) =
index
|> List.find (fun (token, poems) -> token = findToken)
poems
|> List.collect
(
fun (poemNumber, linesPositions) ->
linesPositions
|> List.filter (fun (lineNumber, position) -> position = findPosition)
|> List.map (fun (lineNumber, position) -> (poemNumber, lineNumber))
)
|> Seq.nth 0
type QueryResult =
//token, count
| LineVariant of string*int
//poemNumber, lineNumber
| SinglePoem of int*int
//TODO: identical strings currently will not be resolved to their poems
///Wraps results returned by queryIndex into QueryResult type
let wrappedQueryIndex filteredIndex searchPosition count =
queryIndex filteredIndex searchPosition count
|> List.map
(
fun (token, count) ->
match count with
| 1 -> SinglePoem(resolveSinglePoem filteredIndex token searchPosition)
| _ -> LineVariant(token,count)
)
type ExtendedResult =
| ExtendedLineVariant of string*int
| ExtendedSinglePoem of string*string*int*string
///Extends QueryResult list with information from poems list
let extendQueryResults queryResults poems =
queryResults
|> List.map
(
fun result ->
match result with
| LineVariant (token, count) -> ExtendedLineVariant(token,count)
| SinglePoem (poemNumber, lineNumber) ->
let (poem : Poem) =
poems
|> Seq.nth poemNumber
let line =
poem.Lines
|> Seq.nth lineNumber
ExtendedSinglePoem(poem.Title, poem.Href, lineNumber, line)
)
//TODO: add more structural analysis -> handle sub-titles, personas
let hrefAndHtmlToPoem poemHref poemHtml =
let titlePattern = "<h1>(.+?)</h1>"
//titles can be multiline, sometimes they include sub-titles, we take only the first line
let title = (regexSingleMatchSingleLine poemHtml titlePattern) |> cleanupHtml |> takeFirstLine
let linePattern = "<span class=\"line.*>(.+?)</span>"
let lines = regexMatches poemHtml linePattern |> Seq.map cleanupHtml
new Poem(poemHref,title,lines)
///Check that the given link is a link to a final edition poem
let isFinalEditionHref (href : string) =
not (href.Contains("03edit") || href.Contains("02misc"))
let crawlPoemsFromWeb =
let domainUrl = "http://www.rvb.ru/pushkin/"
let volumeUrlTemplate = domainUrl + "tocvol{0}.htm"
let poemUrlTemplate = domainUrl + "{0}"
//take only first 4 volumes -- they contain poems
seq { for volumeNumber in 1..4 -> String.Format(volumeUrlTemplate, volumeNumber) }
|> Seq.map webRequestHtmlWin1251
//Poems are always referenced through named links on rvb.ru
|> Seq.collect extractNamedHrefs
//We only take final editions of poems to avoid massive duplication of lines
|> Seq.filter isFinalEditionHref
|> Seq.map (fun href -> String.Format(poemUrlTemplate, href))
// //uncomment for development mode -- total number of Poems is ~800
// |> Seq.take 40
//Request and wrap individual poems
|> Seq.map (fun href -> (hrefAndHtmlToPoem href (webRequestHtmlWin1251 href)))
//Empty poem is not a poem!
//It means we crawled some prose accidentally, it might happen
|> Seq.filter (fun poem -> not (poem.Lines |> Seq.isEmpty))
//cache results so we don't crawl poems twice
|> Seq.cache
let savePoemsToCache cacheFilePath poemsList =
let stream = new FileStream(cacheFilePath, FileMode.Create)
//Serialization of the whole poem object is redundant ans
//it also throws StackOverflow exception, because lists are serialized as nested <tail></tail> elements!
let serializer = new DataContractSerializer(typeof<(string*string*seq<string>) list>)
serializer.WriteObject(stream, (poemsList |> List.map (fun (poem : Poem) -> poem.SerializationInfo)))
stream.Flush()
stream.Close()
let loadPoemsFromCache cacheFilePath =
let serializer = new DataContractSerializer(typeof<(string*string*seq<string>) list>)
let stream = new FileStream(cacheFilePath, FileMode.Open)
let poemsList = serializer.ReadObject(stream) :?> list<string*string*seq<string>>
stream.Close()
poemsList |> List.map (fun poemInfo -> new Poem(poemInfo))
let crawlPoemsOrLoadFromCache =
let cacheFilePath = "poems.cache"
if File.Exists(cacheFilePath) then
printfn "Loading poems from cache"
loadPoemsFromCache cacheFilePath
else
printfn "Loading poems from web"
let poems = crawlPoemsFromWeb |> Seq.toList
savePoemsToCache cacheFilePath poems
poems
type PushkinTreeNode =
| VariantNode of string*int*seq<PushkinTreeNode>
| PoemNode of string*string*int*string
let createPushkinTree pushkinPoems poemsIndex count =
let rec createTreeLevel count currentQuery currentIndex =
let searchPosition = List.length currentQuery
let queryResult = wrappedQueryIndex currentIndex searchPosition count
let prettyResult = extendQueryResults queryResult pushkinPoems
prettyResult
|> List.map
(
fun result ->
match result with
| ExtendedSinglePoem (title, href, lineNumber, line) -> PoemNode(title, href, lineNumber, line)
| ExtendedLineVariant (token, freq) -> VariantNode(token, freq, createTreeLevel count (currentQuery @ [token]) (intersectIndex currentIndex (tokenIndex currentIndex token searchPosition)))
)
createTreeLevel count [] poemsIndex
let rec pushkinTreeToNumberOfQueries pushkinTree =
let subTreeResults =
pushkinTree
|> Seq.sumBy
(
fun pushkinTreeNode ->
match pushkinTreeNode with
| VariantNode (_, _, subTree) -> pushkinTreeToNumberOfQueries subTree
| PoemNode (_, _, _, _) -> 0
)
subTreeResults+1
let resultsToHtml pushkinTree =
let rec treeToHtml tree currentPath (currentNumber:int) startingNumber =
let zippedTreeLevel =
tree
|> Seq.zip (Seq.initInfinite (fun i -> startingNumber+i))
let pathToString path =
let parts =
path
|> Seq.map (fun x -> "'"+x+"'")
String.Join(",", parts)
let thisLevelStart = String.Format("<div class=\"x\"><table id=\"{0}\" class=\"p\">", currentNumber) + Environment.NewLine
let thisLevelTable =
zippedTreeLevel
|> Seq.fold
(
fun acc treeNode ->
match treeNode with
| (number, PoemNode (title, href, lineNumber, line)) ->
acc + String.Format("<tr><td><span class=line>{0}</span> ⇒ <a target=blank class=fromlink href=\"{1}\">{2}</a>, ?????? {3}</tr>",line, href, limitStringLength title 30, lineNumber+1) + Environment.NewLine
| (number, VariantNode (token, freq, subtree)) ->
acc + String.Format("<tr id=\"r{0}\"><td>{1} ⇒ <span class=\"lv\" onClick=\"x([{2}])\">{3}</span></td></tr>", number, token, (pathToString (currentPath@[string(number)])), freq) + Environment.NewLine
) ""
let thisLevelEnd = @"</table></div>" + Environment.NewLine + Environment.NewLine
let thisLevelOutput = (thisLevelStart+thisLevelTable+thisLevelEnd)
let levelLength =
tree
|> Seq.length
let (subTreeCount, subTreeOutput) =
zippedTreeLevel
|> Seq.fold
(
fun (acc, result) treeNode ->
match treeNode with
| (number, PoemNode (title, href, lineNumber, line)) ->
(acc, result)
| (number, VariantNode (token, freq, subtree)) ->
let (subTreeCount, subTreeOutput) = treeToHtml subtree (currentPath@[string(number)]) number (startingNumber+acc+levelLength)
(acc + subTreeCount, result + subTreeOutput)
) (0, "")
(levelLength + subTreeCount, thisLevelOutput + subTreeOutput)
let (_, content) = treeToHtml pushkinTree ["0"] 0 1
content
let outputResultsToFile (content:string) =
let templateFile = "template.htm"
let outputFile = "output.htm"
let templateReplacePattern = "#HERE_GOES_CONTENT#"
let templateHtml = File.ReadAllText(templateFile)
let resultHtml = regexReplace templateHtml templateReplacePattern content
File.WriteAllText(outputFile, resultHtml)
let poems = time "Crawling poems" (fun() -> crawlPoemsOrLoadFromCache)
printfn "Crawled %d poems" (poems |> Seq.length)
printfn "Crawled %d lines" (poems |> Seq.sumBy ( fun poem -> poem.Lines |> Seq.length))
let poemIndex = time "Indexing poems" (fun () -> poems |> indexPoems)
printfn "Index contains %d terms" poemIndex.Length
let tree = time "Generating result tree" (fun () -> createPushkinTree poems poemIndex 20)
printfn "Number of queries made to create tree: %d" (pushkinTreeToNumberOfQueries tree)
let htmlContent = time "Generating html content" (fun () -> resultsToHtml tree)
time "Output content" (fun() -> outputResultsToFile htmlContent)
|
namespace System
namespace System.Text
namespace System.Text.RegularExpressions
namespace System.Net
namespace System.IO
namespace System.Runtime
namespace System.Runtime.Serialization
val time : jobName:string -> job:(unit -> 'a) -> 'a
Full name: Script.time
Measures time spent in an eagerly executed function.
Not gonna work with a lazy function, e.g. function returning a sequence (IEnumerable).
val jobName : string
val job : (unit -> 'a)
val startTime : DateTime
Multiple items
type DateTime =
struct
new : ticks:int64 -> DateTime + 10 overloads
member Add : value:TimeSpan -> DateTime
member AddDays : value:float -> DateTime
member AddHours : value:float -> DateTime
member AddMilliseconds : value:float -> DateTime
member AddMinutes : value:float -> DateTime
member AddMonths : months:int -> DateTime
member AddSeconds : value:float -> DateTime
member AddTicks : value:int64 -> DateTime
member AddYears : value:int -> DateTime
...
end
Full name: System.DateTime
--------------------
DateTime()
(+0 other overloads)
DateTime(ticks: int64) : unit
(+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
(+0 other overloads)
property DateTime.Now: DateTime
val returnValue : 'a
val endTime : DateTime
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val limitStringLength : string:string -> maxLength:int -> string
Full name: Script.limitStringLength
Multiple items
val string : string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
val maxLength : int
property String.Length: int
String.Substring(startIndex: int) : string
String.Substring(startIndex: int, length: int) : string
val regexSingleMatch : text:string -> pattern:string -> string
Full name: Script.regexSingleMatch
Default single match regex: "." matches any character, except "\n".
val text : string
val pattern : string
Multiple items
type Regex =
new : pattern:string -> Regex + 1 overload
member GetGroupNames : unit -> string[]
member GetGroupNumbers : unit -> int[]
member GroupNameFromNumber : i:int -> string
member GroupNumberFromName : name:string -> int
member IsMatch : input:string -> bool + 1 overload
member Match : input:string -> Match + 2 overloads
member Matches : input:string -> MatchCollection + 1 overload
member Options : RegexOptions
member Replace : input:string * replacement:string -> string + 5 overloads
...
Full name: System.Text.RegularExpressions.Regex
--------------------
Regex(pattern: string) : unit
Regex(pattern: string, options: RegexOptions) : unit
Regex.Match(input: string, pattern: string) : Match
Regex.Match(input: string, pattern: string, options: RegexOptions) : Match
val regexSingleMatchSingleLine : text:string -> pattern:string -> string
Full name: Script.regexSingleMatchSingleLine
Treats input as single line, so "." pattern mathces any character including "\n".
type RegexOptions =
| None = 0
| IgnoreCase = 1
| Multiline = 2
| ExplicitCapture = 4
| Compiled = 8
| Singleline = 16
| IgnorePatternWhitespace = 32
| RightToLeft = 64
| ECMAScript = 256
| CultureInvariant = 512
Full name: System.Text.RegularExpressions.RegexOptions
field RegexOptions.Singleline = 16
val regexMatches : text:string -> pattern:string -> string list
Full name: Script.regexMatches
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val m : Match
Regex.Matches(input: string, pattern: string) : MatchCollection
Regex.Matches(input: string, pattern: string, options: RegexOptions) : MatchCollection
property Match.Groups: GroupCollection
Multiple items
property GroupCollection.Item: int -> Group
--------------------
property GroupCollection.Item: string -> Group
module Seq
from Microsoft.FSharp.Collections
val toList : source:seq<'T> -> 'T list
Full name: Microsoft.FSharp.Collections.Seq.toList
val regexReplace : text:string -> pattern:string -> replacement:string -> string
Full name: Script.regexReplace
val replacement : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
Regex.Replace(input: string, pattern: string, evaluator: MatchEvaluator) : string
Regex.Replace(input: string, pattern: string, replacement: string) : string
Regex.Replace(input: string, pattern: string, evaluator: MatchEvaluator, options: RegexOptions) : string
Regex.Replace(input: string, pattern: string, replacement: string, options: RegexOptions) : string
val regexRemove : text:string -> pattern:string -> string
Full name: Script.regexRemove
Removes all occurrences of the given string from the given text
val orderedListsMerge : xs:'a list -> ys:'a list -> keyExtractor:('a -> int) -> merger:('a -> 'a -> 'a0) -> 'a0 list
Full name: Script.orderedListsMerge
Merges 2 lists, calling merge function for the elements with equal keys.
Function assumes that all keys in the second list are unique.
Function assumes both lists are ordered ascending.
val xs : 'a list
val ys : 'a list
val keyExtractor : ('a -> int)
val merger : ('a -> 'a -> 'a0)
val x : 'a
val xs' : 'a list
val y : 'a
val ys' : 'a list
val xkey : int
val ykey : int
val webRequestHtmlWin1251 : url:string -> string
Full name: Script.webRequestHtmlWin1251
Requests HTML for the given URL using Windows-1251 encoding.
val url : string
val req : WebRequest
type WebRequest =
inherit MarshalByRefObject
member Abort : unit -> unit
member AuthenticationLevel : AuthenticationLevel with get, set
member BeginGetRequestStream : callback:AsyncCallback * state:obj -> IAsyncResult
member BeginGetResponse : callback:AsyncCallback * state:obj -> IAsyncResult
member CachePolicy : RequestCachePolicy with get, set
member ConnectionGroupName : string with get, set
member ContentLength : int64 with get, set
member ContentType : string with get, set
member Credentials : ICredentials with get, set
member EndGetRequestStream : asyncResult:IAsyncResult -> Stream
...
Full name: System.Net.WebRequest
WebRequest.Create(requestUri: Uri) : WebRequest
WebRequest.Create(requestUriString: string) : WebRequest
val resp : WebResponse
WebRequest.GetResponse() : WebResponse
val stream : Stream
WebResponse.GetResponseStream() : Stream
val reader : StreamReader
Multiple items
type StreamReader =
inherit TextReader
new : stream:Stream -> StreamReader + 9 overloads
member BaseStream : Stream
member Close : unit -> unit
member CurrentEncoding : Encoding
member DiscardBufferedData : unit -> unit
member EndOfStream : bool
member Peek : unit -> int
member Read : unit -> int + 1 overload
member ReadLine : unit -> string
member ReadToEnd : unit -> string
...
Full name: System.IO.StreamReader
--------------------
StreamReader(stream: Stream) : unit
StreamReader(path: string) : unit
StreamReader(stream: Stream, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(stream: Stream, encoding: Encoding) : unit
StreamReader(path: string, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(path: string, encoding: Encoding) : unit
StreamReader(stream: Stream, encoding: Encoding, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(path: string, encoding: Encoding, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(stream: Stream, encoding: Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : unit
StreamReader(path: string, encoding: Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : unit
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
Encoding.GetEncoding(name: string) : Encoding
Encoding.GetEncoding(codepage: int) : Encoding
Encoding.GetEncoding(name: string, encoderFallback: EncoderFallback, decoderFallback: DecoderFallback) : Encoding
Encoding.GetEncoding(codepage: int, encoderFallback: EncoderFallback, decoderFallback: DecoderFallback) : Encoding
val html : string
StreamReader.ReadToEnd() : string
WebResponse.Close() : unit
val cleanupHtml : text:string -> string
Full name: Script.cleanupHtml
Removes html markup from the given text
val htmlTagPattern : string
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Encoding) : unit
field string.Empty
val takeFirstLine : text:string -> string
Full name: Script.takeFirstLine
Takes first line from the given text
val firstLinePattern : string
val extractNamedHrefs : html:string -> string list
Full name: Script.extractNamedHrefs
Extract HREFS only from the named links
val hrefPattern : string
Multiple items
type Poem =
new : poemHref:string * title:string * lines:seq<string> -> Poem
member Href : string
member LineTokens : string list list
member Lines : string list
member SerializationInfo : string * string * seq<string>
member Title : string
Full name: Script.Poem
--------------------
new : poemHref:string * title:string * lines:seq<string> -> Poem
val poemHref : string
val title : string
val lines : seq<string>
val parsedLines : string list
val line : string
String.Replace(oldValue: string, newValue: string) : string
String.Replace(oldChar: char, newChar: char) : string
val lineTokens : string list list
String.ToLower() : string
String.ToLower(culture: Globalization.CultureInfo) : string
val parsedTitle : string
val isEmpty : source:seq<'T> -> bool
Full name: Microsoft.FSharp.Collections.Seq.isEmpty
val nth : index:int -> source:seq<'T> -> 'T
Full name: Microsoft.FSharp.Collections.Seq.nth
val this : Poem
member Poem.Href : string
Full name: Script.Poem.Href
member Poem.Lines : string list
Full name: Script.Poem.Lines
member Poem.LineTokens : string list list
Full name: Script.Poem.LineTokens
Line tokens are Russian words comprising the line.
member Poem.Title : string
Full name: Script.Poem.Title
Multiple items
member Poem.SerializationInfo : string * string * seq<string>
Full name: Script.Poem.SerializationInfo
--------------------
type SerializationInfo =
new : type:Type * converter:IFormatterConverter -> SerializationInfo
member AddValue : name:string * value:obj -> unit + 15 overloads
member AssemblyName : string with get, set
member FullTypeName : string with get, set
member GetBoolean : name:string -> bool
member GetByte : name:string -> byte
member GetChar : name:string -> char
member GetDateTime : name:string -> DateTime
member GetDecimal : name:string -> decimal
member GetDouble : name:string -> float
...
Full name: System.Runtime.Serialization.SerializationInfo
--------------------
SerializationInfo(type: Type, converter: IFormatterConverter) : unit
val extractKeySortAndGroupBy : sequence:seq<'a * 'b> -> seq<'a * seq<'b>> (requires comparison)
Full name: Script.extractKeySortAndGroupBy
Transforms seq<key*data> to seq<key*seq<data>> ordered by key.
val sequence : seq<'a * 'b> (requires comparison)
val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> (requires equality)
Full name: Microsoft.FSharp.Collections.Seq.groupBy
val fst : tuple:('T1 * 'T2) -> 'T1
Full name: Microsoft.FSharp.Core.Operators.fst
val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Seq.sortBy
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val key : 'a (requires comparison)
val elements : seq<'a * 'b> (requires comparison)
val data : 'b
val indexPoems : poems:Poem list -> (string * (int * (int * int) list) list) list
Full name: Script.indexPoems
Builds inversed index of tokens in poems.
Index structure is (token -> poem number -> (line number,position in line)).
val poems : Poem list
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val mapi : mapping:(int -> 'T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.mapi
val poemNumber : int
val poem : Poem
property Poem.LineTokens: string list list
Line tokens are Russian words comprising the line.
val lineNumber : int
val tokens : string list
val position : int
val token : string
val collect : mapping:('T -> 'U list) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.collect
val id : x:'T -> 'T
Full name: Microsoft.FSharp.Core.Operators.id
val tuples : seq<int * (int * int)>
val poems : (int * (int * int) list) list
val tuples : seq<int * int>
val linesPositions : (int * int) list
val tokenIndex : fullIndex:('a * ('b * ('c * 'd) list) list) list -> filterToken:'a -> filterPosition:'d -> ('b * ('c * 'd) list) list (requires equality and equality)
Full name: Script.tokenIndex
Token index is a subtree of the given index including only poems and lines with the given token in the given position.
val fullIndex : ('a * ('b * ('c * 'd) list) list) list (requires equality and equality)
val filterToken : 'a (requires equality)
val filterPosition : 'd (requires equality)
val token : 'a (requires equality)
val poems : ('b * ('c * 'd) list) list (requires equality)
val find : predicate:('T -> bool) -> list:'T list -> 'T
Full name: Microsoft.FSharp.Collections.List.find
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
val poemNumber : 'b
val linesPositions : ('c * 'd) list (requires equality)
val filteredLines : ('c * 'd) list (requires equality)
val filter : predicate:('T -> bool) -> list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.filter
val lineNumber : 'c
val position : 'd (requires equality)
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
val intersectIndex : currentIndex:('a * (int * (int * 'b) list) list) list -> tokenIndex:(int * (int * 'b) list) list -> ('a * (int * (int * 'b) list) list) list
Full name: Script.intersectIndex
Intersect current index with token index.
We will only keep tokens that occur in the poems and lines of the token index.
val currentIndex : ('a * (int * (int * 'b) list) list) list
val tokenIndex : (int * (int * 'b) list) list
val mergeLinesPositions : ((int * 'c) list -> (int * 'c) list -> (int * 'c) list)
val currentLinesPositions : (int * 'c) list
val tokenLinesPositions : (int * 'c) list
val keyExtractor : ('d * 'e -> 'd)
val merger : ('d * 'e -> 'f * 'g -> 'd * 'e)
val currentLineNumber : 'd
val currentPosition : 'e
val mergePoems : ((int * (int * 'c) list) list -> (int * (int * 'c) list) list -> (int * (int * 'c) list) list)
val currentPoems : (int * (int * 'c) list) list
val tokenPoems : (int * (int * 'c) list) list
val merger : ('d * (int * 'e) list -> 'f * (int * 'e) list -> 'd * (int * 'e) list)
val currentPoemNumber : 'd
val currentLinesPositions : (int * 'e) list
val tokenLinesPositions : (int * 'e) list
val linesPositions : (int * 'c) list
val isEmpty : list:'T list -> bool
Full name: Microsoft.FSharp.Collections.List.isEmpty
val token : 'a
val poems : (int * (int * 'b) list) list
val queryIndex : index:('a * ('b * ('c * 'd) list) list) list -> findPosition:'d -> count:int -> ('a * int) list (requires equality)
Full name: Script.queryIndex
The function will return at most "count" terms that appear in the "findPosition" in the given index.
val index : ('a * ('b * ('c * 'd) list) list) list (requires equality)
val findPosition : 'd (requires equality)
val count : int
val tokenFreq : int
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)
Full name: Microsoft.FSharp.Collections.List.sumBy
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.filter
val zip : source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2>
Full name: Microsoft.FSharp.Collections.Seq.zip
val index : int
val element : 'a * int
val resolveSinglePoem : index:('a * ('b * ('c * 'd) list) list) list -> findToken:'a -> findPosition:'d -> 'b * 'c (requires equality and equality)
Full name: Script.resolveSinglePoem
Acquire first poem for the given token and line position
val index : ('a * ('b * ('c * 'd) list) list) list (requires equality and equality)
val findToken : 'a (requires equality)
type QueryResult =
| LineVariant of string * int
| SinglePoem of int * int
Full name: Script.QueryResult
union case QueryResult.LineVariant: string * int -> QueryResult
union case QueryResult.SinglePoem: int * int -> QueryResult
val wrappedQueryIndex : filteredIndex:(string * (int * (int * 'a) list) list) list -> searchPosition:'a -> count:int -> QueryResult list (requires equality)
Full name: Script.wrappedQueryIndex
Wraps results returned by queryIndex into QueryResult type
val filteredIndex : (string * (int * (int * 'a) list) list) list (requires equality)
val searchPosition : 'a (requires equality)
type ExtendedResult =
| ExtendedLineVariant of string * int
| ExtendedSinglePoem of string * string * int * string
Full name: Script.ExtendedResult
union case ExtendedResult.ExtendedLineVariant: string * int -> ExtendedResult
union case ExtendedResult.ExtendedSinglePoem: string * string * int * string -> ExtendedResult
val extendQueryResults : queryResults:QueryResult list -> poems:seq<Poem> -> ExtendedResult list
Full name: Script.extendQueryResults
Extends QueryResult list with information from poems list
val queryResults : QueryResult list
val poems : seq<Poem>
val result : QueryResult
property Poem.Lines: string list
property Poem.Title: string
property Poem.Href: string
val hrefAndHtmlToPoem : poemHref:string -> poemHtml:string -> Poem
Full name: Script.hrefAndHtmlToPoem
val poemHtml : string
val titlePattern : string
val linePattern : string
val isFinalEditionHref : href:string -> bool
Full name: Script.isFinalEditionHref
Check that the given link is a link to a final edition poem
val href : string
String.Contains(value: string) : bool
val crawlPoemsFromWeb : seq<Poem>
Full name: Script.crawlPoemsFromWeb
val domainUrl : string
val volumeUrlTemplate : string
val poemUrlTemplate : string
val volumeNumber : int
String.Format(format: string, [<ParamArray>] args: obj []) : string
String.Format(format: string, arg0: obj) : string
String.Format(provider: IFormatProvider, format: string, [<ParamArray>] args: obj []) : string
String.Format(format: string, arg0: obj, arg1: obj) : string
String.Format(format: string, arg0: obj, arg1: obj, arg2: obj) : string
val collect : mapping:('T -> #seq<'U>) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.collect
val cache : source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.cache
val savePoemsToCache : cacheFilePath:string -> poemsList:'a -> unit
Full name: Script.savePoemsToCache
val cacheFilePath : string
val poemsList : 'a
val stream : FileStream
Multiple items
type FileStream =
inherit Stream
new : path:string * mode:FileMode -> FileStream + 14 overloads
member BeginRead : array:byte[] * offset:int * numBytes:int * userCallback:AsyncCallback * stateObject:obj -> IAsyncResult
member BeginWrite : array:byte[] * offset:int * numBytes:int * userCallback:AsyncCallback * stateObject:obj -> IAsyncResult
member CanRead : bool
member CanSeek : bool
member CanWrite : bool
member EndRead : asyncResult:IAsyncResult -> int
member EndWrite : asyncResult:IAsyncResult -> unit
member Flush : unit -> unit + 1 overload
member GetAccessControl : unit -> FileSecurity
...
Full name: System.IO.FileStream
--------------------
FileStream(path: string, mode: FileMode) : unit
(+0 other overloads)
FileStream(handle: Win32.SafeHandles.SafeFileHandle, access: FileAccess) : unit
(+0 other overloads)
FileStream(path: string, mode: FileMode, access: FileAccess) : unit
(+0 other overloads)
FileStream(handle: Win32.SafeHandles.SafeFileHandle, access: FileAccess, bufferSize: int) : unit
(+0 other overloads)
FileStream(path: string, mode: FileMode, access: FileAccess, share: FileShare) : unit
(+0 other overloads)
FileStream(handle: Win32.SafeHandles.SafeFileHandle, access: FileAccess, bufferSize: int, isAsync: bool) : unit
(+0 other overloads)
FileStream(path: string, mode: FileMode, access: FileAccess, share: FileShare, bufferSize: int) : unit
(+0 other overloads)
FileStream(path: string, mode: FileMode, access: FileAccess, share: FileShare, bufferSize: int, options: FileOptions) : unit
(+0 other overloads)
FileStream(path: string, mode: FileMode, access: FileAccess, share: FileShare, bufferSize: int, useAsync: bool) : unit
(+0 other overloads)
FileStream(path: string, mode: FileMode, rights: Security.AccessControl.FileSystemRights, share: FileShare, bufferSize: int, options: FileOptions) : unit
(+0 other overloads)
type FileMode =
| CreateNew = 1
| Create = 2
| Open = 3
| OpenOrCreate = 4
| Truncate = 5
| Append = 6
Full name: System.IO.FileMode
field FileMode.Create = 2
val serializer : obj
val typeof<'T> : Type
Full name: Microsoft.FSharp.Core.Operators.typeof
Multiple items
type SerializationInfo =
new : type:Type * converter:IFormatterConverter -> SerializationInfo
member AddValue : name:string * value:obj -> unit + 15 overloads
member AssemblyName : string with get, set
member FullTypeName : string with get, set
member GetBoolean : name:string -> bool
member GetByte : name:string -> byte
member GetChar : name:string -> char
member GetDateTime : name:string -> DateTime
member GetDecimal : name:string -> decimal
member GetDouble : name:string -> float
...
Full name: System.Runtime.Serialization.SerializationInfo
--------------------
SerializationInfo(type: Type, converter: IFormatterConverter) : unit
FileStream.Flush() : unit
FileStream.Flush(flushToDisk: bool) : unit
Stream.Close() : unit
val loadPoemsFromCache : cacheFilePath:string -> Poem list
Full name: Script.loadPoemsFromCache
field FileMode.Open = 3
val poemsList : (string * string * seq<string>) list
val poemInfo : string * string * seq<string>
val crawlPoemsOrLoadFromCache : Poem list
Full name: Script.crawlPoemsOrLoadFromCache
type File =
static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
static member AppendAllText : path:string * contents:string -> unit + 1 overload
static member AppendText : path:string -> StreamWriter
static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
static member Create : path:string -> FileStream + 3 overloads
static member CreateText : path:string -> StreamWriter
static member Decrypt : path:string -> unit
static member Delete : path:string -> unit
static member Encrypt : path:string -> unit
static member Exists : path:string -> bool
...
Full name: System.IO.File
File.Exists(path: string) : bool
type PushkinTreeNode =
| VariantNode of string * int * seq<PushkinTreeNode>
| PoemNode of string * string * int * string
Full name: Script.PushkinTreeNode
union case PushkinTreeNode.VariantNode: string * int * seq<PushkinTreeNode> -> PushkinTreeNode
union case PushkinTreeNode.PoemNode: string * string * int * string -> PushkinTreeNode
val createPushkinTree : pushkinPoems:seq<Poem> -> poemsIndex:(string * (int * (int * int) list) list) list -> count:int -> PushkinTreeNode list
Full name: Script.createPushkinTree
val pushkinPoems : seq<Poem>
val poemsIndex : (string * (int * (int * int) list) list) list
val createTreeLevel : (int -> string list -> (string * (int * (int * int) list) list) list -> PushkinTreeNode list)
val currentQuery : string list
val currentIndex : (string * (int * (int * int) list) list) list
val searchPosition : int
val length : list:'T list -> int
Full name: Microsoft.FSharp.Collections.List.length
val queryResult : QueryResult list
val prettyResult : ExtendedResult list
val result : ExtendedResult
val freq : int
val pushkinTreeToNumberOfQueries : pushkinTree:seq<PushkinTreeNode> -> int
Full name: Script.pushkinTreeToNumberOfQueries
val pushkinTree : seq<PushkinTreeNode>
val subTreeResults : int
val sumBy : projection:('T -> 'U) -> source:seq<'T> -> 'U (requires member ( + ) and member get_Zero)
Full name: Microsoft.FSharp.Collections.Seq.sumBy
val pushkinTreeNode : PushkinTreeNode
val subTree : seq<PushkinTreeNode>
val resultsToHtml : pushkinTree:seq<PushkinTreeNode> -> string
Full name: Script.resultsToHtml
val treeToHtml : (seq<PushkinTreeNode> -> string list -> int -> int -> int * string)
val tree : seq<PushkinTreeNode>
val currentPath : string list
val currentNumber : int
val startingNumber : int
val zippedTreeLevel : seq<int * PushkinTreeNode>
val initInfinite : initializer:(int -> 'T) -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.initInfinite
val i : int
val pathToString : (seq<string> -> string)
val path : seq<string>
val parts : seq<string>
val x : string
String.Join(separator: string, values: Collections.Generic.IEnumerable<string>) : string
String.Join<'T>(separator: string, values: Collections.Generic.IEnumerable<'T>) : string
String.Join(separator: string, [<ParamArray>] values: obj []) : string
String.Join(separator: string, [<ParamArray>] value: string []) : string
String.Join(separator: string, value: string [], startIndex: int, count: int) : string
val thisLevelStart : string
type Environment =
static member CommandLine : string
static member CurrentDirectory : string with get, set
static member Exit : exitCode:int -> unit
static member ExitCode : int with get, set
static member ExpandEnvironmentVariables : name:string -> string
static member FailFast : message:string -> unit + 1 overload
static member GetCommandLineArgs : unit -> string[]
static member GetEnvironmentVariable : variable:string -> string + 1 overload
static member GetEnvironmentVariables : unit -> IDictionary + 1 overload
static member GetFolderPath : folder:SpecialFolder -> string + 1 overload
...
nested type SpecialFolder
nested type SpecialFolderOption
Full name: System.Environment
property Environment.NewLine: string
val thisLevelTable : string
val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State
Full name: Microsoft.FSharp.Collections.Seq.fold
val acc : string
val treeNode : int * PushkinTreeNode
val number : int
val subtree : seq<PushkinTreeNode>
val thisLevelEnd : string
val thisLevelOutput : string
val levelLength : int
val length : source:seq<'T> -> int
Full name: Microsoft.FSharp.Collections.Seq.length
val subTreeCount : int
val subTreeOutput : string
val acc : int
val result : string
val content : string
val outputResultsToFile : content:string -> unit
Full name: Script.outputResultsToFile
val templateFile : string
val outputFile : string
val templateReplacePattern : string
val templateHtml : string
File.ReadAllText(path: string) : string
File.ReadAllText(path: string, encoding: Encoding) : string
val resultHtml : string
File.WriteAllText(path: string, contents: string) : unit
File.WriteAllText(path: string, contents: string, encoding: Encoding) : unit
val poems : Poem list
Full name: Script.poems
val poemIndex : (string * (int * (int * int) list) list) list
Full name: Script.poemIndex
property List.Length: int
val tree : PushkinTreeNode list
Full name: Script.tree
val htmlContent : string
Full name: Script.htmlContent
More information