#! /usr/bin/original-awk -f # RTFM - The Resource Teaching Frame-based Machine # Copyright (C) 2008 Matous J. Fialka, # Released under the terms of The MIT License # Usage: rtfm.awk [ file ] # Notes: to avoid infinite loop never redirect file to stdin! { SkipComment = gsub(/#.*$/, "", $0) } /[^\\]\\$/ { OmitNewLine = 1 gsub(/\\$/, "", $0) } /\\\\$/ { gsub(/\\\\$/, "\\", $0) } /^[[:blank:]]*$/ { if (SeenCommand) { next } if (! SkipComment && ! OmitNewLine) { BlanksCount++ } } $1 ~ /^\.(MARK|STOP|CASE|PLAY)$/ { DataTape[++Record] = gsubspecials() if (! OmitNewLine) { DataTape[Record] = DataTape[Record] } OmitNewLine = 0 BlanksCount = 0 SeenCommand = 1 next } /[^[:blank:]]/ { if (! FirstNonBlank) { FirstNonBlank = 1 } else { while (BlanksCount-- > 0) { DataTape[++Record] = "\n" } } gsub(/^\t/, "", $0) DataTape[++Record] = gsubspecials() if (! OmitNewLine) { DataTape[Record] = (DataTape[Record] "\n") } OmitNewLine = 0 BlanksCount = 0 SeenCommand = 0 next } END { RecordsCount = Record for (Record = 1; Record <= RecordsCount; Record++) { if (DataTape[Record] ~ /^\.(MARK|STOP|CASE|PLAY)[[:blank:]]+/) { split(Line = DataTape[Record], LineParts, /[[:blank:]]+/) gsub(/^[^[:blank:]]+[[:blank:]]*/, "", Line) if (LineParts[1] == ".MARK") { Marks[Record] = LineParts[2] if (LookingUpMark && indexOf(Marks, MarkToLookUp)) { LookingUpMark = 0 Record-- continue } } if (LookingUpMark) { continue } if (LineParts[1] == ".STOP") { printf "%s", Line if((getline Answer < "-") < 1) { printf "\n" } continue } if (LineParts[1] == ".CASE") { if (Answer ~ (("^" LineParts[2]) "$")) { gsub(/\\\?/, Answer, LineParts[3]) if (Temp = indexOf(Marks, LineParts[3])) { Record = Temp - 1 } else { LookingUpMark = 1 MarkToLookUp = LineParts[3] } gsub(/^[^[:blank:]]+[[:blank:]]*/, "", Line) gsub(/^[^[:blank:]]+[[:blank:]]*/, "", Line) printf "%s", Line } continue } if (LineParts[1] == ".PLAY") { gsub(/\\\?/, Answer, LineParts[2]) if (Temp = indexOf(Marks, LineParts[2])) { Record = Temp - 1 } else { LookingUpMark = 1 MarkToLookUp = LineParts[2] } gsub(/^[^[:blank:]]+[[:blank:]]*/, "", Line) printf "%s", Line } continue } if (! LookingUpMark) { printf "%s", DataTape[Record] } } if (LookingUpMark) { exit 1 } } function gsubspecials() { gsub(/\\a/, "\a", $0) gsub(/\\b/, "\b", $0) gsub(/\\f/, "\f", $0) gsub(/\\n/, "\n", $0) gsub(/\\r/, "\r", $0) gsub(/\\t/, "\t", $0) gsub(/\\v/, "\v", $0) return $0 } function indexOf(Array, Word, Index) { for (Index in Array) { if (Array[Index] == Word) { return Index } } return 0 }