Leeres Fossil Repo

Check-in [1aa4e3e7c1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial commit
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1aa4e3e7c1b8253b7ffa5e93913859d481784bb1
User & Date: nsa 2013-04-08 08:48:05
Context
2013-04-08
11:35
Draft implementation in literate style check-in: bd5b945d3b user: nsa tags: trunk
08:48
Initial commit check-in: 1aa4e3e7c1 user: nsa tags: trunk
2011-09-30
15:44
initial empty check-in check-in: f2e5bbc816 user: sven schmalle tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added lit.go.











































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
package main

import (
	"regexp"
	"flag"
	"bufio"
	"fmt"
	"os"
	"io"
	"strings"
)

func main() {
	var sourceFile string
	var docFile string
	var parsingFile string
	var defaultChunk string

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of lit: lit [options] file-to-parse.w\n")
		flag.PrintDefaults()
	}

	flag.StringVar(&defaultChunk, "default-chunk", "*", "Default program chunk")
	flag.StringVar(&sourceFile, "src-out", "", "File to write source code")
	flag.StringVar(&docFile, "doc-out", "", "File to write document")
	flag.Parse()

	if len(flag.Args()) > 0 {
		parsingFile = flag.Arg(0)
	}
	
	if parsingFile == "" || (sourceFile == "" && docFile == "") {
		flag.Usage()
		os.Exit(0)
	}

	chunks, document := parseFile(parsingFile)
	chunks = expandChunks(chunks)

	if sourceFile != "" {
		sourceOutput, err := os.Create(sourceFile)
		defer sourceOutput.Close()

		if err != nil {
			panic(err)
		}
		sourceOutput.WriteString(chunks[defaultChunk])
	}

	if docFile != "" {
		docOutput, err := os.Create(docFile)
		defer docOutput.Close()	

		if err != nil {
			panic(err)
		}
		docOutput.WriteString(document)	
	}
}


func parseFile(fileName string) (map[string]string, string) {
	f, err := os.Open(fileName)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	fileBuf := bufio.NewReader(f)

	var (
		endOfChunkMatcher *regexp.Regexp
		chunkMatcher *regexp.Regexp
		regexpError error
	)

	chunkMatcher, regexpError = regexp.Compile("<<([^>]+)>>=")
	if regexpError != nil {
		panic(regexpError)
	}
	endOfChunkMatcher, regexpError = regexp.Compile("@")
	if regexpError != nil {
		panic(regexpError)
	}
	
	var document string
	var chunkName string
	var chunks = make(map[string]string)

	var processLine = func(line string) {
		if chunkName != "" {
			chunks[chunkName] += line
		} else {
			document += line
		}
	}
	
	for {
		line, err := fileBuf.ReadString('\n')
		if err == io.EOF {
			processLine(line)
			break
		} else if err != nil {
			panic(err)
		}
		var matches = chunkMatcher.FindStringSubmatch(line)
		if matches != nil {
			chunkName = matches[1]
			chunks[chunkName] = ""
		} else if matches = endOfChunkMatcher.FindStringSubmatch(line); matches != nil {
			chunkName = ""
		} else {
			processLine(line)
		}
	}
	return chunks, document
}


func expandChunks(chunks map[string]string) map[string]string {

	var expandedChunks = make(map[string]string)
	chunkMatcher, err := regexp.Compile("<<([^>]+)>>")
	if err != nil {
		panic(err)
	}

	var expandBody func(b string) string
	expandBody = func(b string) string {
		var newBody = b
		submatches := chunkMatcher.FindAllStringSubmatch(b, -1)
		if submatches != nil {
			for _, matches := range submatches {
				fullChunk, chunkName := matches[0], matches[1]
				if chunks[chunkName] != "" {
					newBody = strings.Replace(newBody, fullChunk, expandBody(chunks[chunkName]), -1)
				}
			}
		}
		return newBody
	}

	for name, body := range chunks {
		expandedChunks[name] = expandBody(body)
	}

	return expandedChunks
}

Added test.w.

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
Hello!

<<test>>=
	begin test
		print "Ok"
	end
@ 

Another one tricky insert
<<test2>>=
	if a > b then
		<<test>>
	else 
		return 42
	end
@

Bye!

<<Здравствуйте>>=
	hello world
@

<<*>>= 
	program dummy
	<<test>>
	<<test2>>
	<<Здравствуйте>>
	end
@

Conclusion