* Document extractor service

* Fixing vendor modules

* Addressing PR Review comments

* Some small simplifications

* Fixing a linter complain

* simplifying a bit the code using package variables

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Jesús Espino
2020-10-27 15:58:38 +01:00
коммит произвёл GitHub
родитель 04ef5c682e
Коммит 8d5be2d657
484 изменённых файлов: 343292 добавлений и 6 удалений

27
vendor/github.com/ledongthuc/pdf/LICENSE сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

136
vendor/github.com/ledongthuc/pdf/README.md сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,136 @@
# PDF Reader
A simple Go library which enables reading PDF files. Forked from https://github.com/rsc/pdf
Features
- Get plain text content (without format)
- Get Content (including all font and formatting information)
## Install:
`go get -u github.com/ledongthuc/pdf`
## Read plain text
```golang
package main
import (
"bytes"
"fmt"
"github.com/ledongthuc/pdf"
)
func main() {
pdf.DebugOn = true
content, err := readPdf("test.pdf") // Read local pdf file
if err != nil {
panic(err)
}
fmt.Println(content)
return
}
func readPdf(path string) (string, error) {
f, r, err := pdf.Open(path)
// remember close file
defer f.Close()
if err != nil {
return "", err
}
var buf bytes.Buffer
b, err := r.GetPlainText()
if err != nil {
return "", err
}
buf.ReadFrom(b)
return buf.String(), nil
}
```
## Read all text with styles from PDF
```golang
func readPdf2(path string) (string, error) {
f, r, err := pdf.Open(path)
// remember close file
defer f.Close()
if err != nil {
return "", err
}
totalPage := r.NumPage()
for pageIndex := 1; pageIndex <= totalPage; pageIndex++ {
p := r.Page(pageIndex)
if p.V.IsNull() {
continue
}
var lastTextStyle pdf.Text
texts := p.Content().Text
for _, text := range texts {
if isSameSentence(text, lastTextStyle) {
lastTextStyle.S = lastTextStyle.S + text.S
} else {
fmt.Printf("Font: %s, Font-size: %f, x: %f, y: %f, content: %s \n", lastTextStyle.Font, lastTextStyle.FontSize, lastTextStyle.X, lastTextStyle.Y, lastTextStyle.S)
lastTextStyle = text
}
}
}
return "", nil
}
```
## Read text grouped by rows
```golang
package main
import (
"fmt"
"os"
"github.com/dcu/pdf"
)
func main() {
content, err := readPdf(os.Args[1]) // Read local pdf file
if err != nil {
panic(err)
}
fmt.Println(content)
return
}
func readPdf(path string) (string, error) {
f, r, err := pdf.Open(path)
defer func() {
_ = f.Close()
}()
if err != nil {
return "", err
}
totalPage := r.NumPage()
for pageIndex := 1; pageIndex <= totalPage; pageIndex++ {
p := r.Page(pageIndex)
if p.V.IsNull() {
continue
}
rows, _ := p.GetTextByRow()
for _, row := range rows {
println(">>>> row: ", row.Position)
for _, word := range row.Content {
fmt.Println(word.S)
}
}
}
return "", nil
}
```
## Demo
![Run example](https://i.gyazo.com/01fbc539e9872593e0ff6bac7e954e6d.gif)

53
vendor/github.com/ledongthuc/pdf/ascii85.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,53 @@
// file with help function for ascii85 decoder
// later if new decoders is going to add it reasonable to rename file and add them here
// also create interfaces to switch between them (like in unidoc)
package pdf
import (
"io"
)
type alphaReader struct {
reader io.Reader
}
func newAlphaReader(reader io.Reader) *alphaReader {
return &alphaReader{reader: reader}
}
func checkASCII85(r byte) byte {
if r >= '!' && r <= 'u' { // 33 <= ascii85 <=117
return r
}
if r == '~' {
return 1 // for marking possible end of data
}
return 0 // if non-ascii85
}
func (a *alphaReader) Read(p []byte) (int, error) {
n, err := a.reader.Read(p)
if err == io.EOF {
}
if err != nil {
return n, err
}
buf := make([]byte, n)
tilda := false
for i := 0; i < n; i++ {
char := checkASCII85(p[i])
if char == '>' && tilda { // end of data
break
}
if char > 1 {
buf[i] = char
}
if char == 1 {
tilda = true // possible end of data
}
}
copy(p, buf)
return n, nil
}

529
vendor/github.com/ledongthuc/pdf/lex.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,529 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Reading of PDF tokens and objects from a raw byte stream.
package pdf
import (
"fmt"
"io"
"strconv"
)
// A token is a PDF token in the input stream, one of the following Go types:
//
// bool, a PDF boolean
// int64, a PDF integer
// float64, a PDF real
// string, a PDF string literal
// keyword, a PDF keyword
// name, a PDF name without the leading slash
//
type token interface{}
// A name is a PDF name, without the leading slash.
type name string
// A keyword is a PDF keyword.
// Delimiter tokens used in higher-level syntax,
// such as "<<", ">>", "[", "]", "{", "}", are also treated as keywords.
type keyword string
// A buffer holds buffered input bytes from the PDF file.
type buffer struct {
r io.Reader // source of data
buf []byte // buffered data
pos int // read index in buf
offset int64 // offset at end of buf; aka offset of next read
tmp []byte // scratch space for accumulating token
unread []token // queue of read but then unread tokens
allowEOF bool
allowObjptr bool
allowStream bool
eof bool
key []byte
useAES bool
objptr objptr
}
// newBuffer returns a new buffer reading from r at the given offset.
func newBuffer(r io.Reader, offset int64) *buffer {
return &buffer{
r: r,
offset: offset,
buf: make([]byte, 0, 4096),
allowObjptr: true,
allowStream: true,
}
}
func (b *buffer) seek(offset int64) {
b.offset = offset
b.buf = b.buf[:0]
b.pos = 0
b.unread = b.unread[:0]
}
func (b *buffer) readByte() byte {
if b.pos >= len(b.buf) {
b.reload()
if b.pos >= len(b.buf) {
return '\n'
}
}
c := b.buf[b.pos]
b.pos++
return c
}
func (b *buffer) errorf(format string, args ...interface{}) {
panic(fmt.Errorf(format, args...))
}
func (b *buffer) reload() bool {
n := cap(b.buf) - int(b.offset%int64(cap(b.buf)))
n, err := b.r.Read(b.buf[:n])
if n == 0 && err != nil {
b.buf = b.buf[:0]
b.pos = 0
if b.allowEOF && err == io.EOF {
b.eof = true
return false
}
b.errorf("malformed PDF: reading at offset %d: %v", b.offset, err)
return false
}
b.offset += int64(n)
b.buf = b.buf[:n]
b.pos = 0
return true
}
func (b *buffer) seekForward(offset int64) {
for b.offset < offset {
if !b.reload() {
return
}
}
b.pos = len(b.buf) - int(b.offset-offset)
}
func (b *buffer) readOffset() int64 {
return b.offset - int64(len(b.buf)) + int64(b.pos)
}
func (b *buffer) unreadByte() {
if b.pos > 0 {
b.pos--
}
}
func (b *buffer) unreadToken(t token) {
b.unread = append(b.unread, t)
}
func (b *buffer) readToken() token {
if n := len(b.unread); n > 0 {
t := b.unread[n-1]
b.unread = b.unread[:n-1]
return t
}
// Find first non-space, non-comment byte.
c := b.readByte()
for {
if isSpace(c) {
if b.eof {
return io.EOF
}
c = b.readByte()
} else if c == '%' {
for c != '\r' && c != '\n' {
c = b.readByte()
}
} else {
break
}
}
switch c {
case '<':
if b.readByte() == '<' {
return keyword("<<")
}
b.unreadByte()
return b.readHexString()
case '(':
return b.readLiteralString()
case '[', ']', '{', '}':
return keyword(string(c))
case '/':
return b.readName()
case '>':
if b.readByte() == '>' {
return keyword(">>")
}
b.unreadByte()
fallthrough
default:
if isDelim(c) {
b.errorf("unexpected delimiter %#q", rune(c))
return nil
}
b.unreadByte()
return b.readKeyword()
}
}
func (b *buffer) readHexString() token {
tmp := b.tmp[:0]
for {
Loop:
c := b.readByte()
if c == '>' {
break
}
if isSpace(c) {
goto Loop
}
Loop2:
c2 := b.readByte()
if isSpace(c2) {
goto Loop2
}
x := unhex(c)<<4 | unhex(c2)
if x < 0 {
b.errorf("malformed hex string %c %c %s", c, c2, b.buf[b.pos:])
break
}
tmp = append(tmp, byte(x))
}
b.tmp = tmp
return string(tmp)
}
func unhex(b byte) int {
switch {
case '0' <= b && b <= '9':
return int(b) - '0'
case 'a' <= b && b <= 'f':
return int(b) - 'a' + 10
case 'A' <= b && b <= 'F':
return int(b) - 'A' + 10
}
return -1
}
func (b *buffer) readLiteralString() token {
tmp := b.tmp[:0]
depth := 1
Loop:
for !b.eof {
c := b.readByte()
switch c {
default:
tmp = append(tmp, c)
case '(':
depth++
tmp = append(tmp, c)
case ')':
if depth--; depth == 0 {
break Loop
}
tmp = append(tmp, c)
case '\\':
switch c = b.readByte(); c {
default:
b.errorf("invalid escape sequence \\%c", c)
tmp = append(tmp, '\\', c)
case 'n':
tmp = append(tmp, '\n')
case 'r':
tmp = append(tmp, '\r')
case 'b':
tmp = append(tmp, '\b')
case 't':
tmp = append(tmp, '\t')
case 'f':
tmp = append(tmp, '\f')
case '(', ')', '\\':
tmp = append(tmp, c)
case '\r':
if b.readByte() != '\n' {
b.unreadByte()
}
fallthrough
case '\n':
// no append
case '0', '1', '2', '3', '4', '5', '6', '7':
x := int(c - '0')
for i := 0; i < 2; i++ {
c = b.readByte()
if c < '0' || c > '7' {
b.unreadByte()
break
}
x = x*8 + int(c-'0')
}
if x > 255 {
b.errorf("invalid octal escape \\%03o", x)
}
tmp = append(tmp, byte(x))
}
}
}
b.tmp = tmp
return string(tmp)
}
func (b *buffer) readName() token {
tmp := b.tmp[:0]
for {
c := b.readByte()
if isDelim(c) || isSpace(c) {
b.unreadByte()
break
}
if c == '#' {
x := unhex(b.readByte())<<4 | unhex(b.readByte())
if x < 0 {
b.errorf("malformed name")
}
tmp = append(tmp, byte(x))
continue
}
tmp = append(tmp, c)
}
b.tmp = tmp
return name(string(tmp))
}
func (b *buffer) readKeyword() token {
tmp := b.tmp[:0]
for {
c := b.readByte()
if isDelim(c) || isSpace(c) {
b.unreadByte()
break
}
tmp = append(tmp, c)
}
b.tmp = tmp
s := string(tmp)
switch {
case s == "true":
return true
case s == "false":
return false
case isInteger(s):
x, err := strconv.ParseInt(s, 10, 64)
if err != nil {
b.errorf("invalid integer %s", s)
}
return x
case isReal(s):
x, err := strconv.ParseFloat(s, 64)
if err != nil {
b.errorf("invalid real %s", s)
}
return x
}
return keyword(string(tmp))
}
func isInteger(s string) bool {
if len(s) > 0 && (s[0] == '+' || s[0] == '-') {
s = s[1:]
}
if len(s) == 0 {
return false
}
for _, c := range s {
if c < '0' || '9' < c {
return false
}
}
return true
}
func isReal(s string) bool {
if len(s) > 0 && (s[0] == '+' || s[0] == '-') {
s = s[1:]
}
if len(s) == 0 {
return false
}
ndot := 0
for _, c := range s {
if c == '.' {
ndot++
continue
}
if c < '0' || '9' < c {
return false
}
}
return ndot == 1
}
// An object is a PDF syntax object, one of the following Go types:
//
// bool, a PDF boolean
// int64, a PDF integer
// float64, a PDF real
// string, a PDF string literal
// name, a PDF name without the leading slash
// dict, a PDF dictionary
// array, a PDF array
// stream, a PDF stream
// objptr, a PDF object reference
// objdef, a PDF object definition
//
// An object may also be nil, to represent the PDF null.
type object interface{}
type dict map[name]object
type array []object
type stream struct {
hdr dict
ptr objptr
offset int64
}
type objptr struct {
id uint32
gen uint16
}
type objdef struct {
ptr objptr
obj object
}
func (b *buffer) readObject() object {
tok := b.readToken()
if kw, ok := tok.(keyword); ok {
switch kw {
case "null":
return nil
case "<<":
return b.readDict()
case "[":
return b.readArray()
}
b.errorf("unexpected keyword %q parsing object", kw)
return nil
}
if str, ok := tok.(string); ok && b.key != nil && b.objptr.id != 0 {
tok = decryptString(b.key, b.useAES, b.objptr, str)
}
if !b.allowObjptr {
return tok
}
if t1, ok := tok.(int64); ok && int64(uint32(t1)) == t1 {
tok2 := b.readToken()
if t2, ok := tok2.(int64); ok && int64(uint16(t2)) == t2 {
tok3 := b.readToken()
switch tok3 {
case keyword("R"):
return objptr{uint32(t1), uint16(t2)}
case keyword("obj"):
old := b.objptr
b.objptr = objptr{uint32(t1), uint16(t2)}
obj := b.readObject()
if _, ok := obj.(stream); !ok {
tok4 := b.readToken()
if tok4 != keyword("endobj") {
b.errorf("missing endobj after indirect object definition")
b.unreadToken(tok4)
}
}
b.objptr = old
return objdef{objptr{uint32(t1), uint16(t2)}, obj}
}
b.unreadToken(tok3)
}
b.unreadToken(tok2)
}
return tok
}
func (b *buffer) readArray() object {
var x array
for {
tok := b.readToken()
if tok == nil || tok == keyword("]") {
break
}
b.unreadToken(tok)
x = append(x, b.readObject())
}
return x
}
func (b *buffer) readDict() object {
x := make(dict)
for {
tok := b.readToken()
if tok == nil || tok == keyword(">>") {
break
}
n, ok := tok.(name)
if !ok {
b.errorf("unexpected non-name key %T(%v) parsing dictionary", tok, tok)
continue
}
x[n] = b.readObject()
}
if !b.allowStream {
return x
}
tok := b.readToken()
if tok != keyword("stream") {
b.unreadToken(tok)
return x
}
switch b.readByte() {
case '\r':
if b.readByte() != '\n' {
b.unreadByte()
}
case '\n':
// ok
default:
b.errorf("stream keyword not followed by newline")
}
return stream{x, b.objptr, b.readOffset()}
}
func isSpace(b byte) bool {
switch b {
case '\x00', '\t', '\n', '\f', '\r', ' ':
return true
}
return false
}
func isDelim(b byte) bool {
switch b {
case '<', '>', '(', ')', '[', ']', '{', '}', '/', '%':
return true
}
return false
}

4286
vendor/github.com/ledongthuc/pdf/name.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1050
vendor/github.com/ledongthuc/pdf/page.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

138
vendor/github.com/ledongthuc/pdf/ps.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,138 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pdf
import (
"fmt"
"io"
)
// A Stack represents a stack of values.
type Stack struct {
stack []Value
}
func (stk *Stack) Len() int {
return len(stk.stack)
}
func (stk *Stack) Push(v Value) {
stk.stack = append(stk.stack, v)
}
func (stk *Stack) Pop() Value {
n := len(stk.stack)
if n == 0 {
return Value{}
}
v := stk.stack[n-1]
stk.stack[n-1] = Value{}
stk.stack = stk.stack[:n-1]
return v
}
func newDict() Value {
return Value{nil, objptr{}, make(dict)}
}
// Interpret interprets the content in a stream as a basic PostScript program,
// pushing values onto a stack and then calling the do function to execute
// operators. The do function may push or pop values from the stack as needed
// to implement op.
//
// Interpret handles the operators "dict", "currentdict", "begin", "end", "def", and "pop" itself.
//
// Interpret is not a full-blown PostScript interpreter. Its job is to handle the
// very limited PostScript found in certain supporting file formats embedded
// in PDF files, such as cmap files that describe the mapping from font code
// points to Unicode code points.
//
// There is no support for executable blocks, among other limitations.
//
func Interpret(strm Value, do func(stk *Stack, op string)) {
rd := strm.Reader()
b := newBuffer(rd, 0)
b.allowEOF = true
b.allowObjptr = false
b.allowStream = false
var stk Stack
var dicts []dict
Reading:
for {
tok := b.readToken()
if tok == io.EOF {
break
}
if kw, ok := tok.(keyword); ok {
switch kw {
case "null", "[", "]", "<<", ">>":
break
default:
for i := len(dicts) - 1; i >= 0; i-- {
if v, ok := dicts[i][name(kw)]; ok {
stk.Push(Value{nil, objptr{}, v})
continue Reading
}
}
do(&stk, string(kw))
continue
case "dict":
stk.Pop()
stk.Push(Value{nil, objptr{}, make(dict)})
continue
case "currentdict":
if len(dicts) == 0 {
panic("no current dictionary")
}
stk.Push(Value{nil, objptr{}, dicts[len(dicts)-1]})
continue
case "begin":
d := stk.Pop()
if d.Kind() != Dict {
panic("cannot begin non-dict")
}
dicts = append(dicts, d.data.(dict))
continue
case "end":
if len(dicts) <= 0 {
panic("mismatched begin/end")
}
dicts = dicts[:len(dicts)-1]
continue
case "def":
if len(dicts) <= 0 {
panic("def without open dict")
}
val := stk.Pop()
key, ok := stk.Pop().data.(name)
if !ok {
panic("def of non-name")
}
dicts[len(dicts)-1][key] = val.data
continue
case "pop":
stk.Pop()
continue
}
}
b.unreadToken(tok)
obj := b.readObject()
stk.Push(Value{nil, objptr{}, obj})
}
}
type seqReader struct {
rd io.Reader
offset int64
}
func (r *seqReader) ReadAt(buf []byte, offset int64) (int, error) {
if offset != r.offset {
return 0, fmt.Errorf("non-sequential read of stream")
}
n, err := io.ReadFull(r.rd, buf)
r.offset += int64(n)
return n, err
}

1112
vendor/github.com/ledongthuc/pdf/read.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

158
vendor/github.com/ledongthuc/pdf/text.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,158 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pdf
import (
"unicode"
"unicode/utf16"
)
const noRune = unicode.ReplacementChar
func isPDFDocEncoded(s string) bool {
if isUTF16(s) {
return false
}
for i := 0; i < len(s); i++ {
if pdfDocEncoding[s[i]] == noRune {
return false
}
}
return true
}
func pdfDocDecode(s string) string {
for i := 0; i < len(s); i++ {
if s[i] >= 0x80 || pdfDocEncoding[s[i]] != rune(s[i]) {
goto Decode
}
}
return s
Decode:
r := make([]rune, len(s))
for i := 0; i < len(s); i++ {
r[i] = pdfDocEncoding[s[i]]
}
return string(r)
}
func isUTF16(s string) bool {
return len(s) >= 2 && s[0] == 0xfe && s[1] == 0xff && len(s)%2 == 0
}
func utf16Decode(s string) string {
var u []uint16
for i := 0; i < len(s); i += 2 {
u = append(u, uint16(s[i])<<8|uint16(s[i+1]))
}
return string(utf16.Decode(u))
}
// See PDF 32000-1:2008, Table D.2
var pdfDocEncoding = [256]rune{
noRune, noRune, noRune, noRune, noRune, noRune, noRune, noRune,
noRune, 0x0009, 0x000a, noRune, noRune, 0x000d, noRune, noRune,
noRune, noRune, noRune, noRune, noRune, noRune, noRune, noRune,
0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, noRune,
0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044,
0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160,
0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, noRune,
0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, noRune, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
}
var winAnsiEncoding = [256]rune{
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
0x20ac, noRune, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, noRune, 0x017d, noRune,
noRune, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, noRune, 0x017e, 0x0178,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
}
var macRomanEncoding = [256]rune{
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1,
0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8,
0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3,
0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc,
0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df,
0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8,
0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211,
0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8,
0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab,
0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153,
0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca,
0x00ff, 0x0178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1,
0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4,
0xf8ff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc,
0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7,
}