// code generated by "translate.go.pss" a pep script // http://bumble.sf.net/books/pars/tr/ // s.HasPrefix can be used instead of strings.HasPrefix package main import ( "fmt" "bufio" "strings" "strconv" "unicode" "io" "os" "unicode/utf8" ) // an alias for Println for brevity var pr = fmt.Println /* a machine for parsing */ type machine struct { SIZE int // how many elements in stack/tape/marks eof bool charsRead int linesRead int escape rune delimiter rune counter int work string stack []string cell int tape []string marks []string peep rune reader *bufio.Reader } // there is no special init for structures func newMachine(size int) *machine { mm := machine{SIZE: size} mm.eof = false // end of stream reached? mm.charsRead = 0 // how many chars already read mm.linesRead = 1 // how many lines already read mm.escape = '\\' mm.delimiter = '*' // push/pop delimiter (default "*") mm.counter = 0 // a counter for anything mm.work = "" // the workspace mm.stack = make([]string, 0, mm.SIZE) // stack for parse tokens mm.cell = 0 // current tape cell // slices not arrays mm.tape = make([]string, mm.SIZE, mm.SIZE) // a list of attribute for tokens mm.marks = make([]string, mm.SIZE, mm.SIZE) // marked tape cells // or dont initialse peep until "parse()" calls "setInput()" // check! this is not so simple mm.reader = bufio.NewReader(os.Stdin) var err error mm.peep, _, err = mm.reader.ReadRune() if err == io.EOF { mm.eof = true } else if err != nil { fmt.Fprintln(os.Stderr, "error:", err) os.Exit(1) } return &mm } // method syntax. // func (v * vertex) abs() float64 { ... } // multiline strings are ok ? func (mm *machine) setInput(newInput string) { print("to be implemented") } // read one utf8 character from the input stream and // update the machine. func (mm *machine) read() { var err error if mm.eof { os.Exit(0) } mm.charsRead += 1 // increment lines if mm.peep == '\n' { mm.linesRead += 1 } mm.work += string(mm.peep) // check! mm.peep, _, err = mm.reader.ReadRune() if err == io.EOF { mm.eof = true } else if err != nil { fmt.Fprintln(os.Stderr, "error:", err) os.Exit(1) } } // remove escape character: trivial method ? // check the python code for this, and the c code in machine.interp.c func (mm *machine) unescapeChar(c string) { // if mm.work = "" { return } mm.work = strings.Replace(mm.work, "\\"+c, c, -1) } // add escape character : trivial func (mm *machine) escapeChar(c string) { mm.work = strings.Replace(mm.work, c, "\\"+c, -1) } /** a helper function to count trailing escapes */ func (mm *machine) countEscapes(suffix string) int { count := 0 ss := "" if strings.HasSuffix(mm.work, suffix) { ss = strings.TrimSuffix(mm.work, suffix) } for (strings.HasSuffix(ss, string(mm.escape))) { ss = strings.TrimSuffix(ss, string(mm.escape)) count++ } return count } // reads the input stream until the workspace ends with the // given character or text, ignoring escaped characters func (mm *machine) until(suffix string) { if mm.eof { return; } // read at least one character mm.read() for true { if mm.eof { return; } // we need to count the mm.Escape chars preceding suffix // if odd, keep reading, if even, stop if strings.HasSuffix(mm.work, suffix) { if (mm.countEscapes(suffix) % 2 == 0) { return } } mm.read() } } /* increment the tape pointer (command ++) and grow the tape and marks arrays if necessary */ func (mm *machine) increment() { mm.cell++ if mm.cell >= len(mm.tape) { mm.tape = append(mm.tape, "") mm.marks = append(mm.marks, "") mm.SIZE++ } } /* pop the last token from the stack into the workspace */ func (mm *machine) pop() bool { if len(mm.stack) == 0 { return false } // no, get last element of stack // a[len(a)-1] mm.work = mm.stack[len(mm.stack)-1] + mm.work // a = a[:len(a)-1] mm.stack = mm.stack[:len(mm.stack)-1] if mm.cell > 0 { mm.cell -= 1 } return true } // push the first token from the workspace to the stack func (mm *machine) push() bool { // dont increment the tape pointer on an empty push if mm.work == "" { return false } // push first token, or else whole string if no delimiter aa := strings.SplitN(mm.work, string(mm.delimiter), 2) if len(aa) == 1 { mm.stack = append(mm.stack, mm.work) mm.work = "" } else { mm.stack = append(mm.stack, aa[0]+string(mm.delimiter)) mm.work = aa[1] } mm.increment() return true } // func (mm *machine) printState() { fmt.Printf("Stack %v Work[%s] Peep[%c] \n", mm.stack, mm.work, mm.peep) fmt.Printf("Acc:%v Esc:%c Delim:%c Chars:%v", mm.counter, mm.escape, mm.delimiter, mm.charsRead) fmt.Printf(" Lines:%v Cell:%v EOF:%v \n", mm.linesRead, mm.cell, mm.eof) for ii, vv := range mm.tape { fmt.Printf("%v [%s] \n", ii, vv) if ii > 4 { return; } } } func (mm *machine) goToMark(mark string) { markFound := false for ii := range mm.marks { if mm.marks[ii] == mark { mm.cell = ii; markFound = true; break } } if markFound == false { fmt.Printf("badmark '%s'", mark) os.Exit(1) } } // this is where the actual parsing/compiling code should go // so that it can be used by other go classes/objects. Also // should have a stream argument. func (mm *machine) parse(s string) { } /* adapt for clop and clip */ func trimLastChar(s string) string { r, size := utf8.DecodeLastRuneInString(s) if r == utf8.RuneError && (size == 0 || size == 1) { size = 0 } return s[:len(s)-size] } func (mm *machine) clip() { cc, _ := utf8.DecodeLastRuneInString(mm.work) mm.work = strings.TrimSuffix(mm.work, string(cc)) } func (mm *machine) clop() { _, size := utf8.DecodeRuneInString(mm.work) mm.work = mm.work[size:] } type fn func(rune) bool // eg unicode.IsLetter('x') /* check whether the string s only contains runes of type determined by the typeFn function */ func isInClass(typeFn fn, s string) bool { if s == "" { return false; } for _, rr := range s { //if !unicode.IsLetter(rr) { if !typeFn(rr) { return false } } return true } /* range in format 'a,z' */ func isInRange(start rune, end rune, s string) bool { if s == "" { return false; } for _, rr := range s { if (rr < start) || (rr > end) { return false } } return true } /* list of runes (unicode chars ) */ func isInList(list string, s string) bool { return strings.ContainsAny(s, list) } func main() { // This size needs to be big for some applications. Eg // calculating big palindromes. Really // it should be dynamically allocated. var size = 30000 var mm = newMachine(size); var restart = false; // the go compiler complains when modules are imported but // not used, also if vars are not used. if restart {}; unicode.IsDigit('0'); strconv.Itoa(0); // make room for document title, and table of contents // mark "toc"; add "toc*"; push; // mark "title"; add "title*"; push; /* nop eliminated */ for !mm.eof { /* lex block */ for true { mm.read() /* read */ if (isInList("\n", mm.work)) { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear // just for debugging. // add "line: "; lines; add "\n"; print; clear; mm.work += strconv.Itoa(mm.counter) /* count */ // check counter as flag. If set, then dont generate newline // tokens. if (mm.work == "0") { mm.work = "" // clear mm.work += "nl*" mm.push(); break } } if (isInList("\r", mm.work)) { mm.work = "" // clear restart = true; break // restart } // space includes \n\r so we can't use the [:space:] class if (isInList(" \t", mm.work)) { /* while */ for isInList(" \t", string(mm.peep)) { if mm.eof { break } mm.read() } mm.work = "" // clear break } // cant really use ' because then we can't write "can't" for example if (mm.work == "\"") { // check for multiline syntax """ /* while */ for isInList("\"", string(mm.peep)) { if mm.eof { break } mm.read() } if (mm.work != "\"") { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "word*" mm.push(); break } /* whilenot */ for !isInList("\"\n", string(mm.peep)) { if mm.eof { break; } mm.read() } // check for multiple """ for multiline quotes if (mm.eof) { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); break } mm.read() /* read */ // one double quote on line. if (isInList("\n", mm.work)) { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); break } // closing double quote. mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "quoted*" mm.push(); break } // [[ ]] >> << are parse as words (space delimited) // everything else is a word // all the logic in the word* block could just be here. if (mm.work != "") { /* whilenot */ for !isInClass(unicode.IsSpace, string(mm.peep)) { if mm.eof { break; } mm.read() } mm.tape[mm.cell] = mm.work /* put */ // the subsection marker if (mm.work == "....") { mm.work = "" // clear mm.work += "4dots*" mm.push(); break } mm.work = "" // clear mm.work += "word*" mm.push(); break } // end of the lexing phase of the script // start of the parse/compile/translate phase break } if restart { restart = false; continue; } // parse block for true { // The parse/compile/translate/transform phase involves // recognising series of tokens on the stack and "reducing" them // according to the required bnf grammar rules. //----------------- // 1 token mm.pop(); //(eof).!"end*" { //} if (mm.work == "word*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ // no numbers in headings! if (isInRange('A','Z', mm.work)) { mm.work = "" // clear mm.work += "utext*" mm.push(); continue } // the subheading marker //"...." { clear; add "4dots*"; push; .reparse } // emphasis or explanation line marker //"*" { clear; add "star*"; push; .reparse } // image markers if (mm.work == "[[") { mm.work += "*" mm.push(); continue } if (mm.work == "]]") { mm.work += "*" mm.push(); continue } // the code line marker, and float right marker if (mm.work == ">>") { // convert to html entities mm.work = "" // clear mm.work += ">> " mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += ">>*" mm.push(); continue } // the float left marker if (mm.work == "<<") { mm.work = "" // clear mm.work += "<< " mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "<<*" mm.push(); continue } // multiline quotes if (mm.work == "\"\"\"") { mm.work = "" // clear mm.until("\"\"\""); if (!strings.HasSuffix(mm.work,"\"\"\"")) { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } mm.clip() mm.clip() mm.clip() mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "quoted*" mm.push(); continue } // multiline codeblocks start with --- on a newline if (strings.HasPrefix(mm.work, "---") && isInList("-", mm.work)) { mm.work = "" // clear mm.pop(); if (mm.work == "nl*") { mm.work = "" // clear mm.until(",,,"); if (!strings.HasSuffix(mm.work,",,,")) { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } mm.clip() mm.clip() mm.clip() /* replace */ mm.work = strings.Replace(mm.work, ">", ">", -1) /* replace */ mm.work = strings.Replace(mm.work, "<", "<", -1) mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "
"
            mm.work += mm.tape[mm.cell] /* get */
            mm.work += "
" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear // discard extra ,,,, /* while */ for isInList(",", string(mm.peep)) { if mm.eof { break } mm.read() } mm.work = "" // clear mm.work += "codeline*" mm.push(); continue } mm.push(); mm.work += "word*" mm.push(); continue } // starline starts with a star if (mm.work == "*") { mm.work = "" // clear mm.work += "⊗ " mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.pop(); if (mm.work == "nl*") { mm.work = "" // clear // clear leading whitespace /* while */ for isInList(" \t", string(mm.peep)) { if mm.eof { break } mm.read() } mm.work = "" // clear mm.work += "" /* whilenot */ for !isInList("\n", string(mm.peep)) { if mm.eof { break; } mm.read() } mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "emline*" mm.push(); continue } mm.push(); mm.work += "word*" mm.push(); continue } // document title is marked up by ==* at start of line if (mm.work == "==*") { mm.work = "" // clear mm.pop(); if (mm.work == "nl*") { mm.work = "" // clear // clear leading whitespace /* while */ for isInList(" \t", string(mm.peep)) { if mm.eof { break } mm.read() } mm.work = "" // clear mm.work += "

" /* whilenot */ for !isInList("\n", string(mm.peep)) { if mm.eof { break; } mm.read() } mm.work += "

" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } mm.push(); mm.work += "word*" mm.push(); continue } // the code block begin marker. can't read straight to end marker //B"---".[-] { clear; put; add "---*"; push; .reparse } if (strings.HasPrefix(mm.work, "http://") || strings.HasPrefix(mm.work, "https://") || strings.HasPrefix(mm.work, "www.") || strings.HasPrefix(mm.work, "ftp://") || strings.HasPrefix(mm.work, "sftp://")) { mm.work = "" // clear mm.work += "link*" mm.push(); continue } // file names if (mm.work != "/") { if (strings.HasPrefix(mm.work, "/") || strings.HasPrefix(mm.work, "../") || strings.HasPrefix(mm.work, "img/")) { if (strings.HasSuffix(mm.work, "/") || strings.HasSuffix(mm.work, ".c") || strings.HasSuffix(mm.work, ".txt") || strings.HasSuffix(mm.work, ".html") || strings.HasSuffix(mm.work, ".pss") || strings.HasSuffix(mm.work, ".pp") || strings.HasSuffix(mm.work, ".js") || strings.HasSuffix(mm.work, ".java") || strings.HasSuffix(mm.work, ".tcl") || strings.HasSuffix(mm.work, ".py") || strings.HasSuffix(mm.work, ".pl") || strings.HasSuffix(mm.work, ".jpeg") || strings.HasSuffix(mm.work, ".jpg") || strings.HasSuffix(mm.work, ".png")) { mm.work = "" // clear mm.work += "file*" mm.push(); continue } } } // file names in single quotes, eg 'asm.pp' if (strings.HasPrefix(mm.work, "'") && strings.HasSuffix(mm.work, "'") && mm.work != "'" && mm.work != "''" && mm.work != "'/'") { mm.clip() mm.clop() if (strings.HasSuffix(mm.work, "/") || strings.HasSuffix(mm.work, ".c") || strings.HasSuffix(mm.work, ".txt") || strings.HasSuffix(mm.work, ".html") || strings.HasSuffix(mm.work, ".pss") || strings.HasSuffix(mm.work, ".pp") || strings.HasSuffix(mm.work, ".js") || strings.HasSuffix(mm.work, ".java") || strings.HasSuffix(mm.work, ".tcl") || strings.HasSuffix(mm.work, ".py") || strings.HasSuffix(mm.work, ".pl") || strings.HasSuffix(mm.work, ".jpeg") || strings.HasSuffix(mm.work, ".jpg") || strings.HasSuffix(mm.work, ".png")) { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "file*" mm.push(); continue } } mm.work = "" // clear mm.work += "word*" // leave the wordtoken on the workspace. } // get rid of insignificant tokens at the end of the document if (mm.work == "[[*" || mm.work == "<<*" || mm.work == ">>*" || mm.work == "quoted*") { if (mm.eof) { mm.work = "" // clear mm.work += "word*" } } // resolve links at the end of the document if (mm.work == "link*") { if (mm.eof) { mm.work = "" // clear mm.work += "" mm.work += mm.tape[mm.cell] /* get */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } } // resolve file links at the end of the document if (mm.work == "file*") { if (mm.eof) { mm.work = "" // clear mm.work += "" mm.work += mm.tape[mm.cell] /* get */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } } //----------------- // 2 tokens mm.pop(); // eliminate insignificant newlines and ellide words // and upper case text if (mm.work == "nl*word*" || mm.work == "nl*text*" || mm.work == "emline*text*" || mm.work == "emline*word*" || mm.work == "text*utext*" || mm.work == "word*utext*" || mm.work == "utext*text*" || mm.work == "utext*word*" || mm.work == "word*word*" || mm.work == "text*word*" || mm.work == "text*text*" || mm.work == "word*text*" || mm.work == "quoted*text*" || mm.work == "quoted*word*") { // check for pattern "file 'asm.pp' or folder '/books/' mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // ellide upper case text if (mm.work == "utext*utext*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "utext*" mm.push(); continue } // ellide as text insignificant "]]" image end tokens if (mm.work == "word*]]*" || mm.work == "text*]]*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // ellide multiple newlines if (mm.work == "nl*nl*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.work += "

