blob: 24c49ff5588f2cd8601fc3433a914bf9e9328fa7 [file] [log] [blame]
// Copyright 2015 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.
//go:build ignore
// +build ignore
package main
// This code is shared between the main code generator and the test code.
import (
"flag"
"log"
"strconv"
"strings"
"golang.org/x/text/internal/gen"
"golang.org/x/text/internal/ucd"
)
var (
outputFile = flag.String("out", "tables.go", "output file")
)
var typeMap = map[string]elem{
"A": tagAmbiguous,
"N": tagNeutral,
"Na": tagNarrow,
"W": tagWide,
"F": tagFullwidth,
"H": tagHalfwidth,
}
// getWidthData calls f for every entry for which it is defined.
//
// f may be called multiple times for the same rune. The last call to f is the
// correct value. f is not called for all runes. The default tag type is
// Neutral.
func getWidthData(f func(r rune, tag elem, alt rune)) {
// Set the default values for Unified Ideographs. In line with Annex 11,
// we encode full ranges instead of the defined runes in Unified_Ideograph.
for _, b := range []struct{ lo, hi rune }{
{0x4E00, 0x9FFF}, // the CJK Unified Ideographs block,
{0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block,
{0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block,
{0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane,
{0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane,
} {
for r := b.lo; r <= b.hi; r++ {
f(r, tagWide, 0)
}
}
inverse := map[rune]rune{}
maps := map[string]bool{
"<wide>": true,
"<narrow>": true,
}
// We cannot reuse package norm's decomposition, as we need an unexpanded
// decomposition. We make use of the opportunity to verify that the
// decomposition type is as expected.
ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) {
r := p.Rune(0)
s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2)
if !maps[s[0]] {
return
}
x, err := strconv.ParseUint(s[1], 16, 32)
if err != nil {
log.Fatalf("Error parsing rune %q", s[1])
}
if inverse[r] != 0 || inverse[rune(x)] != 0 {
log.Fatalf("Circular dependency in mapping between %U and %U", r, x)
}
inverse[r] = rune(x)
inverse[rune(x)] = r
})
// <rune range>;<type>
ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) {
tag, ok := typeMap[p.String(1)]
if !ok {
log.Fatalf("Unknown width type %q", p.String(1))
}
r := p.Rune(0)
alt, ok := inverse[r]
if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign {
tag |= tagNeedsFold
if !ok {
log.Fatalf("Narrow or wide rune %U has no decomposition", r)
}
}
f(r, tag, alt)
})
}