\n" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "nl*" mm.push(); continue } // codelines. nl*>>* should not occur in image markup if (mm.work == "nl*>>*") { mm.work = "" // clear // clear leading whitespace /* while */ for isInList(" \t", string(mm.peep)) { if mm.eof { break } mm.read() } mm.work = "" // clear /* whilenot */ for !isInList("\n", string(mm.peep)) { if mm.eof { break; } mm.read() } /* replace */ mm.work = strings.Replace(mm.work, ">", ">", -1) /* replace */ mm.work = strings.Replace(mm.work, "<", "<", -1) mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "

"
        mm.work += mm.tape[mm.cell] /* get */
        mm.work += "
" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "codeline*" mm.push(); continue } // eliminate insignificant newlines at end of document if (mm.work == "word*nl*" || mm.work == "text*nl*") { if (mm.eof) { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } } // mark this up as a "recipe". // sample: // * description // >> sh code.to.exec if (mm.work == "emline*codeline*") { mm.work = "" // clear mm.work += "" mm.work += "\n

" mm.work += "\n " mm.work += "\n \n" mm.work += "\n
" mm.work += mm.tape[mm.cell] /* get */ mm.work += "
" mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ mm.work += "
\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } if (mm.work == "word*codeline*" || mm.work == "text*codeline*" || mm.work == "quoted*codeline*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.work += "\n
" mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ mm.work += "
\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // a line of code at the start of the document if (mm.work == "codeline*") { mm.work = "" // clear mm.work += "
" mm.work += mm.tape[mm.cell] /* get */ mm.work += "
\n" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // sample: tree www.abc.org (also at the start of document) if (mm.work == "word*link*" || mm.work == "text*link*" || mm.work == "nl*link*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.work += "" mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // link at the start of document (only 1 token) if (mm.work == "link*") { mm.work = "" // clear mm.work += "" mm.work += mm.tape[mm.cell] /* get */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // sample: condor /file.txt if (mm.work == "word*file*" || mm.work == "text*file*" || mm.work == "nl*file*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.work += "" mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // file link at start of document if (mm.work == "file*") { mm.work = "" // clear mm.work += "" mm.work += mm.tape[mm.cell] /* get */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } if (mm.work == "quoted*file*" || mm.work == "quoted*link*") { mm.work = "" // clear // remove quotes from quoted text mm.work += mm.tape[mm.cell] /* get */ mm.clip() mm.clop() mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "" mm.work += mm.tape[mm.cell] /* get */ mm.work += "" mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // get rid of irrelevant ">>" tokens (ie not in image, nor at // start of code line). // image format: [[ /file.txt "caption" >> ]] if (strings.HasSuffix(mm.work, ">>*")) { if (!strings.HasPrefix(mm.work,"nl*") && !strings.HasPrefix(mm.work,"quoted*") && !strings.HasPrefix(mm.work,"file*") && !strings.HasPrefix(mm.work,"link*")) { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } } // ellide insignificant "<<" tokens (ie not in image markup) if (strings.HasPrefix(mm.work, "<<*") && !strings.HasSuffix(mm.work,"]]*")) { /* replace */ mm.work = strings.Replace(mm.work, "<<*", "word*", -1) mm.push(); mm.push(); continue } // ellide insignificant "...." tokens (ie not in subsection heading) if (strings.HasPrefix(mm.work, "4dots*") && !strings.HasSuffix(mm.work,"nl*") && mm.work != "4dots*") { /* replace */ mm.work = strings.Replace(mm.work, "4dots*", "word*", -1) mm.push(); mm.push(); continue } // ellide insignificant "...." tokens (ie not in subsection heading) if (strings.HasSuffix(mm.work, "4dots*") && !strings.HasPrefix(mm.work,"utext*") && !strings.HasPrefix(mm.work,"uword*") && mm.work != "4dots*") { /* replace */ mm.work = strings.Replace(mm.work, "4dots*", "word*", -1) mm.push(); mm.push(); continue } // eliminate newlines in image markup if (mm.work == "[[*nl*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "[[*" mm.push(); continue } if (mm.work == "nl*]]*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "]]*" mm.push(); continue } // get rid of insignificant "[[" image start tokens // image format: [[ /file.txt "caption" >> ]] if (strings.HasPrefix(mm.work, "[[*") && mm.work != "[[*") { if (!strings.HasSuffix(mm.work,"file*") && !strings.HasSuffix(mm.work,"link*")) { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } } //---------------------- // 3 tokens mm.pop(); // top level headings, all upper case on the line in the source document if (mm.work == "nl*utext*nl*" || mm.work == "nl*uword*nl*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ // add a link so that table-of-contents works mm.work += "\n" mm.work += "\n" mm.work += "

" mm.work += mm.tape[mm.cell] /* get */ mm.work += " (↑)" mm.work += "

\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear // transfer nl value mm.increment() /* ++ */ mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear if mm.cell > 0 { mm.cell-- } /* -- */ mm.work += "text*nl*" mm.push(); mm.push(); continue } // eliminate newlines within image markup // this is important because nl*>>* is considered the // start of a "codeline". if (mm.work == "[[*file*nl*" || mm.work == "[[*link*nl*" || mm.work == "link*quoted*nl*" || mm.work == "file*quoted*nl*") { mm.clip() mm.clip() mm.clip() mm.push(); mm.push(); continue } // simple image format: [[ /path/file.jpg ]] if (mm.work == "[[*file*]]*" || mm.work == "[[*link*]]*") { mm.work = "" // clear mm.increment() /* ++ */ mm.work += "\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // incorrect image format: [[ /path/file.jpg word // just becomes text. I probably should hyperlink the links // but wont for now. if (mm.work == "[[*file*word*" || mm.work == "[[*link*word*" || mm.work == "[[*file*text*" || mm.work == "[[*link*text*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ mm.work += " " mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } //---------------------- // 4 tokens mm.pop(); // second level headings, eg SUBSECTION .... if (mm.work == "nl*utext*4dots*nl*" || mm.work == "nl*uword*4dots*nl*") { mm.work = "" // clear mm.work += mm.tape[mm.cell] /* get */ // add a link so that table-of-contents works mm.work += "\n" mm.work += "\n" mm.work += "

" mm.work += mm.tape[mm.cell] /* get */ mm.work += " (↑)" mm.work += "

\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear // transfer nl value mm.increment() /* ++ */ mm.increment() /* ++ */ mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ if mm.cell > 0 { mm.cell-- } /* -- */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear if mm.cell > 0 { mm.cell-- } /* -- */ mm.work += "text*nl*" mm.push(); mm.push(); continue } // image format with caption: [[ /path/file.jpg "caption" ]] if (mm.work == "[[*file*quoted*]]*" || mm.work == "[[*link*quoted*]]*") { mm.work = "" // clear mm.work += "

" mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ mm.work += "

\n" if mm.cell > 0 { mm.cell-- } /* -- */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // image format with float: [[ /path/file.jpg >> ]] if (mm.work == "[[*file*>>*]]*" || mm.work == "[[*link*>>*]]*") { mm.work = "" // clear mm.work += "\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // image format with float: [[ /path/file.jpg >> ]] if (mm.work == "[[*file*<<*]]*" || mm.work == "[[*link*<<*]]*") { mm.work = "" // clear mm.work += "\n" if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } //---------------------- // 5 tokens mm.pop(); // image format with caption and float: [[ /path/file.jpg "caption" >> ]] if (mm.work == "[[*file*quoted*>>*]]*" || mm.work == "[[*link*quoted*>>*]]*") { mm.work = "" // clear mm.work += "

" mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ mm.work += "

\n" if mm.cell > 0 { mm.cell-- } /* -- */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } // image format with caption and float: [[ /path/file.jpg "caption" >> ]] if (mm.work == "[[*file*quoted*<<*]]*" || mm.work == "[[*link*quoted*<<*]]*") { mm.work = "" // clear mm.work += "

" mm.increment() /* ++ */ mm.work += mm.tape[mm.cell] /* get */ mm.work += "

\n" if mm.cell > 0 { mm.cell-- } /* -- */ if mm.cell > 0 { mm.cell-- } /* -- */ mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "text*" mm.push(); continue } mm.push(); mm.push(); mm.push(); mm.push(); mm.push(); if (mm.eof) { mm.work += "\n \n" fmt.Printf("%s", mm.work) // print mm.work = "" // clear // workspace should be empty if (mm.work != "") { mm.tape[mm.cell] = mm.work /* put */ mm.work = "" // clear mm.work += "\n" fmt.Printf("%s", mm.work) // print } mm.work += "\n" fmt.Printf("%s", mm.work) // print mm.work = "" // clear // pop; mm.pop(); if (mm.work == "word*" || mm.work == "text*" || mm.work == "link*" || mm.work == "file*" || mm.work == "quoted*" || mm.work == "emline*" || mm.work == "nl*") { mm.work = "" // clear mm.work += "" mm.work += "\n" mm.work += "\n " mm.work += "\n " mm.work += "\n " mm.work += "\n" mm.work += "\n " mm.work += "\n " mm.work += "\n " mm.work += "\n " mm.work += "\n ..." mm.work += "\n" mm.work += "\n " mm.work += "\n " mm.work += "\n " mm.work += "\n " mm.work += "\n " mm.work += "\n" mm.work += "\n " mm.work += mm.tape[mm.cell] /* get */ mm.work += "\n\n" mm.work += "\n" fmt.Printf("%s", mm.work) // print } } break } // parse } } // end of generated golang code