Compare commits
1 Commits
master
...
karikera/p
Author | SHA1 | Date | |
---|---|---|---|
|
3d6bf311b8 |
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@ -1,3 +0,0 @@
|
||||
github: SheetJSDev
|
||||
custom: https://sheetjs.com
|
||||
open_collective: s5s
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
*.tgz
|
||||
codepages/
|
||||
.vocrc
|
||||
misc/coverage.html
|
||||
codepage_mini.md
|
||||
ctest/sauce*
|
@ -22,7 +22,6 @@ Wansung
|
||||
halfwidth
|
||||
|
||||
# Third-party
|
||||
ECMA-35
|
||||
FoxPro
|
||||
nodejs
|
||||
unicode.org
|
||||
|
31
Makefile
31
Makefile
@ -3,12 +3,8 @@ LIB=codepage
|
||||
VOC=voc
|
||||
TARGET=cptable.js
|
||||
AUXTARGETS=cputils.js cpexcel.js sbcs.js
|
||||
DISTFULL_A=cpexcel sbcs
|
||||
DISTFULL_B=cptable
|
||||
DISTFULL_M=cpexcel
|
||||
CMDS=
|
||||
#DISTBITS=iso2022.js
|
||||
DISTBITS=
|
||||
DISTFULL=cpexcel sbcs cptable
|
||||
CMDS=bin/codepage.njs
|
||||
|
||||
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
|
||||
FLOWTARGET=cptable.js
|
||||
@ -20,17 +16,14 @@ CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar
|
||||
all: voc ## Build library and auxiliary scripts
|
||||
|
||||
.PHONY: voc
|
||||
voc: codepage.md
|
||||
@make js
|
||||
#$(VOC) codepage.md
|
||||
voc test.js: codepage.md
|
||||
$(VOC) codepage.md
|
||||
|
||||
.PHONY: js
|
||||
js: make.sh codepage.md ## Build all output targets
|
||||
bash make.sh <(awk -F, '$$3=="1"' pages.csv) sbcs.js cptable
|
||||
bash make.sh excel.csv cpexcel.js cptable
|
||||
bash make.sh pages.csv cptable.js cptable
|
||||
bash make_esm.sh excel.csv cpexcel.mjs
|
||||
#node iso2022/make_iso2022.njs > iso2022.js
|
||||
bash make.sh
|
||||
make cputils.js
|
||||
|
||||
cputils.js: cputils.flow.js
|
||||
@ -38,20 +31,18 @@ cputils.js: cputils.flow.js
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Remove targets and build artifacts
|
||||
rm -f bits/*.js
|
||||
rm -f make.sh .vocrc pages.csv bits/*.js
|
||||
|
||||
.PHONY: dist
|
||||
dist: $(TARGET) $(AUXTARGETS) ## Copy files for distribution
|
||||
cp $(TARGET) $(AUXTARGETS) LICENSE dist/
|
||||
for i in $(DISTFULL_A); do cat $$i.js cputils.js | sed "s#require('./cptable')#cptable#" > dist/$$i.full.js; done
|
||||
for i in $(DISTFULL_B); do cat $$i.js $(DISTBITS) cputils.js | sed "s#require('./cptable')#cptable#" > dist/$$i.full.js; done
|
||||
for i in $(DISTFULL_M); do cat $$i.mjs cputils.mjs | sed "s#require('./cptable')#cptable#" > dist/$$i.full.mjs; done
|
||||
for i in $(DISTFULL); do cat $$i.js cputils.js | sed "s#require('./cptable')#cptable#" > dist/$$i.full.js; done
|
||||
|
||||
## Testing
|
||||
|
||||
.PHONY: test mocha
|
||||
test mocha: $(TARGET) baseline ## Run test suite
|
||||
./node_modules/.bin/mocha -R spec -t 20000
|
||||
test mocha: test.js $(TARGET) baseline ## Run test suite
|
||||
mocha -R spec -t 20000
|
||||
|
||||
.PHONY: ctest
|
||||
ctest: ## Build browser test (into ctest/ subdirectory)
|
||||
@ -59,7 +50,7 @@ ctest: ## Build browser test (into ctest/ subdirectory)
|
||||
|
||||
.PHONY: ctestserv
|
||||
ctestserv: ## Start a test server on port 8000
|
||||
@cd cteset && python -mSimpleHTTPServer || python3 -mhttp.server || npx -y http-server -p 8000 .
|
||||
@cd ctest && python -mSimpleHTTPServer
|
||||
|
||||
.PHONY: baseline
|
||||
baseline: ## Build test baselines
|
||||
@ -76,7 +67,7 @@ fullint: lint old-lint tslint flow mdlint ## Run all checks
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks
|
||||
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json
|
||||
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json
|
||||
if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
|
||||
|
||||
.PHONY: old-lint
|
||||
|
17
README.md
17
README.md
@ -26,7 +26,7 @@ Alternatively, use the full version in the dist folder:
|
||||
```
|
||||
|
||||
The complete set of codepages is large due to some Double Byte Character Set
|
||||
encodings. A much smaller file that only includes SBCS codepages is provided in
|
||||
encodings. A much smaller file that just includes SBCS codepages is provided in
|
||||
this repo (`sbcs.js`), as well as a file for other projects (`cpexcel.js`)
|
||||
|
||||
If you know which codepages you need, you can include individual scripts for
|
||||
@ -133,7 +133,7 @@ to produce a complete script like `cpexcel.full.js`.
|
||||
## Building the complete script
|
||||
|
||||
This script uses [voc](npm.im/voc). The script to build the codepage tables and
|
||||
the JS source is `codepage.md`, so building involves `voc codepage.md`.
|
||||
the JS source is `codepage.md`, so building is as simple as `voc codepage.md`.
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
@ -274,11 +274,11 @@ tables are not generated, there is no corresponding entry (they are "magic").
|
||||
| `29001` | Windows 7 | Europa 3 |
|
||||
| `38598` | Windows 7 | ISO 8859-8 Hebrew (ISO-Logical) |
|
||||
| `47451` | unicode.org | Atari ST/TT |
|
||||
| `50220` | magic | ISO 2022 JIS Japanese with no halfwidth Katakana |
|
||||
| `50221` | magic | ISO 2022 JIS Japanese with halfwidth Katakana |
|
||||
| `50222` | magic | ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)|
|
||||
| `50225` | magic | ISO 2022 Korean |
|
||||
| `50227` | magic | ISO 2022 Simplified Chinese |
|
||||
| `50220` | Windows 7 | ISO 2022 JIS Japanese with no halfwidth Katakana |
|
||||
| `50221` | Windows 7 | ISO 2022 JIS Japanese with halfwidth Katakana |
|
||||
| `50222` | Windows 7 | ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)|
|
||||
| `50225` | Windows 7 | ISO 2022 Korean |
|
||||
| `50227` | Windows 7 | ISO 2022 Simplified Chinese |
|
||||
| `51932` | Windows 7 | EUC Japanese |
|
||||
| `51936` | Windows 7 | EUC Simplified Chinese |
|
||||
| `51949` | Windows 7 | EUC Korean |
|
||||
@ -330,9 +330,6 @@ To update the browser artifacts, run `make ctest`.
|
||||
- [Windows Code Page Enumeration](http://msdn.microsoft.com/en-us/library/cc195051.aspx)
|
||||
- [Windows Code Page Identifiers](http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756.aspx)
|
||||
- [IBM Coded Character Sets](https://www-01.ibm.com/software/globalization/ccsid/ccsid_registered.html)
|
||||
- [ISO/IEC 2022 / ECMA-35](https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-035.pdf)
|
||||
- [International Register of Coded Character Sets To Be Used With Escape Sequences](https://www.itscj.ipsj.or.jp/itscj_english/iso-ir/ISO-IR.pdf)
|
||||
- [Japanese Character Encoding for Internet Messages](https://tools.ietf.org/html/rfc1468)
|
||||
|
||||
## License
|
||||
|
||||
|
98
bin/codepage.njs
Executable file
98
bin/codepage.njs
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env node
|
||||
/* js-codepage (C) 2014-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2 ft=javascript: */
|
||||
/* eslint-env node */
|
||||
var codepage = require('../');
|
||||
require('exit-on-epipe');
|
||||
var fs = require('fs'), program/*:any*/ = (require('commander')/*:any*/);
|
||||
program
|
||||
.version(codepage.version)
|
||||
.usage('[options] <file>')
|
||||
.option('-f, --from-code <code>', 'codepage of input (default 65001 utf8)')
|
||||
.option('-t, --to-code <code>', 'codepage of output (default 65001 utf8)')
|
||||
.option('-o, --output <file>', 'output file (<file>.<to> if specified)')
|
||||
.option('-B, --bom', 'write BOM (for unicode codepages)')
|
||||
.option('-F, --force', 'force writing to stdout for non-utf8 codepages')
|
||||
.option('-l, --list', 'List supported codepages');
|
||||
|
||||
program.on('--help', function() {
|
||||
console.log(' Codepage descriptions can be found in the README');
|
||||
console.log(' http://oss.sheetjs.com/js-codepage/README.md');
|
||||
console.log(' Support email: dev.codepage@sheetjs.com');
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
if(program.list) {
|
||||
var l/*:Array<number>*/ = [];
|
||||
Object.keys(codepage).forEach(function(x) { if(parseInt(x, 10) == +x) l.push(+x); });
|
||||
Object.keys(codepage.utils.magic).forEach(function(x) { if(parseInt(x, 10) == +x && +x != 16969) l.push(+x); });
|
||||
l.sort(function(a,b) { return a-b; }).forEach(function(x) { console.log(x); });
|
||||
process.exit();
|
||||
}
|
||||
|
||||
var fr = +program.fromCode || 65001;
|
||||
var to = +program.toCode || 65001;
|
||||
var f = program.args[0];
|
||||
var o = program.output;
|
||||
|
||||
if(!process.stdin.isTTY) f = f || "-";
|
||||
|
||||
if(f !== "-" && !fs.existsSync(f)) {
|
||||
console.error('codepage: must specify a filename');
|
||||
process.exit(13);
|
||||
}
|
||||
|
||||
function concat(func) {
|
||||
// $FlowIgnore
|
||||
var writable = require('stream').Writable();
|
||||
var buf = [];
|
||||
writable._write = function(chunk, e, cb) { buf.push(chunk); cb(); };
|
||||
writable._writev = function(chunks, cb) { chunks.forEach(function(c) { buf.push(c.chunk); cb(); }); };
|
||||
writable.on('finish', function() { func(Buffer.concat(buf)); });
|
||||
return writable;
|
||||
}
|
||||
|
||||
if(f === "-") process.stdin.pipe(concat(process_text));
|
||||
else process_text(fs.readFileSync(f));
|
||||
|
||||
function process_text(text/*:Buffer*/) {
|
||||
var dec/*:Buffer*/ = (codepage.utils.decode(fr, text)/*:any*/);
|
||||
|
||||
var bom/*:Array<Buffer>*/ = [];
|
||||
bom[1200] = new Buffer([0xFF, 0xFE]);
|
||||
bom[1201] = new Buffer([0xFE, 0xFF]);
|
||||
bom[12000] = new Buffer([0xFF, 0xFE, 0x00, 0x00]);
|
||||
bom[12001] = new Buffer([0x00, 0x00, 0xFE, 0xFF]);
|
||||
bom[16969] = new Buffer([0x69, 0x69]);
|
||||
bom[65000] = new Buffer([0x2B, 0x2F, 0x76, 0x2B]);
|
||||
bom[65001] = new Buffer([0xEF, 0xBB, 0xBF]);
|
||||
|
||||
var mybom = (program.bom && bom[to] ? bom[to] : "");
|
||||
var out/*:any*/ = to === 65001 ? dec.toString('utf8') : codepage.utils.encode(to, dec);
|
||||
|
||||
/* if output file is specified */
|
||||
if(o) writefile(o, out, mybom);
|
||||
/* utf8 -> print to stdout */
|
||||
else if(to === 65001) logit(out, mybom);
|
||||
/* stdout piped to process -> print */
|
||||
else if(!process.stdout.isTTY) logit(out, mybom);
|
||||
/* forced */
|
||||
else if(program.force) logit(out, mybom);
|
||||
/* input file specified -> write to file */
|
||||
else if(f !== "-") writefile(f + "." + to, out, mybom);
|
||||
else {
|
||||
console.error('codepage: use force (-F, --force) to print ' + to + ' codes');
|
||||
process.exit(14);
|
||||
}
|
||||
}
|
||||
|
||||
function logit(out/*:Buffer*/, bom) {
|
||||
process.stdout.write(bom);
|
||||
process.stdout.write(out);
|
||||
}
|
||||
|
||||
function writefile(o, out/*:Buffer*/, bom) {
|
||||
fs.writeFileSync(o, bom);
|
||||
fs.appendFileSync(o, out);
|
||||
}
|
671
codepage.md
671
codepage.md
@ -2,14 +2,78 @@
|
||||
|
||||
The fields of the `pages.csv` manifest are `codepage,url,bytes` (SBCS=1, DBCS=2)
|
||||
|
||||
```>pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
863,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP863.TXT,1
|
||||
864,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP864.TXT,1
|
||||
865,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP865.TXT,1
|
||||
866,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP866.TXT,1
|
||||
869,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP869.TXT,1
|
||||
874,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT,1
|
||||
875,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT,1
|
||||
932,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT,2
|
||||
936,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT,2
|
||||
949,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT,2
|
||||
950,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT,2
|
||||
1026,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT,1
|
||||
1250,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT,1
|
||||
1251,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT,1
|
||||
1252,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT,1
|
||||
1253,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT,1
|
||||
1254,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT,1
|
||||
1255,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT,1
|
||||
1256,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT,1
|
||||
1257,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT,1
|
||||
1258,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT,1
|
||||
47451,http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/ATARIST.TXT,1
|
||||
```
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private `0xF8FF` code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
MICSFT. Codepages are an absolute pain :/
|
||||
|
||||
```>pages.csv
|
||||
10000,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ROMAN.TXT,1
|
||||
10006,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/GREEK.TXT,1
|
||||
10007,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/CYRILLIC.TXT,1
|
||||
10029,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT,1
|
||||
10079,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ICELAND.TXT,1
|
||||
10081,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/TURKISH.TXT,1
|
||||
```
|
||||
|
||||
The numbering scheme for the `ISO-8859-X` series is `28590 + X`:
|
||||
|
||||
```>pages.csv
|
||||
28591,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT,1
|
||||
28592,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-2.TXT,1
|
||||
28593,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-3.TXT,1
|
||||
28594,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-4.TXT,1
|
||||
28595,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-5.TXT,1
|
||||
28596,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-6.TXT,1
|
||||
28597,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-7.TXT,1
|
||||
28598,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-8.TXT,1
|
||||
28599,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-9.TXT,1
|
||||
28600,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-10.TXT,1
|
||||
28601,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-11.TXT,1
|
||||
28603,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-13.TXT,1
|
||||
28604,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-14.TXT,1
|
||||
28605,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT,1
|
||||
28606,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-16.TXT,1
|
||||
```
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
@ -78,6 +142,11 @@ The following codepages are available in .NET on Windows:
|
||||
- 21866 Ukrainian (KOI8-U); Cyrillic (KOI8-U)
|
||||
- 29001 Europa 3
|
||||
- 38598 ISO 8859-8 Hebrew; Hebrew (ISO-Logical)
|
||||
- 50220 ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
|
||||
- 50221 ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS Allow 1 byte Kana)
|
||||
- 50222 ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS Allow 1 byte Kana - SO/SI)
|
||||
- 50225 ISO 2022 Korean
|
||||
- 50227 ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)
|
||||
- 51932 EUC Japanese
|
||||
- 51936 EUC Simplified Chinese; Chinese Simplified (EUC)
|
||||
- 51949 EUC Korean
|
||||
@ -94,11 +163,107 @@ The following codepages are available in .NET on Windows:
|
||||
- 57010 ISCII Gujarati
|
||||
- 57011 ISCII Punjabi
|
||||
|
||||
```>pages.csv
|
||||
708,,1
|
||||
720,,1
|
||||
808,,1
|
||||
858,,1
|
||||
870,,1
|
||||
872,,1
|
||||
1010,,1
|
||||
1047,,1
|
||||
1132,,1
|
||||
1140,,1
|
||||
1141,,1
|
||||
1142,,1
|
||||
1143,,1
|
||||
1144,,1
|
||||
1145,,1
|
||||
1146,,1
|
||||
1147,,1
|
||||
1148,,1
|
||||
1149,,1
|
||||
1361,,2
|
||||
10001,,2
|
||||
10002,,2
|
||||
10003,,2
|
||||
10004,,1
|
||||
10005,,1
|
||||
10008,,2
|
||||
10010,,1
|
||||
10017,,1
|
||||
10021,,1
|
||||
10082,,1
|
||||
20000,,2
|
||||
20001,,2
|
||||
20002,,2
|
||||
20003,,2
|
||||
20004,,2
|
||||
20005,,2
|
||||
20105,,1
|
||||
20106,,1
|
||||
20107,,1
|
||||
20108,,1
|
||||
20261,,2
|
||||
20269,,1
|
||||
20273,,1
|
||||
20277,,1
|
||||
20278,,1
|
||||
20280,,1
|
||||
20284,,1
|
||||
20285,,1
|
||||
20290,,1
|
||||
20297,,1
|
||||
20420,,1
|
||||
20423,,1
|
||||
20424,,1
|
||||
20833,,1
|
||||
20838,,1
|
||||
20866,,1
|
||||
20871,,1
|
||||
20880,,1
|
||||
20905,,1
|
||||
20924,,1
|
||||
20932,,2
|
||||
20936,,2
|
||||
20949,,2
|
||||
21025,,1
|
||||
21027,,1
|
||||
21866,,1
|
||||
29001,,1
|
||||
38598,,1
|
||||
50220,,2
|
||||
50221,,2
|
||||
50222,,2
|
||||
50225,,2
|
||||
50227,,2
|
||||
51932,,2
|
||||
51936,,2
|
||||
51949,,2
|
||||
52936,,2
|
||||
54936,,2
|
||||
57002,,2
|
||||
57003,,2
|
||||
57004,,2
|
||||
57005,,2
|
||||
57006,,2
|
||||
57007,,2
|
||||
57008,,2
|
||||
57009,,2
|
||||
57010,,2
|
||||
57011,,2
|
||||
```
|
||||
|
||||
The following codepages are dependencies for Visual FoxPro:
|
||||
|
||||
- 620 Mazovia (Polish) MS-DOS
|
||||
- 895 Kamenický (Czech) MS-DOS
|
||||
|
||||
```>pages.csv
|
||||
620,,1
|
||||
895,,1
|
||||
```
|
||||
|
||||
## Building Notes
|
||||
|
||||
The script `make.sh` (described later) will get these files and massage the data
|
||||
@ -124,7 +289,13 @@ which implies that code `0xF6` is `String.fromCharCode(0x02C6)` and vice versa.
|
||||
|
||||
To build the sources on windows, consult `dotnet/MakeEncoding.cs`.
|
||||
|
||||
After saving standard output to `out`, the `dotnet.sh` script processes results.
|
||||
After saving the standard output to `out`, a simple script processes the result:
|
||||
|
||||
```>dotnet.sh
|
||||
#!/bin/bash
|
||||
if [ ! -e dotnet/out ]; then exit; fi
|
||||
<dotnet/out tr -s ' ' '\t' | awk 'NF>2 {if(outfile) close(outfile); outfile="codepages/" $1 ".TBL"} NF==2 {print > outfile}'
|
||||
```
|
||||
|
||||
# Building the script
|
||||
|
||||
@ -133,9 +304,43 @@ generates JS code for encoding and decoding:
|
||||
|
||||
## Raw Codepages
|
||||
|
||||
```>make.njs
|
||||
#!/usr/bin/env node
|
||||
var argv = process.argv.slice(1), fs = require('fs');
|
||||
if(argv.length < 2) {
|
||||
console.error("usage: make.njs <codepage_index> [variable]");
|
||||
process.exit(22); /* EINVAL */
|
||||
}
|
||||
|
||||
var cp/*:string*/ = argv[1];
|
||||
var jsvar/*:string*/ = argv[2] || "cptable";
|
||||
var x/*:string*/ = fs.readFileSync("codepages/" + cp + ".TBL","utf8");
|
||||
var maxcp = 0, i = 0, ii = 0;
|
||||
|
||||
var y/*:Array<Array<number> >*/ = x.split("\n").map(function(z/*:string*/)/*:Array<number>*/ {
|
||||
var w/*:Array<string>*/ = z.split("\t");
|
||||
if(w.length < 2) return [Number(w[0])];
|
||||
return [Number(w[0]), Number(w[1])];
|
||||
}).filter(function(z) { return z.length > 1; });
|
||||
```
|
||||
|
||||
The DBCS and SBCS code generation strategies are different. The maximum code is
|
||||
used to distinguish (max `0xFF` for SBCS).
|
||||
|
||||
```
|
||||
for(i = 0; i != y.length; ++i) if(y[i][0] > maxcp) maxcp = y[i][0];
|
||||
|
||||
var enc/*:{[key:string]:number}*/ = {}, dec/*:{[key:string]:string}|Array<string>*/ = (maxcp < 256 ? [] : {});
|
||||
for(i = 0; i != y.length; ++i) {
|
||||
/*:: if(Array.isArray(dec)) */ dec[y[i][0]] = String.fromCharCode(y[i][1]);
|
||||
enc[String.fromCharCode(y[i][1])] = y[i][0];
|
||||
}
|
||||
|
||||
var odec = "", outstr = "";
|
||||
if(maxcp < 256) {
|
||||
/*:: if(Array.isArray(dec)) { */
|
||||
```
|
||||
|
||||
The Unicode character `0xFFFD` (REPLACEMENT CHARACTER) is used as a placeholder
|
||||
for characters that are not specified in the map (for example, `0xF0` is not in
|
||||
code page 10000).
|
||||
@ -143,6 +348,14 @@ code page 10000).
|
||||
For SBCS, the idea is to embed a raw string with the contents of the 256 codes.
|
||||
The `dec` field is merely a split of the string, and `enc` is an eversion:
|
||||
|
||||
```
|
||||
for(i = 0; i != 256; ++i) if(typeof dec[i] === "undefined") dec[i] = String.fromCharCode(0xFFFD);
|
||||
odec = JSON.stringify(dec.join(""));
|
||||
outstr = '(function(){ var d = ' + odec + ', D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();';
|
||||
/*:: } */
|
||||
} else {
|
||||
```
|
||||
|
||||
DBCS is similar, except that the space is sliced in chunks of 256 bytes (strings
|
||||
are only generated for those high-bytes represented in the codepage).
|
||||
|
||||
@ -150,6 +363,27 @@ The strategy is to construct an array-of-arrays so that `dd[high][low]` is the
|
||||
character associated with the code. This array is combined at runtime to yield
|
||||
the complete decoding object (and the encoding object is an eversion):
|
||||
|
||||
```
|
||||
var dd = [];
|
||||
/*:: if(!Array.isArray(dec)) { */
|
||||
for(i in dec) if(dec.hasOwnProperty(i)) {
|
||||
ii = +i;
|
||||
if(typeof dd[ii >> 8] === "undefined") dd[ii >> 8] = [];
|
||||
dd[ii >> 8][ii % 256] = dec[i];
|
||||
}
|
||||
/*:: } */
|
||||
outstr = '(function(){ var d = [], e = {}, D = [], j;\n';
|
||||
for(var i = 0; i != 256; ++i) if(dd[i]) {
|
||||
for(var j = 0; j != 256; ++j) if(typeof dd[i][j] === "undefined") dd[i][j] = String.fromCharCode(0xFFFD);
|
||||
outstr += 'D[' + i + '] = ' + JSON.stringify(dd[i].join("")) + '.split("");\n';
|
||||
outstr += 'for(j = 0; j != D[' + i + '].length; ++j) if(D[' + i + '][j].charCodeAt(0) !== 0xFFFD) { e[D[' + i + '][j]] = ' + (i*256) + ' + j; d[' + (i*256) + ' + j] = D[' + i + '][j];}\n'
|
||||
}
|
||||
outstr += 'return {"enc": e, "dec": d }; })();';
|
||||
}
|
||||
process.stdout.write(jsvar + "[" + cp + "] = " + outstr + "\n");
|
||||
|
||||
```
|
||||
|
||||
`make.sh` generates the tables used by `make.njs`. The raw Unicode TXT files
|
||||
are columnar: `code unicode #comments`. For example, the last 10 lines of the
|
||||
text file `ROMAN.TXT` (for CP 10000) are:
|
||||
@ -170,6 +404,35 @@ text file `ROMAN.TXT` (for CP 10000) are:
|
||||
In processing the data, the comments (after the `#`) are stripped and undefined
|
||||
elements (like `0x7F` for CP 10000) are removed.
|
||||
|
||||
```>make.sh
|
||||
#!/bin/bash
|
||||
INFILE=${1:-pages.csv}
|
||||
OUTFILE=${2:-cptable.js}
|
||||
JSVAR=${3:-cptable}
|
||||
VERSION=$(cat package.json | grep version | tr -dc [0-9.])
|
||||
|
||||
mkdir -p codepages bits
|
||||
rm -f $OUTFILE $OUTFILE.tmp
|
||||
echo "/* $OUTFILE (C) 2013-present SheetJS -- http://sheetjs.com */" > $OUTFILE.tmp
|
||||
echo "/*jshint -W100 */" >> $OUTFILE.tmp
|
||||
echo "var $JSVAR = {version:\"$VERSION\"};" >> $OUTFILE.tmp
|
||||
if [ -e dotnet.sh ]; then bash dotnet.sh; fi
|
||||
awk -F, '{print $1, $2, $3}' $INFILE | while read cp url cptype; do
|
||||
echo $cp $url
|
||||
if [ ! -e codepages/$cp.TBL ]; then
|
||||
curl $url | sed 's/#.*//g' | awk 'NF==2' > codepages/$cp.TBL
|
||||
fi
|
||||
echo "if(typeof $JSVAR === 'undefined') $JSVAR = {};" > bits/$cp.js.tmp
|
||||
node make.njs $cp $JSVAR | tee -a bits/$cp.js.tmp >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <bits/$cp.js.tmp >bits/$cp.js
|
||||
rm -f bits/$cp.js.tmp
|
||||
done
|
||||
echo "// eslint-disable-next-line no-undef" >> $OUTFILE.tmp
|
||||
echo "if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = $JSVAR;" >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <$OUTFILE.tmp >$OUTFILE
|
||||
rm -f $OUTFILE.tmp
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
The encode and decode functions are kept in a separate script (`cputils.js`).
|
||||
@ -183,8 +446,412 @@ Both encode and decode deal with data represented as:
|
||||
The `ofmt` variable controls `encode` output (`str`, `arr` respectively)
|
||||
while the input format is automatically determined.
|
||||
|
||||
# Tests
|
||||
|
||||
```>test.js
|
||||
var fs = require('fs'), assert = require('assert'), vm = require('vm');
|
||||
var cptable, sbcs;
|
||||
|
||||
```
|
||||
|
||||
Due to a bug in `Buffer.from` in node `4.0 - 4.4`, a special check is needed:
|
||||
|
||||
```>test.js
|
||||
var Buffer_from = function(){};
|
||||
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The tests include JS validity tests (requiring or evaluating code):
|
||||
|
||||
```>test.js
|
||||
describe('source', function() {
|
||||
it('should load node', function() { cptable = require('./'); });
|
||||
it('should load sbcs', function() { sbcs = require('./sbcs'); });
|
||||
it('should load excel', function() { excel = require('./cpexcel'); });
|
||||
it('should process bits', function() {
|
||||
var files = fs.readdirSync('bits').filter(function(x){return x.substr(-3)==".js";});
|
||||
files.forEach(function(x) {
|
||||
vm.runInThisContext(fs.readFileSync('./bits/' + x));
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The README tests verify the snippets in the README:
|
||||
|
||||
```>test.js
|
||||
describe('README', function() {
|
||||
var readme = function() {
|
||||
var unicode_cp10000_255 = cptable[10000].dec[255]; // ˇ
|
||||
assert.equal(unicode_cp10000_255, "ˇ");
|
||||
|
||||
var cp10000_711 = cptable[10000].enc[String.fromCharCode(711)]; // 255
|
||||
assert.equal(cp10000_711, 255);
|
||||
|
||||
var b1 = [0xbb,0xe3,0xd7,0xdc];
|
||||
var s1 = b1.map(function(x) { return String.fromCharCode(x); }).join("");
|
||||
var 汇总 = cptable.utils.decode(936, b1);
|
||||
var buf = cptable.utils.encode(936, 汇总);
|
||||
assert.equal(汇总,"汇总");
|
||||
assert.equal(buf.length, 4);
|
||||
for(var i = 0; i != 4; ++i) assert.equal(b1[i], buf[i]);
|
||||
|
||||
var b2 = [0xf0,0x9f,0x8d,0xa3];
|
||||
var sushi= cptable.utils.decode(65001, b2);
|
||||
var sbuf = cptable.utils.encode(65001, sushi);
|
||||
assert.equal(sushi,"🍣");
|
||||
assert.equal(sbuf.length, 4);
|
||||
for(var i = 0; i != 4; ++i) assert.equal(b2[i], sbuf[i]);
|
||||
|
||||
};
|
||||
it('should be correct', function() {
|
||||
cptable.utils.cache.encache();
|
||||
readme();
|
||||
cptable.utils.cache.decache();
|
||||
readme();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The consistency tests make sure that encoding and decoding are pseudo inverses:
|
||||
|
||||
```>test.js
|
||||
describe('consistency', function() {
|
||||
cptable = require('./');
|
||||
U = cptable.utils;
|
||||
var chk = function(cptable, cacheit) { return function(x) {
|
||||
it('should consistently process CP ' + x, function() {
|
||||
var cp = cptable[x], D = cp.dec, E = cp.enc;
|
||||
if(cacheit) cptable.utils.cache.encache();
|
||||
else cptable.utils.cache.decache();
|
||||
Object.keys(D).forEach(function(d) {
|
||||
if(E[D[d]] != d) {
|
||||
if(typeof E[D[d]] !== "undefined") return;
|
||||
if(D[d].charCodeAt(0) == 0xFFFD) return;
|
||||
if(D[E[D[d]]] === D[d]) return;
|
||||
throw new Error(x + " e.d[" + d + "] = " + E[D[d]] + "; d[" + d + "]=" + D[d] + "; d.e.d[" + d + "] = " + D[E[D[d]]]);
|
||||
}
|
||||
});
|
||||
Object.keys(E).forEach(function(e) {
|
||||
if(D[E[e]] != e) {
|
||||
throw new Error(x + " d.e[" + e + "] = " + D[E[e]] + "; e[" + e + "]=" + E[e] + "; e.d.e[" + e + "] = " + E[D[E[e]]]);
|
||||
}
|
||||
});
|
||||
var corpus = ["foobar"];
|
||||
corpus.forEach(function(w){
|
||||
assert.equal(U.decode(x,U.encode(x,w)),w);
|
||||
});
|
||||
cptable.utils.cache.encache();
|
||||
});
|
||||
}; };
|
||||
describe('cached', function() {
|
||||
Object.keys(cptable).filter(function(w) { return w == +w; }).forEach(chk(cptable, true));
|
||||
});
|
||||
describe('direct', function() {
|
||||
Object.keys(cptable).filter(function(w) { return w == +w; }).forEach(chk(cptable, false));
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The next tests look at possible entry conditions:
|
||||
|
||||
```
|
||||
describe('entry conditions', function() {
|
||||
it('should fail to load utils if cptable unavailable', function() {
|
||||
var sandbox = {};
|
||||
var ctx = vm.createContext(sandbox);
|
||||
assert.throws(function() {
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx);
|
||||
});
|
||||
});
|
||||
it('should load utils if cptable is available', function() {
|
||||
var sandbox = {};
|
||||
var ctx = vm.createContext(sandbox);
|
||||
vm.runInContext(fs.readFileSync('cpexcel.js','utf8'),ctx);
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx);
|
||||
});
|
||||
var chken = function(cp, i) {
|
||||
var c = function(cp, i, e) {
|
||||
var str = cptable.utils.encode(cp,i,e);
|
||||
var arr = cptable.utils.encode(cp,i.split(""),e);
|
||||
assert.deepEqual(str,arr);
|
||||
if(typeof Buffer === 'undefined') return;
|
||||
var buf = cptable.utils.encode(cp,Buffer_from(i),e);
|
||||
assert.deepEqual(str,buf);
|
||||
};
|
||||
cptable.utils.cache.encache();
|
||||
c(cp,i);
|
||||
c(cp,i,'buf');
|
||||
c(cp,i,'arr');
|
||||
c(cp,i,'str');
|
||||
cptable.utils.cache.decache();
|
||||
c(cp,i);
|
||||
c(cp,i,'buf');
|
||||
c(cp,i,'arr');
|
||||
c(cp,i,'str');
|
||||
};
|
||||
describe('encode', function() {
|
||||
it('CP 1252 : sbcs', function() { chken(1252,"foo•bþr"); });
|
||||
it('CP 708 : sbcs', function() { chken(708,"ت and ث smiley faces");});
|
||||
it('CP 936 : dbcs', function() { chken(936, "这是中文字符测试");});
|
||||
});
|
||||
var chkde = function(cp, i) {
|
||||
var c = function(cp, i) {
|
||||
var s;
|
||||
if(typeof Buffer !== 'undefined' && i instanceof Buffer) s = [].map.call(i, function(s){return String.fromCharCode(s); });
|
||||
else s=(i.map) ? i.map(function(s){return String.fromCharCode(s); }) : i;
|
||||
var str = cptable.utils.decode(cp,i);
|
||||
var arr = cptable.utils.decode(cp,s.join?s.join(""):s);
|
||||
assert.deepEqual(str,arr);
|
||||
if(typeof Buffer === 'undefined') return;
|
||||
var buf = cptable.utils.decode(cp,Buffer_from(i));
|
||||
assert.deepEqual(str,buf);
|
||||
};
|
||||
cptable.utils.cache.encache();
|
||||
c(cp,i);
|
||||
cptable.utils.cache.decache();
|
||||
c(cp,i);
|
||||
};
|
||||
describe('decode', function() {
|
||||
it('CP 1252 : sbcs', function() { chkde(1252,[0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]); }); /* "foobar" */
|
||||
if(typeof Buffer !== 'undefined') it('CP 708 : sbcs', function() { chkde(708, Buffer_from([0xca, 0x20, 0x61, 0x6e, 0x64, 0x20, 0xcb, 0x20, 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x79, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73])); }); /* ("ت and ث smiley faces") */
|
||||
it('CP 936 : dbcs', function() { chkde(936, [0xd5, 0xe2, 0xca, 0xc7, 0xd6, 0xd0, 0xce, 0xc4, 0xd7, 0xd6, 0xb7, 0xfb, 0xb2, 0xe2, 0xca, 0xd4]);}); /* "这是中文字符测试" */
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `testfile` helper function reads a file and compares to node's read facilities:
|
||||
|
||||
```>test.js
|
||||
function testfile(f,cp,type,skip) {
|
||||
var d = fs.readFileSync(f);
|
||||
var x = fs.readFileSync(f, type);
|
||||
var a = x.split("");
|
||||
var chk = function(cp) {
|
||||
var y = cptable.utils.decode(cp, d);
|
||||
assert.equal(x,y);
|
||||
var z = cptable.utils.encode(cp, x);
|
||||
if(z.length != d.length) throw new Error(f + " " + JSON.stringify(z) + " != " + JSON.stringify(d) + " : " + z.length + " " + d.length);
|
||||
for(var i = 0; i != d.length; ++i) if(d[i] !== z[i]) throw new Error("" + i + " " + d[i] + "!=" + z[i]);
|
||||
if(skip) return;
|
||||
z = cptable.utils.encode(cp, a);
|
||||
if(z.length != d.length) throw new Error(f + " " + JSON.stringify(z) + " != " + JSON.stringify(d) + " : " + z.length + " " + d.length);
|
||||
for(var i = 0; i != d.length; ++i) if(d[i] !== z[i]) throw new Error("" + i + " " + d[i] + "!=" + z[i]);
|
||||
if(f.indexOf("cptable.js") == -1) {
|
||||
cptable.utils.encode(cp, d, 'str');
|
||||
cptable.utils.encode(cp, d, 'arr');
|
||||
}
|
||||
}
|
||||
cptable.utils.cache.encache();
|
||||
chk(cp);
|
||||
if(skip) return;
|
||||
cptable.utils.cache.decache();
|
||||
chk(cp);
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
```
|
||||
|
||||
The `utf8` tests verify UTF-8 encoding of the actual JS sources:
|
||||
|
||||
```>test.js
|
||||
describe('node natives', function() {
|
||||
var node = [[65001, 'utf8',1], [1200, 'utf16le',1], [20127, 'ascii',0]];
|
||||
var unicodefiles = ['codepage.md','README.md','cptable.js'];
|
||||
var asciifiles = ['cputils.js'];
|
||||
node.forEach(function(w) {
|
||||
describe(w[1], function() {
|
||||
cptable = require('./');
|
||||
asciifiles.forEach(function(f) {
|
||||
it('should process ' + f, function() { testfile('./misc/'+f+'.'+w[1],w[0],w[1]); });
|
||||
});
|
||||
if(!w[2]) return;
|
||||
unicodefiles.forEach(function(f) {
|
||||
it('should process ' + f, function() { testfile('./misc/'+f+'.'+w[1],w[0],w[1]); });
|
||||
});
|
||||
if(w[1] === 'utf8') it('should process bits', function() {
|
||||
var files = fs.readdirSync('bits').filter(function(x){return x.substr(-3)==".js";});
|
||||
files.forEach(function(f) { testfile('./bits/' + f,w[0],w[1],true); });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `utf*` and `ascii` tests attempt to test other magic formats:
|
||||
|
||||
```>test.js
|
||||
var m = cptable.utils.magic;
|
||||
function cmp(x,z) {
|
||||
assert.equal(x.length, z.length);
|
||||
for(var i = 0; i != z.length; ++i) assert.equal(i+"/"+x.length+""+x[i], i+"/"+z.length+""+z[i]);
|
||||
}
|
||||
Object.keys(m).forEach(function(t){if(t != 16969) describe(m[t], function() {
|
||||
it("should process codepage.md." + m[t], fs.existsSync('./misc/codepage.md.' + m[t]) ?
|
||||
function() {
|
||||
var b = fs.readFileSync('./misc/codepage.md.utf8', "utf8");
|
||||
if(m[t] === "ascii") b = b.replace(/[\u0080-\uffff]*/g,"");
|
||||
var x = fs.readFileSync('./misc/codepage.md.' + m[t]);
|
||||
var y, z;
|
||||
cptable.utils.cache.encache();
|
||||
y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
z = cptable.utils.encode(t, y);
|
||||
if(t != 65000) cmp(x,z);
|
||||
else { assert.equal(y, cptable.utils.decode(t, z)); }
|
||||
cptable.utils.cache.decache();
|
||||
y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
z = cptable.utils.encode(t, y);
|
||||
if(t != 65000) cmp(x,z);
|
||||
else { assert.equal(y, cptable.utils.decode(t, z)); }
|
||||
cptable.utils.cache.encache();
|
||||
cptable.utils.encode(t, y, 'str');
|
||||
cptable.utils.encode(t, y, 'arr');
|
||||
cptable.utils.cache.decache();
|
||||
cptable.utils.encode(t, y, 'str');
|
||||
cptable.utils.encode(t, y, 'arr');
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
: null);
|
||||
it("should process README.md." + m[t], fs.existsSync('./misc/README.md.' + m[t]) ?
|
||||
function() {
|
||||
var b = fs.readFileSync('./misc/README.md.utf8', "utf8");
|
||||
if(m[t] === "ascii") b = b.replace(/[\u0080-\uffff]*/g,"");
|
||||
var x = fs.readFileSync('./misc/README.md.' + m[t]);
|
||||
x = [].slice.call(x);
|
||||
cptable.utils.cache.encache();
|
||||
var y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
cptable.utils.cache.decache();
|
||||
var y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
: null);
|
||||
});});
|
||||
```
|
||||
|
||||
The codepage `6969` is not defined, so operations should fail:
|
||||
|
||||
```>test.js
|
||||
describe('failures', function() {
|
||||
it('should fail to find CP 6969', function() {
|
||||
assert.throws(function(){cptable[6969].dec});
|
||||
assert.throws(function(){cptable[6969].enc});
|
||||
});
|
||||
it('should fail using utils', function() {
|
||||
assert(!cptable.utils.hascp(6969));
|
||||
assert.throws(function(){return cptable.utils.encode(6969, "foobar"); });
|
||||
assert.throws(function(){return cptable.utils.decode(6969, [0x20]); });
|
||||
});
|
||||
it('should fail with black magic', function() {
|
||||
assert(cptable.utils.hascp(16969));
|
||||
assert.throws(function(){return cptable.utils.encode(16969, "foobar"); });
|
||||
assert.throws(function(){return cptable.utils.decode(16969, [0x20]); });
|
||||
});
|
||||
it('should fail when presented with invalid char codes', function() {
|
||||
assert.throws(function(){cptable.utils.cache.decache(); return cptable.utils.encode(20127, [String.fromCharCode(0xAA)]);});
|
||||
});
|
||||
it('should fail to propagate UTF8 BOM in UTF7', function() {
|
||||
["+/v8-abc", "+/v9"].forEach(function(m) { assert.throws(function() {
|
||||
assert.equal(m, cptable.utils.encode(65000, cptable.utils.decode(65000, m)));
|
||||
}); });
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
# Nitty Gritty
|
||||
|
||||
```json>package.json
|
||||
{
|
||||
"name": "codepage",
|
||||
"version": "1.14.0",
|
||||
"author": "SheetJS",
|
||||
"description": "pure-JS library to handle codepages",
|
||||
"keywords": [ "codepage", "iconv", "convert", "strings" ],
|
||||
"bin": {
|
||||
"codepage": "./bin/codepage.njs"
|
||||
},
|
||||
"main": "cputils.js",
|
||||
"types": "types",
|
||||
"browser": {
|
||||
"buffer": "false"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "~2.14.1",
|
||||
"exit-on-epipe": "~1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"voc": "~1.1.0",
|
||||
"mocha": "~2.5.3",
|
||||
"blanket": "~1.2.3",
|
||||
"@sheetjs/uglify-js": "~2.7.3",
|
||||
"@types/node": "^8.0.7",
|
||||
"@types/commander": "^2.12.0",
|
||||
"dtslint": "^0.1.2",
|
||||
"typescript": "2.2.0"
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-codepage.git"},
|
||||
"scripts": {
|
||||
"pretest": "git submodule init && git submodule update",
|
||||
"test": "make test",
|
||||
"build": "make js",
|
||||
"lint": "make fullint",
|
||||
"dtslint": "dtslint types"
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
"pattern": "[cputils.js]"
|
||||
}
|
||||
},
|
||||
"alex": {
|
||||
"allow": [
|
||||
"chinese",
|
||||
"european",
|
||||
"german",
|
||||
"japanese",
|
||||
"latin"
|
||||
]
|
||||
},
|
||||
"homepage": "http://sheetjs.com/opensource",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"bin",
|
||||
"bits/*.js",
|
||||
"types/index.d.ts",
|
||||
"types/*.json",
|
||||
"cptable.js",
|
||||
"cputils.js",
|
||||
"dist/sbcs.full.js",
|
||||
"dist/cpexcel.full.js"
|
||||
],
|
||||
"bugs": { "url": "https://github.com/SheetJS/js-codepage/issues" },
|
||||
"license": "Apache-2.0",
|
||||
"engines": { "node": ">=0.8" }
|
||||
}
|
||||
```
|
||||
|
||||
```>.vocrc
|
||||
{ "post": "make js" }
|
||||
```
|
||||
|
||||
```>.gitignore
|
||||
node_modules
|
||||
package-lock.json
|
||||
*.tgz
|
||||
.gitignore
|
||||
codepages/
|
||||
.vocrc
|
||||
make.sh
|
||||
make.njs
|
||||
misc/coverage.html
|
||||
codepage_mini.md
|
||||
ctest/sauce*
|
||||
```
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*! cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W100 */
|
||||
var cptable = {version:"1.15.0"};
|
||||
var cptable = {version:"1.14.0"};
|
||||
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖÜ¢Ł¥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
@ -973,6 +973,5 @@ return {"enc": e, "dec": d }; })();
|
||||
cptable[10029] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[10079] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[10081] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙ<C39B>ˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[28591] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~
¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = cptable;
|
||||
|
1700
cptable.js
1700
cptable.js
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
/*::
|
||||
@ -257,10 +257,7 @@ type DecoderMap = {[id:CPIndex]:Decoder};
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
@ -246,10 +246,7 @@
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
524
cputils.mjs
524
cputils.mjs
@ -1,524 +0,0 @@
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
var cpt = cptable;
|
||||
/*global module, Buffer */
|
||||
var magic/*:{[id:CPIndex]:string}*/ = {
|
||||
"1200":"utf16le",
|
||||
"1201":"utf16be",
|
||||
"12000":"utf32le",
|
||||
"12001":"utf32be",
|
||||
"16969":"utf64le",
|
||||
"20127":"ascii",
|
||||
"65000":"utf7",
|
||||
"65001":"utf8"
|
||||
};
|
||||
|
||||
var sbcs_cache/*:Array<number>*/ = [874,1250,1251,1252,1253,1254,1255,1256,10000];
|
||||
var dbcs_cache/*:Array<number>*/ = [932,936,949,950];
|
||||
var magic_cache/*:Array<number>*/ = [65001];
|
||||
var magic_decode/*:DecoderMap*/ = {};
|
||||
var magic_encode/*:EncoderMap*/ = {};
|
||||
var cpdcache/*:DecoderMap*/ = {};
|
||||
var cpecache/*:EncoderMap*/ = {};
|
||||
|
||||
var sfcc = function sfcc(x/*:number*/)/*:string*/ { return String.fromCharCode(x); };
|
||||
var cca = function cca(x/*:string*/)/*:number*/ { return x.charCodeAt(0); };
|
||||
|
||||
var has_buf/*:boolean*/ = (typeof Buffer !== 'undefined');
|
||||
var Buffer_from = function(){};
|
||||
if(has_buf) {
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
// $FlowIgnore
|
||||
if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); };
|
||||
|
||||
var mdl = 1024, mdb = Buffer.allocUnsafe(mdl);
|
||||
var make_EE = function make_EE(E/*:EMap*/)/*:Buffer*/{
|
||||
var EE = Buffer.allocUnsafe(65536);
|
||||
for(var i = 0; i < 65536;++i) EE[i] = 0;
|
||||
var keys/*:Array<string>*/ = Object.keys(E), len = keys.length;
|
||||
for(var ee = 0, e = keys[ee]; ee < len; ++ee) {
|
||||
if(!(e = keys[ee])) continue;
|
||||
EE[e.charCodeAt(0)] = E[e];
|
||||
}
|
||||
return EE;
|
||||
};
|
||||
var sbcs_encode = function make_sbcs_encode(cp/*:CPIndex*/)/*:Encoder*/ {
|
||||
var EE/*:Buffer*/ = make_EE(cpt[cp].enc);
|
||||
return function sbcs_e(data/*:StrData*/, ofmt/*:?string*/) {
|
||||
var len = data.length;
|
||||
var out/*:Buffer*/, i=0, j=0, D=0, w=0;
|
||||
if(typeof data === 'string') {
|
||||
out = Buffer.allocUnsafe(len);
|
||||
for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)];
|
||||
} else if(/*:: data instanceof Buffer && */Buffer.isBuffer(data)) {
|
||||
out = Buffer.allocUnsafe(2*len);
|
||||
j = 0;
|
||||
for(i = 0; i < len; ++i) {
|
||||
D = data[i];
|
||||
if(D < 128) out[j++] = EE[D];
|
||||
else if(D < 224) { out[j++] = EE[((D&31)<<6)+(data[i+1]&63)]; ++i; }
|
||||
else if(D < 240) { out[j++] = EE[((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63)]; i+=2; }
|
||||
else {
|
||||
w = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3;
|
||||
if(w < 65536) out[j++] = EE[w];
|
||||
else { w -= 65536; out[j++] = EE[0xD800 + ((w>>10)&1023)]; out[j++] = EE[0xDC00 + (w&1023)]; }
|
||||
}
|
||||
}
|
||||
out = out.slice(0,j);
|
||||
} else {
|
||||
out = Buffer.allocUnsafe(len);
|
||||
for(i = 0; i < len; ++i) out[i] = EE[/*::(*/data[i]/*:: :any)*/.charCodeAt(0)];
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return out;
|
||||
if(ofmt !== 'arr') return out.toString('binary');
|
||||
return [].slice.call(out);
|
||||
};
|
||||
};
|
||||
var sbcs_decode = function make_sbcs_decode(cp/*:CPIndex*/)/*:Decoder*/ {
|
||||
var D/*:DMap*/ = cpt[cp].dec;
|
||||
var DD = Buffer.allocUnsafe(131072), d=0, c="";
|
||||
for(d=0;d<D.length;++d) {
|
||||
if(!(c=D[d])) continue;
|
||||
var w = c.charCodeAt(0);
|
||||
DD[2*d] = w&255; DD[2*d+1] = w>>8;
|
||||
}
|
||||
return function sbcs_d(data/*:Data*/)/*:string*/ {
|
||||
var len = data.length, i=0, j=0;
|
||||
if(2 * len > mdl) { mdl = 2 * len; mdb = Buffer.allocUnsafe(mdl); }
|
||||
if(/*::data instanceof Buffer && */Buffer.isBuffer(data)) {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
||||
}
|
||||
} else if(typeof data === "string") {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data.charCodeAt(i);
|
||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
||||
}
|
||||
}
|
||||
return mdb.slice(0, 2 * len).toString('ucs2');
|
||||
};
|
||||
};
|
||||
var dbcs_encode = function make_dbcs_encode(cp/*:CPIndex*/)/*:Encoder*/ {
|
||||
var E/*:EMap*/ = cpt[cp].enc;
|
||||
var EE = Buffer.allocUnsafe(131072);
|
||||
for(var i = 0; i < 131072; ++i) EE[i] = 0;
|
||||
var keys = Object.keys(E);
|
||||
for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) {
|
||||
if(!(e = keys[ee])) continue;
|
||||
var f = e.charCodeAt(0);
|
||||
EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8;
|
||||
}
|
||||
return function dbcs_e(data/*:StrData*/, ofmt/*:?string*/)/*:any*/ {
|
||||
var len = data.length, out = Buffer.allocUnsafe(2*len), i=0, j=0, jj=0, k=0, D=0;
|
||||
if(typeof data === 'string') {
|
||||
for(i = k = 0; i < len; ++i) {
|
||||
j = data.charCodeAt(i)*2;
|
||||
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
}
|
||||
out = out.slice(0,k);
|
||||
} else if(/*::data instanceof Buffer && */Buffer.isBuffer(data)) {
|
||||
for(i = k = 0; i < len; ++i) {
|
||||
D = data[i];
|
||||
if(D < 128) j = D;
|
||||
else if(D < 224) { j = ((D&31)<<6)+(data[i+1]&63); ++i; }
|
||||
else if(D < 240) { j = ((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63); i+=2; }
|
||||
else { j = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3; }
|
||||
if(j<65536) { j*=2; out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j]; }
|
||||
else { jj = j-65536;
|
||||
j=2*(0xD800 + ((jj>>10)&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
j=2*(0xDC00 + (jj&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
}
|
||||
}
|
||||
out = out.slice(0,k);
|
||||
} else {
|
||||
for(i = k = 0; i < len; i++) {
|
||||
j = /*::(*/data[i]/*:: :any)*/.charCodeAt(0)*2;
|
||||
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return out;
|
||||
if(ofmt !== 'arr') return out.toString('binary');
|
||||
return [].slice.call(out);
|
||||
};
|
||||
};
|
||||
var dbcs_decode = function make_dbcs_decode(cp/*:CPIndex*/)/*:Decoder*/ {
|
||||
var D/*:DMap*/ = cpt[cp].dec;
|
||||
var DD = Buffer.allocUnsafe(131072), d=0, c, w=0, j=0, i=0;
|
||||
for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;}
|
||||
for(d = 0; d < D.length; ++d) {
|
||||
if(!(c=D[d])) continue;
|
||||
w = c.charCodeAt(0);
|
||||
j = 2*d;
|
||||
DD[j] = w&255; DD[j+1] = w>>8;
|
||||
}
|
||||
return function dbcs_d(data/*:Data*/)/*:string*/ {
|
||||
var len = data.length, out = Buffer.allocUnsafe(2*len), i=0, j=0, k=0;
|
||||
if(/*::data instanceof Buffer && */Buffer.isBuffer(data)) {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
|
||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
||||
}
|
||||
} else if(typeof data === "string") {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data.charCodeAt(i);
|
||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data.charCodeAt(i)<<8)+data.charCodeAt(i+1)); ++i; }
|
||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < len; i++) {
|
||||
j = 2*data[i];
|
||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
|
||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
||||
}
|
||||
}
|
||||
return out.slice(0,k).toString('ucs2');
|
||||
};
|
||||
};
|
||||
magic_decode[65001] = function utf8_d(data/*:Data*/)/*:string*/ {
|
||||
if(typeof data === "string") return utf8_d(data.split("").map(cca));
|
||||
var len = data.length, w = 0, ww = 0;
|
||||
if(4 * len > mdl) { mdl = 4 * len; mdb = Buffer.allocUnsafe(mdl); }
|
||||
var i = 0;
|
||||
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
|
||||
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
|
||||
j = 1; D = data[i];
|
||||
if(D < 128) w = D;
|
||||
else if(D < 224) { w=(D&31)*64+(data[i+1]&63); j=2; }
|
||||
else if(D < 240) { w=((D&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
|
||||
else { w=(D&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
|
||||
if(w < 65536) { mdb[k++] = w&255; mdb[k++] = w>>8; }
|
||||
else {
|
||||
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
|
||||
mdb[k++] = ww&255; mdb[k++] = ww>>>8; mdb[k++] = w&255; mdb[k++] = (w>>>8)&255;
|
||||
}
|
||||
}
|
||||
return mdb.slice(0,k).toString('ucs2');
|
||||
};
|
||||
magic_encode[65001] = function utf8_e(data/*:StrData*/, ofmt/*:?string*/)/*:any*/ {
|
||||
if(has_buf && /*::data instanceof Buffer && */Buffer.isBuffer(data)) {
|
||||
if(!ofmt || ofmt === 'buf') return data;
|
||||
if(ofmt !== 'arr') return data.toString('binary');
|
||||
return [].slice.call(data);
|
||||
}
|
||||
/*::
|
||||
// data cannot be a buffer at this point
|
||||
if(data instanceof Buffer) throw "";
|
||||
*/
|
||||
var len = data.length, w = 0, ww = 0, j = 0;
|
||||
var direct = typeof data === "string";
|
||||
if(4 * len > mdl) { mdl = 4 * len; mdb = Buffer.allocUnsafe(mdl); }
|
||||
for(var i = 0; i < len; ++i) {
|
||||
w = direct /*::&& typeof data === "string" */? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w <= 0x007F) mdb[j++] = w;
|
||||
else if(w <= 0x07FF) {
|
||||
mdb[j++] = 192 + (w >> 6);
|
||||
mdb[j++] = 128 + (w&63);
|
||||
} else if(w >= 0xD800 && w <= 0xDFFF) {
|
||||
w -= 0xD800; ++i;
|
||||
ww = (direct /*::&& typeof data === "string" */? data.charCodeAt(i) : data[i].charCodeAt(0)) - 0xDC00 + (w << 10);
|
||||
mdb[j++] = 240 + ((ww>>>18) & 0x07);
|
||||
mdb[j++] = 144 + ((ww>>>12) & 0x3F);
|
||||
mdb[j++] = 128 + ((ww>>>6) & 0x3F);
|
||||
mdb[j++] = 128 + (ww & 0x3F);
|
||||
} else {
|
||||
mdb[j++] = 224 + (w >> 12);
|
||||
mdb[j++] = 128 + ((w >> 6)&63);
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
}
|
||||
|
||||
var encache = function encache() {
|
||||
if(has_buf) {
|
||||
if(cpdcache[sbcs_cache[0]]) return;
|
||||
var i=0, s=0;
|
||||
for(i = 0; i < sbcs_cache.length; ++i) {
|
||||
s = sbcs_cache[i];
|
||||
if(cpt[s]) {
|
||||
cpdcache[s] = sbcs_decode(s);
|
||||
cpecache[s] = sbcs_encode(s);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < dbcs_cache.length; ++i) {
|
||||
s = dbcs_cache[i];
|
||||
if(cpt[s]) {
|
||||
cpdcache[s] = dbcs_decode(s);
|
||||
cpecache[s] = dbcs_encode(s);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < magic_cache.length; ++i) {
|
||||
s = magic_cache[i];
|
||||
if(magic_decode[s]) cpdcache[s] = magic_decode[s];
|
||||
if(magic_encode[s]) cpecache[s] = magic_encode[s];
|
||||
}
|
||||
}
|
||||
};
|
||||
var null_enc = function(data/*:StrData*/, ofmt/*:?string*/) { void ofmt; return ""; };
|
||||
var cp_decache = function cp_decache(cp/*:CPIndex*/)/*:void*/ { delete cpdcache[cp]; delete cpecache[cp]; };
|
||||
var decache = function decache() {
|
||||
if(has_buf) {
|
||||
if(!cpdcache[sbcs_cache[0]]) return;
|
||||
sbcs_cache.forEach(cp_decache);
|
||||
dbcs_cache.forEach(cp_decache);
|
||||
magic_cache.forEach(cp_decache);
|
||||
}
|
||||
last_enc = null_enc; last_cp = 0;
|
||||
};
|
||||
var cache = {
|
||||
encache: encache,
|
||||
decache: decache,
|
||||
sbcs: sbcs_cache,
|
||||
dbcs: dbcs_cache
|
||||
};
|
||||
|
||||
encache();
|
||||
|
||||
var BM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var SetD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
|
||||
var last_enc/*:Encoder*/ = null_enc, last_cp/*:CPIndex*/ = 0;
|
||||
var encode = function encode(cp/*:CPIndex*/, data/*:StrData*/, ofmt/*:?string*/)/*:OutType*/ {
|
||||
if(cp === last_cp && last_enc) { return last_enc(data, ofmt); }
|
||||
if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); }
|
||||
if(has_buf && /*::data instanceof Buffer && */Buffer.isBuffer(data)) data = data.toString('utf8');
|
||||
/*::
|
||||
// data cannot be a buffer at this point
|
||||
if(data instanceof Buffer) throw "";
|
||||
*/
|
||||
var len = data.length;
|
||||
var out = has_buf ? Buffer.allocUnsafe(4*len) : [], w=0, i=0, j = 0, ww=0;
|
||||
var C/*:CPEntry*/ = cpt[cp], E/*:EMap*/, M/*:string*/ = "";
|
||||
var isstr = typeof data === 'string';
|
||||
if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) {
|
||||
w = E[isstr/*:: && typeof data == 'string' */? data.charAt(i) : data[i]];
|
||||
if(w > 255) {
|
||||
out[j] = w>>8;
|
||||
out[++j] = w&255;
|
||||
} else out[j] = w&255;
|
||||
}
|
||||
else if((M=magic[cp])) switch(M) {
|
||||
case "utf8":
|
||||
if(has_buf && isstr/*:: && typeof data == 'string' */) { out = Buffer_from(data, M); j = out.length; break; }
|
||||
for(i = 0; i < len; ++i, ++j) {
|
||||
w = isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w <= 0x007F) out[j] = w;
|
||||
else if(w <= 0x07FF) {
|
||||
out[j] = 192 + (w >> 6);
|
||||
out[++j] = 128 + (w&63);
|
||||
} else if(w >= 0xD800 && w <= 0xDFFF) {
|
||||
w -= 0xD800;
|
||||
ww = (isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(++i) : data[++i].charCodeAt(0)) - 0xDC00 + (w << 10);
|
||||
out[j] = 240 + ((ww>>>18) & 0x07);
|
||||
out[++j] = 144 + ((ww>>>12) & 0x3F);
|
||||
out[++j] = 128 + ((ww>>>6) & 0x3F);
|
||||
out[++j] = 128 + (ww & 0x3F);
|
||||
} else {
|
||||
out[j] = 224 + (w >> 12);
|
||||
out[++j] = 128 + ((w >> 6)&63);
|
||||
out[++j] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "ascii":
|
||||
if(has_buf && typeof data === "string") { out = Buffer_from(data, M); j = out.length; break; }
|
||||
for(i = 0; i < len; ++i, ++j) {
|
||||
w = isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w <= 0x007F) out[j] = w;
|
||||
else throw new Error("bad ascii " + w);
|
||||
}
|
||||
break;
|
||||
case "utf16le":
|
||||
if(has_buf && typeof data === "string") { out = Buffer_from(data, M); j = out.length; break; }
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
out[j++] = w&255;
|
||||
out[j++] = w>>8;
|
||||
}
|
||||
break;
|
||||
case "utf16be":
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
out[j++] = w>>8;
|
||||
out[j++] = w&255;
|
||||
}
|
||||
break;
|
||||
case "utf32le":
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
|
||||
out[j++] = w&255; w >>= 8;
|
||||
out[j++] = w&255; w >>= 8;
|
||||
out[j++] = w&255; w >>= 8;
|
||||
out[j++] = w&255;
|
||||
}
|
||||
break;
|
||||
case "utf32be":
|
||||
for(i = 0; i < len; ++i) {
|
||||
w = isstr/*:: && typeof data == 'string' */ ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
||||
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
|
||||
out[j+3] = w&255; w >>= 8;
|
||||
out[j+2] = w&255; w >>= 8;
|
||||
out[j+1] = w&255; w >>= 8;
|
||||
out[j] = w&255;
|
||||
j+=4;
|
||||
}
|
||||
break;
|
||||
case "utf7":
|
||||
for(i = 0; i < len; i++) {
|
||||
/*::
|
||||
// data cannot be a buffer at this point
|
||||
if(data instanceof Buffer) throw "";
|
||||
*/
|
||||
var c/*:string*/ = isstr/*:: && typeof data == 'string' */ ? data.charAt(i) : data[i].charAt(0);
|
||||
if(c === "+") { out[j++] = 0x2b; out[j++] = 0x2d; continue; }
|
||||
if(SetD.indexOf(c) > -1) { out[j++] = c.charCodeAt(0); continue; }
|
||||
var tt = encode(1201, c);
|
||||
out[j++] = 0x2b;
|
||||
out[j++] = BM.charCodeAt(tt[0]>>2);
|
||||
out[j++] = BM.charCodeAt(((tt[0]&0x03)<<4) + ((tt[1]||0)>>4));
|
||||
out[j++] = BM.charCodeAt(((tt[1]&0x0F)<<2) + ((tt[2]||0)>>6));
|
||||
out[j++] = 0x2d;
|
||||
}
|
||||
break;
|
||||
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
|
||||
}
|
||||
else throw new Error("Unrecognized CP: " + cp);
|
||||
out = out.slice(0,j);
|
||||
if(!has_buf) return (ofmt == 'str') ? (out/*:any*/).map(sfcc).join("") : out;
|
||||
if(!ofmt || ofmt === 'buf') return out;
|
||||
if(ofmt !== 'arr') return /*::((*/out/*:: :any) :Buffer)*/.toString('binary');
|
||||
return [].slice.call(out);
|
||||
};
|
||||
var decode = function decode(cp/*:CPIndex*/, data/*:Data*/)/*:string*/ {
|
||||
var F/*:Decoder*/; if((F=cpdcache[cp])) return F(data);
|
||||
if(typeof data === "string") return decode(cp, data.split("").map(cca));
|
||||
var len = data.length, out = new Array(len), s="", w=0, i=0, j=1, k=0, ww=0;
|
||||
var C/*:CPEntry*/ = cpt[cp], D/*:DMap*/, M="";
|
||||
if(C && (D=C.dec)) {
|
||||
for(i = 0; i < len; i+=j) {
|
||||
j = 2;
|
||||
s = D[(data[i]<<8)+ data[i+1]];
|
||||
if(!s) {
|
||||
j = 1;
|
||||
s = D[data[i]];
|
||||
}
|
||||
if(!s) throw new Error('Unrecognized code: ' + data[i] + ' ' + data[i+j-1] + ' ' + i + ' ' + j + ' ' + D[data[i]]);
|
||||
out[k++] = s;
|
||||
}
|
||||
}
|
||||
else if((M=magic[cp])) switch(M) {
|
||||
case "utf8":
|
||||
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
|
||||
for(; i < len; i+=j) {
|
||||
j = 1;
|
||||
if(data[i] < 128) w = data[i];
|
||||
else if(data[i] < 224) { w=(data[i]&31)*64+(data[i+1]&63); j=2; }
|
||||
else if(data[i] < 240) { w=((data[i]&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
|
||||
else { w=(data[i]&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
|
||||
if(w < 65536) { out[k++] = String.fromCharCode(w); }
|
||||
else {
|
||||
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
|
||||
out[k++] = String.fromCharCode(ww); out[k++] = String.fromCharCode(w);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "ascii":
|
||||
if(has_buf && /*::data instanceof Buffer && */Buffer.isBuffer(data)) return data.toString(M);
|
||||
for(i = 0; i < len; i++) out[i] = String.fromCharCode(data[i]);
|
||||
k = len; break;
|
||||
case "utf16le":
|
||||
if(len >= 2 && data[0] == 0xFF) if(data[1] == 0xFE) i = 2;
|
||||
if(has_buf && /*::data instanceof Buffer && */Buffer.isBuffer(data)) return data.toString(M);
|
||||
j = 2;
|
||||
for(; i+1 < len; i+=j) {
|
||||
out[k++] = String.fromCharCode((data[i+1]<<8) + data[i]);
|
||||
}
|
||||
break;
|
||||
case "utf16be":
|
||||
if(len >= 2 && data[0] == 0xFE) if(data[1] == 0xFF) i = 2;
|
||||
j = 2;
|
||||
for(; i+1 < len; i+=j) {
|
||||
out[k++] = String.fromCharCode((data[i]<<8) + data[i+1]);
|
||||
}
|
||||
break;
|
||||
case "utf32le":
|
||||
if(len >= 4 && data[0] == 0xFF) if(data[1] == 0xFE && data[2] === 0 && data[3] === 0) i = 4;
|
||||
j = 4;
|
||||
for(; i < len; i+=j) {
|
||||
w = (data[i+3]<<24) + (data[i+2]<<16) + (data[i+1]<<8) + (data[i]);
|
||||
if(w > 0xFFFF) {
|
||||
w -= 0x10000;
|
||||
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
|
||||
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
|
||||
}
|
||||
else out[k++] = String.fromCharCode(w);
|
||||
}
|
||||
break;
|
||||
case "utf32be":
|
||||
if(len >= 4 && data[3] == 0xFF) if(data[2] == 0xFE && data[1] === 0 && data[0] === 0) i = 4;
|
||||
j = 4;
|
||||
for(; i < len; i+=j) {
|
||||
w = (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + (data[i+3]);
|
||||
if(w > 0xFFFF) {
|
||||
w -= 0x10000;
|
||||
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
|
||||
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
|
||||
}
|
||||
else out[k++] = String.fromCharCode(w);
|
||||
}
|
||||
break;
|
||||
case "utf7":
|
||||
if(len >= 4 && data[0] == 0x2B && data[1] == 0x2F && data[2] == 0x76) {
|
||||
if(len >= 5 && data[3] == 0x38 && data[4] == 0x2D) i = 5;
|
||||
else if(data[3] == 0x38 || data[3] == 0x39 || data[3] == 0x2B || data[3] == 0x2F) i = 4;
|
||||
}
|
||||
for(; i < len; i+=j) {
|
||||
if(data[i] !== 0x2b) { j=1; out[k++] = String.fromCharCode(data[i]); continue; }
|
||||
j=1;
|
||||
if(data[i+1] === 0x2d) { j = 2; out[k++] = "+"; continue; }
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
while(String.fromCharCode(data[i+j]).match(/[A-Za-z0-9+\/]/)) j++;
|
||||
var dash = 0;
|
||||
if(data[i+j] === 0x2d) { ++j; dash=1; }
|
||||
var tt = [];
|
||||
var o64 = "";
|
||||
var c1=0, c2=0, c3=0;
|
||||
var e1=0, e2=0, e3=0, e4=0;
|
||||
for(var l = 1; l < j - dash;) {
|
||||
e1 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
e2 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
c1 = e1 << 2 | e2 >> 4;
|
||||
tt.push(c1);
|
||||
e3 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
if(e3 === -1) break;
|
||||
c2 = (e2 & 15) << 4 | e3 >> 2;
|
||||
tt.push(c2);
|
||||
e4 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
||||
if(e4 === -1) break;
|
||||
c3 = (e3 & 3) << 6 | e4;
|
||||
if(e4 < 64) tt.push(c3);
|
||||
}
|
||||
o64 = decode(1201, tt);
|
||||
for(l = 0; l < o64.length; ++l) out[k++] = o64.charAt(l);
|
||||
}
|
||||
break;
|
||||
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
|
||||
}
|
||||
else throw new Error("Unrecognized CP: " + cp);
|
||||
return out.slice(0,k).join("");
|
||||
};
|
||||
var hascp = function hascp(cp/*:number*/)/*:boolean*/ { return !!(cpt[cp] || magic[cp]); };
|
||||
const utils = { decode: decode, encode: encode, hascp: hascp, magic: magic, cache:cache };
|
||||
export { utils };
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
191
dist/LICENSE
vendored
191
dist/LICENSE
vendored
@ -1,192 +1,4 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (C) 2013-present SheetJS LLC
|
||||
Copyright (C) 2013-present SheetJS
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -199,3 +11,4 @@
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
12
dist/cpexcel.full.js
vendored
12
dist/cpexcel.full.js
vendored
@ -1,6 +1,6 @@
|
||||
/*! cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W100 */
|
||||
var cptable = {version:"1.15.0"};
|
||||
var cptable = {version:"1.14.0"};
|
||||
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖÜ¢Ł¥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
@ -973,10 +973,9 @@ return {"enc": e, "dec": d }; })();
|
||||
cptable[10029] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[10079] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[10081] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙ<C39B>ˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[28591] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~
¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = cptable;
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
@ -1224,10 +1223,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
1502
dist/cpexcel.full.mjs
vendored
1502
dist/cpexcel.full.mjs
vendored
File diff suppressed because it is too large
Load Diff
5
dist/cpexcel.js
vendored
5
dist/cpexcel.js
vendored
@ -1,6 +1,6 @@
|
||||
/*! cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W100 */
|
||||
var cptable = {version:"1.15.0"};
|
||||
var cptable = {version:"1.14.0"};
|
||||
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖÜ¢Ł¥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
@ -973,6 +973,5 @@ return {"enc": e, "dec": d }; })();
|
||||
cptable[10029] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[10079] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[10081] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙ<C39B>ˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[28591] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~
¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = cptable;
|
||||
|
1707
dist/cptable.full.js
vendored
1707
dist/cptable.full.js
vendored
File diff suppressed because it is too large
Load Diff
1700
dist/cptable.js
vendored
1700
dist/cptable.js
vendored
File diff suppressed because it is too large
Load Diff
7
dist/cputils.js
vendored
7
dist/cputils.js
vendored
@ -1,4 +1,4 @@
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
@ -246,10 +246,7 @@
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
11
dist/sbcs.full.js
vendored
11
dist/sbcs.full.js
vendored
@ -1,6 +1,6 @@
|
||||
/*! sbcs.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* sbcs.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W100 */
|
||||
var cptable = {version:"1.15.0"};
|
||||
var cptable = {version:"1.14.0"};
|
||||
cptable[37] = (function(){ var d = "\u0000\u0001\u0002\u0003\t\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013
\b\u0018\u0019\u001c\u001d\u001e\u001f\n\u0017\u001b\u0005\u0006\u0007\u0016\u0004\u0014\u0015\u001a âäàáãåçñ¢.<(+|&éêëèíîïìß!$*);¬-/ÂÄÀÁÃÅÇѦ,%_>?øÉÊËÈÍÎÏÌ`:#@'=\"Øabcdefghi«»ðýþ±°jklmnopqrªºæ¸Æ¤µ~stuvwxyz¡¿ÐÝÞ®^£¥·©§¶¼½¾[]¯¨´×{ABCDEFGHIôöòóõ}JKLMNOPQR¹ûüùúÿ\\÷STUVWXYZ²ÔÖÒÓÕ0123456789³ÛÜÙÚ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[500] = (function(){ var d = "\u0000\u0001\u0002\u0003\t\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013
\b\u0018\u0019\u001c\u001d\u001e\u001f\n\u0017\u001b\u0005\u0006\u0007\u0016\u0004\u0014\u0015\u001a âäàáãåçñ[.<(+!&éêëèíîïìß]$*);^-/ÂÄÀÁÃÅÇѦ,%_>?øÉÊËÈÍÎÏÌ`:#@'=\"Øabcdefghi«»ðýþ±°jklmnopqrªºæ¸Æ¤µ~stuvwxyz¡¿ÐÝÞ®¢£¥·©§¶¼½¾¬|¯¨´×{ABCDEFGHIôöòóõ}JKLMNOPQR¹ûüùúÿ\\÷STUVWXYZ²ÔÖÒÓÕ0123456789³ÛÜÙÚ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
@ -109,7 +109,7 @@ cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\
|
||||
cptable[895] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ČüéďäĎŤčěĚĹÍľǪÄÁÉžŽôöÓůÚýÖÜŠĽÝŘťáíóúňŇŮÔšřŕŔ¼§«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = cptable;
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
@ -357,10 +357,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
4
dist/sbcs.js
vendored
4
dist/sbcs.js
vendored
@ -1,6 +1,6 @@
|
||||
/*! sbcs.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* sbcs.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W100 */
|
||||
var cptable = {version:"1.15.0"};
|
||||
var cptable = {version:"1.14.0"};
|
||||
cptable[37] = (function(){ var d = "\u0000\u0001\u0002\u0003\t\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013
\b\u0018\u0019\u001c\u001d\u001e\u001f\n\u0017\u001b\u0005\u0006\u0007\u0016\u0004\u0014\u0015\u001a âäàáãåçñ¢.<(+|&éêëèíîïìß!$*);¬-/ÂÄÀÁÃÅÇѦ,%_>?øÉÊËÈÍÎÏÌ`:#@'=\"Øabcdefghi«»ðýþ±°jklmnopqrªºæ¸Æ¤µ~stuvwxyz¡¿ÐÝÞ®^£¥·©§¶¼½¾[]¯¨´×{ABCDEFGHIôöòóõ}JKLMNOPQR¹ûüùúÿ\\÷STUVWXYZ²ÔÖÒÓÕ0123456789³ÛÜÙÚ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[500] = (function(){ var d = "\u0000\u0001\u0002\u0003\t\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013
\b\u0018\u0019\u001c\u001d\u001e\u001f\n\u0017\u001b\u0005\u0006\u0007\u0016\u0004\u0014\u0015\u001a âäàáãåçñ[.<(+!&éêëèíîïìß]$*);^-/ÂÄÀÁÃÅÇѦ,%_>?øÉÊËÈÍÎÏÌ`:#@'=\"Øabcdefghi«»ðýþ±°jklmnopqrªºæ¸Æ¤µ~stuvwxyz¡¿ÐÝÞ®¢£¥·©§¶¼½¾¬|¯¨´×{ABCDEFGHIôöòóõ}JKLMNOPQR¹ûüùúÿ\\÷STUVWXYZ²ÔÖÒÓÕ0123456789³ÛÜÙÚ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
|
@ -29,4 +29,3 @@
|
||||
10029,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT,1
|
||||
10079,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ICELAND.TXT,1
|
||||
10081,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/TURKISH.TXT,1
|
||||
28591,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT,1
|
||||
|
|
@ -1,6 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- codepage (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<title>js-codepage tests</title>
|
||||
|
51
make.njs
51
make.njs
@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
var argv = process.argv.slice(1), fs = require('fs');
|
||||
if(argv.length < 2) {
|
||||
console.error("usage: make.njs <codepage_index> [variable]");
|
||||
process.exit(22); /* EINVAL */
|
||||
}
|
||||
|
||||
var cp/*:string*/ = argv[1];
|
||||
var jsvar/*:string*/ = argv[2] || "cptable";
|
||||
var x/*:string*/ = fs.readFileSync("codepages/" + cp + ".TBL","utf8");
|
||||
var maxcp = 0, i = 0, ii = 0;
|
||||
|
||||
var y/*:Array<Array<number> >*/ = x.split("\n").map(function(z/*:string*/)/*:Array<number>*/ {
|
||||
var w/*:Array<string>*/ = z.split("\t");
|
||||
if(w.length < 2) return [Number(w[0])];
|
||||
return [Number(w[0]), Number(w[1])];
|
||||
}).filter(function(z) { return z.length > 1; });
|
||||
for(i = 0; i != y.length; ++i) if(y[i][0] > maxcp) maxcp = y[i][0];
|
||||
|
||||
var enc/*:{[key:string]:number}*/ = {}, dec/*:{[key:string]:string}|Array<string>*/ = (maxcp < 256 ? [] : {});
|
||||
for(i = 0; i != y.length; ++i) {
|
||||
/*:: if(Array.isArray(dec)) */ dec[y[i][0]] = String.fromCharCode(y[i][1]);
|
||||
enc[String.fromCharCode(y[i][1])] = y[i][0];
|
||||
}
|
||||
|
||||
var odec = "", outstr = "";
|
||||
if(maxcp < 256) {
|
||||
/*:: if(Array.isArray(dec)) { */
|
||||
for(i = 0; i != 256; ++i) if(typeof dec[i] === "undefined") dec[i] = String.fromCharCode(0xFFFD);
|
||||
odec = JSON.stringify(dec.join(""));
|
||||
outstr = '(function(){ var d = ' + odec + ', D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();';
|
||||
/*:: } */
|
||||
} else {
|
||||
var dd = [];
|
||||
/*:: if(!Array.isArray(dec)) { */
|
||||
for(i in dec) if(dec.hasOwnProperty(i)) {
|
||||
ii = +i;
|
||||
if(typeof dd[ii >> 8] === "undefined") dd[ii >> 8] = [];
|
||||
dd[ii >> 8][ii % 256] = dec[i];
|
||||
}
|
||||
/*:: } */
|
||||
outstr = '(function(){ var d = [], e = {}, D = [], j;\n';
|
||||
for(var i = 0; i != 256; ++i) if(dd[i]) {
|
||||
for(var j = 0; j != 256; ++j) if(typeof dd[i][j] === "undefined") dd[i][j] = String.fromCharCode(0xFFFD);
|
||||
outstr += 'D[' + i + '] = ' + JSON.stringify(dd[i].join("")) + '.split("");\n';
|
||||
outstr += 'for(j = 0; j != D[' + i + '].length; ++j) if(D[' + i + '][j].charCodeAt(0) !== 0xFFFD) { e[D[' + i + '][j]] = ' + (i*256) + ' + j; d[' + (i*256) + ' + j] = D[' + i + '][j];}\n'
|
||||
}
|
||||
outstr += 'return {"enc": e, "dec": d }; })();';
|
||||
}
|
||||
process.stdout.write(jsvar + "[" + cp + "] = " + outstr + "\n");
|
||||
|
26
make.sh
26
make.sh
@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
INFILE=${1:-pages.csv}
|
||||
OUTFILE=${2:-cptable.js}
|
||||
JSVAR=${3:-cptable}
|
||||
VERSION=$(cat package.json | grep version | tr -dc [0-9.])
|
||||
|
||||
mkdir -p codepages bits
|
||||
rm -f $OUTFILE $OUTFILE.tmp
|
||||
echo "/*! $OUTFILE (C) 2013-present SheetJS -- http://sheetjs.com */" > $OUTFILE.tmp
|
||||
echo "/*jshint -W100 */" >> $OUTFILE.tmp
|
||||
echo "var $JSVAR = {version:\"$VERSION\"};" >> $OUTFILE.tmp
|
||||
if [ -e dotnet.sh ]; then bash dotnet.sh; fi
|
||||
awk -F, '{print $1, $2, $3}' $INFILE | while read cp url cptype; do
|
||||
echo $cp $url
|
||||
if [ ! -e codepages/$cp.TBL ]; then
|
||||
curl $url | sed 's/#.*//g' | awk 'NF==2' > codepages/$cp.TBL
|
||||
fi
|
||||
echo "if(typeof $JSVAR === 'undefined') $JSVAR = {};" > bits/$cp.js.tmp
|
||||
node make.njs $cp $JSVAR | tee -a bits/$cp.js.tmp >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <bits/$cp.js.tmp >bits/$cp.js
|
||||
rm -f bits/$cp.js.tmp
|
||||
done
|
||||
echo "// eslint-disable-next-line no-undef" >> $OUTFILE.tmp
|
||||
echo "if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = $JSVAR;" >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <$OUTFILE.tmp >$OUTFILE
|
||||
rm -f $OUTFILE.tmp
|
22
make_esm.sh
22
make_esm.sh
@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
INFILE=${1:-pages.csv}
|
||||
OUTFILE=${2:-cptable.mjs}
|
||||
VERSION=$(cat package.json | grep version | tr -dc [0-9.])
|
||||
|
||||
mkdir -p codepages bits
|
||||
rm -f $OUTFILE $OUTFILE.tmp
|
||||
echo "/*! $OUTFILE (C) 2013-present SheetJS -- http://sheetjs.com */" > $OUTFILE.tmp
|
||||
echo "/*jshint -W100 */" >> $OUTFILE.tmp
|
||||
echo "export const version = \"$VERSION\";" >> $OUTFILE.tmp
|
||||
echo "const cptable = {};" >> $OUTFILE.tmp
|
||||
if [ -e dotnet.sh ]; then bash dotnet.sh; fi
|
||||
awk -F, '{print $1, $2, $3}' $INFILE | while read cp url cptype; do
|
||||
echo $cp $url
|
||||
if [ ! -e codepages/$cp.TBL ]; then
|
||||
curl $url | sed 's/#.*//g' | awk 'NF==2' > codepages/$cp.TBL
|
||||
fi
|
||||
node make.njs $cp cptable >> $OUTFILE.tmp
|
||||
done
|
||||
echo "export { cptable };" >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <$OUTFILE.tmp >$OUTFILE
|
||||
rm -f $OUTFILE.tmp
|
@ -26,7 +26,7 @@ Alternatively, use the full version in the dist folder:
|
||||
```
|
||||
|
||||
The complete set of codepages is large due to some Double Byte Character Set
|
||||
encodings. A much smaller file that only includes SBCS codepages is provided in
|
||||
encodings. A much smaller file that just includes SBCS codepages is provided in
|
||||
this repo (`sbcs.js`), as well as a file for other projects (`cpexcel.js`)
|
||||
|
||||
If you know which codepages you need, you can include individual scripts for
|
||||
@ -133,7 +133,7 @@ to produce a complete script like `cpexcel.full.js`.
|
||||
## Building the complete script
|
||||
|
||||
This script uses [voc](npm.im/voc). The script to build the codepage tables and
|
||||
the JS source is `codepage.md`, so building involves `voc codepage.md`.
|
||||
the JS source is `codepage.md`, so building is as simple as `voc codepage.md`.
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
@ -274,11 +274,11 @@ tables are not generated, there is no corresponding entry (they are "magic").
|
||||
| `29001` | Windows 7 | Europa 3 |
|
||||
| `38598` | Windows 7 | ISO 8859-8 Hebrew (ISO-Logical) |
|
||||
| `47451` | unicode.org | Atari ST/TT |
|
||||
| `50220` | magic | ISO 2022 JIS Japanese with no halfwidth Katakana |
|
||||
| `50221` | magic | ISO 2022 JIS Japanese with halfwidth Katakana |
|
||||
| `50222` | magic | ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)|
|
||||
| `50225` | magic | ISO 2022 Korean |
|
||||
| `50227` | magic | ISO 2022 Simplified Chinese |
|
||||
| `50220` | Windows 7 | ISO 2022 JIS Japanese with no halfwidth Katakana |
|
||||
| `50221` | Windows 7 | ISO 2022 JIS Japanese with halfwidth Katakana |
|
||||
| `50222` | Windows 7 | ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)|
|
||||
| `50225` | Windows 7 | ISO 2022 Korean |
|
||||
| `50227` | Windows 7 | ISO 2022 Simplified Chinese |
|
||||
| `51932` | Windows 7 | EUC Japanese |
|
||||
| `51936` | Windows 7 | EUC Simplified Chinese |
|
||||
| `51949` | Windows 7 | EUC Korean |
|
||||
@ -330,9 +330,6 @@ To update the browser artifacts, run `make ctest`.
|
||||
- [Windows Code Page Enumeration](http://msdn.microsoft.com/en-us/library/cc195051.aspx)
|
||||
- [Windows Code Page Identifiers](http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756.aspx)
|
||||
- [IBM Coded Character Sets](https://www-01.ibm.com/software/globalization/ccsid/ccsid_registered.html)
|
||||
- [ISO/IEC 2022 / ECMA-35](https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-035.pdf)
|
||||
- [International Register of Coded Character Sets To Be Used With Escape Sequences](https://www.itscj.ipsj.or.jp/itscj_english/iso-ir/ISO-IR.pdf)
|
||||
- [Japanese Character Encoding for Internet Messages](https://tools.ietf.org/html/rfc1468)
|
||||
|
||||
## License
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -26,7 +26,7 @@ Alternatively, use the full version in the dist folder:
|
||||
+AGAAYABg
|
||||
|
||||
The complete set of codepages is large due to some Double Byte Character Set
|
||||
encodings. A much smaller file that only includes SBCS codepages is provided in
|
||||
encodings. A much smaller file that just includes SBCS codepages is provided in
|
||||
this repo (+AGA-sbcs.js+AGA), as well as a file for other projects (+AGA-cpexcel.js+AGA)
|
||||
|
||||
If you know which codepages you need, you can include individual scripts for
|
||||
@ -133,7 +133,7 @@ to produce a complete script like +AGA-cpexcel.full.js+AGA.
|
||||
+ACMAIw Building the complete script
|
||||
|
||||
This script uses +AFs-voc+AF0(npm.im/voc). The script to build the codepage tables and
|
||||
the JS source is +AGA-codepage.md+AGA, so building involves +AGA-voc codepage.md+AGA.
|
||||
the JS source is +AGA-codepage.md+AGA, so building is as simple as +AGA-voc codepage.md+AGA.
|
||||
|
||||
+ACMAIw Generated Codepages
|
||||
|
||||
@ -274,11 +274,11 @@ tables are not generated, there is no corresponding entry (they are +ACI-magic+A
|
||||
+AHw +AGA-29001+AGA +AHw Windows 7 +AHw Europa 3 +AHw
|
||||
+AHw +AGA-38598+AGA +AHw Windows 7 +AHw ISO 8859-8 Hebrew (ISO-Logical) +AHw
|
||||
+AHw +AGA-47451+AGA +AHw unicode.org +AHw Atari ST/TT +AHw
|
||||
+AHw +AGA-50220+AGA +AHw magic +AHw ISO 2022 JIS Japanese with no halfwidth Katakana +AHw
|
||||
+AHw +AGA-50221+AGA +AHw magic +AHw ISO 2022 JIS Japanese with halfwidth Katakana +AHw
|
||||
+AHw +AGA-50222+AGA +AHw magic +AHw ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)+AHw
|
||||
+AHw +AGA-50225+AGA +AHw magic +AHw ISO 2022 Korean +AHw
|
||||
+AHw +AGA-50227+AGA +AHw magic +AHw ISO 2022 Simplified Chinese +AHw
|
||||
+AHw +AGA-50220+AGA +AHw Windows 7 +AHw ISO 2022 JIS Japanese with no halfwidth Katakana +AHw
|
||||
+AHw +AGA-50221+AGA +AHw Windows 7 +AHw ISO 2022 JIS Japanese with halfwidth Katakana +AHw
|
||||
+AHw +AGA-50222+AGA +AHw Windows 7 +AHw ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)+AHw
|
||||
+AHw +AGA-50225+AGA +AHw Windows 7 +AHw ISO 2022 Korean +AHw
|
||||
+AHw +AGA-50227+AGA +AHw Windows 7 +AHw ISO 2022 Simplified Chinese +AHw
|
||||
+AHw +AGA-51932+AGA +AHw Windows 7 +AHw EUC Japanese +AHw
|
||||
+AHw +AGA-51936+AGA +AHw Windows 7 +AHw EUC Simplified Chinese +AHw
|
||||
+AHw +AGA-51949+AGA +AHw Windows 7 +AHw EUC Korean +AHw
|
||||
@ -330,9 +330,6 @@ To update the browser artifacts, run +AGA-make ctest+AGA.
|
||||
- +AFs-Windows Code Page Enumeration+AF0(http://msdn.microsoft.com/en-us/library/cc195051.aspx)
|
||||
- +AFs-Windows Code Page Identifiers+AF0(http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756.aspx)
|
||||
- +AFs-IBM Coded Character Sets+AF0(https://www-01.ibm.com/software/globalization/ccsid/ccsid+AF8-registered.html)
|
||||
- +AFs-ISO/IEC 2022 / ECMA-35+AF0(https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-035.pdf)
|
||||
- +AFs-International Register of Coded Character Sets To Be Used With Escape Sequences+AF0(https://www.itscj.ipsj.or.jp/itscj+AF8-english/iso-ir/ISO-IR.pdf)
|
||||
- +AFs-Japanese Character Encoding for Internet Messages+AF0(https://tools.ietf.org/html/rfc1468)
|
||||
|
||||
+ACMAIw License
|
||||
|
||||
|
@ -26,7 +26,7 @@ Alternatively, use the full version in the dist folder:
|
||||
```
|
||||
|
||||
The complete set of codepages is large due to some Double Byte Character Set
|
||||
encodings. A much smaller file that only includes SBCS codepages is provided in
|
||||
encodings. A much smaller file that just includes SBCS codepages is provided in
|
||||
this repo (`sbcs.js`), as well as a file for other projects (`cpexcel.js`)
|
||||
|
||||
If you know which codepages you need, you can include individual scripts for
|
||||
@ -133,7 +133,7 @@ to produce a complete script like `cpexcel.full.js`.
|
||||
## Building the complete script
|
||||
|
||||
This script uses [voc](npm.im/voc). The script to build the codepage tables and
|
||||
the JS source is `codepage.md`, so building involves `voc codepage.md`.
|
||||
the JS source is `codepage.md`, so building is as simple as `voc codepage.md`.
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
@ -274,11 +274,11 @@ tables are not generated, there is no corresponding entry (they are "magic").
|
||||
| `29001` | Windows 7 | Europa 3 |
|
||||
| `38598` | Windows 7 | ISO 8859-8 Hebrew (ISO-Logical) |
|
||||
| `47451` | unicode.org | Atari ST/TT |
|
||||
| `50220` | magic | ISO 2022 JIS Japanese with no halfwidth Katakana |
|
||||
| `50221` | magic | ISO 2022 JIS Japanese with halfwidth Katakana |
|
||||
| `50222` | magic | ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)|
|
||||
| `50225` | magic | ISO 2022 Korean |
|
||||
| `50227` | magic | ISO 2022 Simplified Chinese |
|
||||
| `50220` | Windows 7 | ISO 2022 JIS Japanese with no halfwidth Katakana |
|
||||
| `50221` | Windows 7 | ISO 2022 JIS Japanese with halfwidth Katakana |
|
||||
| `50222` | Windows 7 | ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI)|
|
||||
| `50225` | Windows 7 | ISO 2022 Korean |
|
||||
| `50227` | Windows 7 | ISO 2022 Simplified Chinese |
|
||||
| `51932` | Windows 7 | EUC Japanese |
|
||||
| `51936` | Windows 7 | EUC Simplified Chinese |
|
||||
| `51949` | Windows 7 | EUC Korean |
|
||||
@ -330,9 +330,6 @@ To update the browser artifacts, run `make ctest`.
|
||||
- [Windows Code Page Enumeration](http://msdn.microsoft.com/en-us/library/cc195051.aspx)
|
||||
- [Windows Code Page Identifiers](http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756.aspx)
|
||||
- [IBM Coded Character Sets](https://www-01.ibm.com/software/globalization/ccsid/ccsid_registered.html)
|
||||
- [ISO/IEC 2022 / ECMA-35](https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-035.pdf)
|
||||
- [International Register of Coded Character Sets To Be Used With Escape Sequences](https://www.itscj.ipsj.or.jp/itscj_english/iso-ir/ISO-IR.pdf)
|
||||
- [Japanese Character Encoding for Internet Messages](https://tools.ietf.org/html/rfc1468)
|
||||
|
||||
## License
|
||||
|
||||
|
@ -2,14 +2,78 @@
|
||||
|
||||
The fields of the `pages.csv` manifest are `codepage,url,bytes` (SBCS=1, DBCS=2)
|
||||
|
||||
```>pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
863,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP863.TXT,1
|
||||
864,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP864.TXT,1
|
||||
865,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP865.TXT,1
|
||||
866,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP866.TXT,1
|
||||
869,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP869.TXT,1
|
||||
874,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT,1
|
||||
875,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT,1
|
||||
932,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT,2
|
||||
936,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT,2
|
||||
949,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT,2
|
||||
950,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT,2
|
||||
1026,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT,1
|
||||
1250,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT,1
|
||||
1251,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT,1
|
||||
1252,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT,1
|
||||
1253,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT,1
|
||||
1254,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT,1
|
||||
1255,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT,1
|
||||
1256,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT,1
|
||||
1257,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT,1
|
||||
1258,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT,1
|
||||
47451,http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/ATARIST.TXT,1
|
||||
```
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private `0xF8FF` code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
MICSFT. Codepages are an absolute pain :/
|
||||
|
||||
```>pages.csv
|
||||
10000,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ROMAN.TXT,1
|
||||
10006,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/GREEK.TXT,1
|
||||
10007,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/CYRILLIC.TXT,1
|
||||
10029,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT,1
|
||||
10079,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ICELAND.TXT,1
|
||||
10081,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/TURKISH.TXT,1
|
||||
```
|
||||
|
||||
The numbering scheme for the `ISO-8859-X` series is `28590 + X`:
|
||||
|
||||
```>pages.csv
|
||||
28591,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT,1
|
||||
28592,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-2.TXT,1
|
||||
28593,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-3.TXT,1
|
||||
28594,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-4.TXT,1
|
||||
28595,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-5.TXT,1
|
||||
28596,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-6.TXT,1
|
||||
28597,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-7.TXT,1
|
||||
28598,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-8.TXT,1
|
||||
28599,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-9.TXT,1
|
||||
28600,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-10.TXT,1
|
||||
28601,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-11.TXT,1
|
||||
28603,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-13.TXT,1
|
||||
28604,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-14.TXT,1
|
||||
28605,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT,1
|
||||
28606,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-16.TXT,1
|
||||
```
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
@ -78,6 +142,11 @@ The following codepages are available in .NET on Windows:
|
||||
- 21866 Ukrainian (KOI8-U); Cyrillic (KOI8-U)
|
||||
- 29001 Europa 3
|
||||
- 38598 ISO 8859-8 Hebrew; Hebrew (ISO-Logical)
|
||||
- 50220 ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
|
||||
- 50221 ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS Allow 1 byte Kana)
|
||||
- 50222 ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS Allow 1 byte Kana - SO/SI)
|
||||
- 50225 ISO 2022 Korean
|
||||
- 50227 ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)
|
||||
- 51932 EUC Japanese
|
||||
- 51936 EUC Simplified Chinese; Chinese Simplified (EUC)
|
||||
- 51949 EUC Korean
|
||||
@ -94,11 +163,107 @@ The following codepages are available in .NET on Windows:
|
||||
- 57010 ISCII Gujarati
|
||||
- 57011 ISCII Punjabi
|
||||
|
||||
```>pages.csv
|
||||
708,,1
|
||||
720,,1
|
||||
808,,1
|
||||
858,,1
|
||||
870,,1
|
||||
872,,1
|
||||
1010,,1
|
||||
1047,,1
|
||||
1132,,1
|
||||
1140,,1
|
||||
1141,,1
|
||||
1142,,1
|
||||
1143,,1
|
||||
1144,,1
|
||||
1145,,1
|
||||
1146,,1
|
||||
1147,,1
|
||||
1148,,1
|
||||
1149,,1
|
||||
1361,,2
|
||||
10001,,2
|
||||
10002,,2
|
||||
10003,,2
|
||||
10004,,1
|
||||
10005,,1
|
||||
10008,,2
|
||||
10010,,1
|
||||
10017,,1
|
||||
10021,,1
|
||||
10082,,1
|
||||
20000,,2
|
||||
20001,,2
|
||||
20002,,2
|
||||
20003,,2
|
||||
20004,,2
|
||||
20005,,2
|
||||
20105,,1
|
||||
20106,,1
|
||||
20107,,1
|
||||
20108,,1
|
||||
20261,,2
|
||||
20269,,1
|
||||
20273,,1
|
||||
20277,,1
|
||||
20278,,1
|
||||
20280,,1
|
||||
20284,,1
|
||||
20285,,1
|
||||
20290,,1
|
||||
20297,,1
|
||||
20420,,1
|
||||
20423,,1
|
||||
20424,,1
|
||||
20833,,1
|
||||
20838,,1
|
||||
20866,,1
|
||||
20871,,1
|
||||
20880,,1
|
||||
20905,,1
|
||||
20924,,1
|
||||
20932,,2
|
||||
20936,,2
|
||||
20949,,2
|
||||
21025,,1
|
||||
21027,,1
|
||||
21866,,1
|
||||
29001,,1
|
||||
38598,,1
|
||||
50220,,2
|
||||
50221,,2
|
||||
50222,,2
|
||||
50225,,2
|
||||
50227,,2
|
||||
51932,,2
|
||||
51936,,2
|
||||
51949,,2
|
||||
52936,,2
|
||||
54936,,2
|
||||
57002,,2
|
||||
57003,,2
|
||||
57004,,2
|
||||
57005,,2
|
||||
57006,,2
|
||||
57007,,2
|
||||
57008,,2
|
||||
57009,,2
|
||||
57010,,2
|
||||
57011,,2
|
||||
```
|
||||
|
||||
The following codepages are dependencies for Visual FoxPro:
|
||||
|
||||
- 620 Mazovia (Polish) MS-DOS
|
||||
- 895 Kamenick (Czech) MS-DOS
|
||||
|
||||
```>pages.csv
|
||||
620,,1
|
||||
895,,1
|
||||
```
|
||||
|
||||
## Building Notes
|
||||
|
||||
The script `make.sh` (described later) will get these files and massage the data
|
||||
@ -124,7 +289,13 @@ which implies that code `0xF6` is `String.fromCharCode(0x02C6)` and vice versa.
|
||||
|
||||
To build the sources on windows, consult `dotnet/MakeEncoding.cs`.
|
||||
|
||||
After saving standard output to `out`, the `dotnet.sh` script processes results.
|
||||
After saving the standard output to `out`, a simple script processes the result:
|
||||
|
||||
```>dotnet.sh
|
||||
#!/bin/bash
|
||||
if [ ! -e dotnet/out ]; then exit; fi
|
||||
<dotnet/out tr -s ' ' '\t' | awk 'NF>2 {if(outfile) close(outfile); outfile="codepages/" $1 ".TBL"} NF==2 {print > outfile}'
|
||||
```
|
||||
|
||||
# Building the script
|
||||
|
||||
@ -133,9 +304,43 @@ generates JS code for encoding and decoding:
|
||||
|
||||
## Raw Codepages
|
||||
|
||||
```>make.njs
|
||||
#!/usr/bin/env node
|
||||
var argv = process.argv.slice(1), fs = require('fs');
|
||||
if(argv.length < 2) {
|
||||
console.error("usage: make.njs <codepage_index> [variable]");
|
||||
process.exit(22); /* EINVAL */
|
||||
}
|
||||
|
||||
var cp/*:string*/ = argv[1];
|
||||
var jsvar/*:string*/ = argv[2] || "cptable";
|
||||
var x/*:string*/ = fs.readFileSync("codepages/" + cp + ".TBL","utf8");
|
||||
var maxcp = 0, i = 0, ii = 0;
|
||||
|
||||
var y/*:Array<Array<number> >*/ = x.split("\n").map(function(z/*:string*/)/*:Array<number>*/ {
|
||||
var w/*:Array<string>*/ = z.split("\t");
|
||||
if(w.length < 2) return [Number(w[0])];
|
||||
return [Number(w[0]), Number(w[1])];
|
||||
}).filter(function(z) { return z.length > 1; });
|
||||
```
|
||||
|
||||
The DBCS and SBCS code generation strategies are different. The maximum code is
|
||||
used to distinguish (max `0xFF` for SBCS).
|
||||
|
||||
```
|
||||
for(i = 0; i != y.length; ++i) if(y[i][0] > maxcp) maxcp = y[i][0];
|
||||
|
||||
var enc/*:{[key:string]:number}*/ = {}, dec/*:{[key:string]:string}|Array<string>*/ = (maxcp < 256 ? [] : {});
|
||||
for(i = 0; i != y.length; ++i) {
|
||||
/*:: if(Array.isArray(dec)) */ dec[y[i][0]] = String.fromCharCode(y[i][1]);
|
||||
enc[String.fromCharCode(y[i][1])] = y[i][0];
|
||||
}
|
||||
|
||||
var odec = "", outstr = "";
|
||||
if(maxcp < 256) {
|
||||
/*:: if(Array.isArray(dec)) { */
|
||||
```
|
||||
|
||||
The Unicode character `0xFFFD` (REPLACEMENT CHARACTER) is used as a placeholder
|
||||
for characters that are not specified in the map (for example, `0xF0` is not in
|
||||
code page 10000).
|
||||
@ -143,6 +348,14 @@ code page 10000).
|
||||
For SBCS, the idea is to embed a raw string with the contents of the 256 codes.
|
||||
The `dec` field is merely a split of the string, and `enc` is an eversion:
|
||||
|
||||
```
|
||||
for(i = 0; i != 256; ++i) if(typeof dec[i] === "undefined") dec[i] = String.fromCharCode(0xFFFD);
|
||||
odec = JSON.stringify(dec.join(""));
|
||||
outstr = '(function(){ var d = ' + odec + ', D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();';
|
||||
/*:: } */
|
||||
} else {
|
||||
```
|
||||
|
||||
DBCS is similar, except that the space is sliced in chunks of 256 bytes (strings
|
||||
are only generated for those high-bytes represented in the codepage).
|
||||
|
||||
@ -150,6 +363,27 @@ The strategy is to construct an array-of-arrays so that `dd[high][low]` is the
|
||||
character associated with the code. This array is combined at runtime to yield
|
||||
the complete decoding object (and the encoding object is an eversion):
|
||||
|
||||
```
|
||||
var dd = [];
|
||||
/*:: if(!Array.isArray(dec)) { */
|
||||
for(i in dec) if(dec.hasOwnProperty(i)) {
|
||||
ii = +i;
|
||||
if(typeof dd[ii >> 8] === "undefined") dd[ii >> 8] = [];
|
||||
dd[ii >> 8][ii % 256] = dec[i];
|
||||
}
|
||||
/*:: } */
|
||||
outstr = '(function(){ var d = [], e = {}, D = [], j;\n';
|
||||
for(var i = 0; i != 256; ++i) if(dd[i]) {
|
||||
for(var j = 0; j != 256; ++j) if(typeof dd[i][j] === "undefined") dd[i][j] = String.fromCharCode(0xFFFD);
|
||||
outstr += 'D[' + i + '] = ' + JSON.stringify(dd[i].join("")) + '.split("");\n';
|
||||
outstr += 'for(j = 0; j != D[' + i + '].length; ++j) if(D[' + i + '][j].charCodeAt(0) !== 0xFFFD) { e[D[' + i + '][j]] = ' + (i*256) + ' + j; d[' + (i*256) + ' + j] = D[' + i + '][j];}\n'
|
||||
}
|
||||
outstr += 'return {"enc": e, "dec": d }; })();';
|
||||
}
|
||||
process.stdout.write(jsvar + "[" + cp + "] = " + outstr + "\n");
|
||||
|
||||
```
|
||||
|
||||
`make.sh` generates the tables used by `make.njs`. The raw Unicode TXT files
|
||||
are columnar: `code unicode #comments`. For example, the last 10 lines of the
|
||||
text file `ROMAN.TXT` (for CP 10000) are:
|
||||
@ -170,6 +404,35 @@ text file `ROMAN.TXT` (for CP 10000) are:
|
||||
In processing the data, the comments (after the `#`) are stripped and undefined
|
||||
elements (like `0x7F` for CP 10000) are removed.
|
||||
|
||||
```>make.sh
|
||||
#!/bin/bash
|
||||
INFILE=${1:-pages.csv}
|
||||
OUTFILE=${2:-cptable.js}
|
||||
JSVAR=${3:-cptable}
|
||||
VERSION=$(cat package.json | grep version | tr -dc [0-9.])
|
||||
|
||||
mkdir -p codepages bits
|
||||
rm -f $OUTFILE $OUTFILE.tmp
|
||||
echo "/* $OUTFILE (C) 2013-present SheetJS -- http://sheetjs.com */" > $OUTFILE.tmp
|
||||
echo "/*jshint -W100 */" >> $OUTFILE.tmp
|
||||
echo "var $JSVAR = {version:\"$VERSION\"};" >> $OUTFILE.tmp
|
||||
if [ -e dotnet.sh ]; then bash dotnet.sh; fi
|
||||
awk -F, '{print $1, $2, $3}' $INFILE | while read cp url cptype; do
|
||||
echo $cp $url
|
||||
if [ ! -e codepages/$cp.TBL ]; then
|
||||
curl $url | sed 's/#.*//g' | awk 'NF==2' > codepages/$cp.TBL
|
||||
fi
|
||||
echo "if(typeof $JSVAR === 'undefined') $JSVAR = {};" > bits/$cp.js.tmp
|
||||
node make.njs $cp $JSVAR | tee -a bits/$cp.js.tmp >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <bits/$cp.js.tmp >bits/$cp.js
|
||||
rm -f bits/$cp.js.tmp
|
||||
done
|
||||
echo "// eslint-disable-next-line no-undef" >> $OUTFILE.tmp
|
||||
echo "if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = $JSVAR;" >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <$OUTFILE.tmp >$OUTFILE
|
||||
rm -f $OUTFILE.tmp
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
The encode and decode functions are kept in a separate script (`cputils.js`).
|
||||
@ -183,8 +446,412 @@ Both encode and decode deal with data represented as:
|
||||
The `ofmt` variable controls `encode` output (`str`, `arr` respectively)
|
||||
while the input format is automatically determined.
|
||||
|
||||
# Tests
|
||||
|
||||
```>test.js
|
||||
var fs = require('fs'), assert = require('assert'), vm = require('vm');
|
||||
var cptable, sbcs;
|
||||
|
||||
```
|
||||
|
||||
Due to a bug in `Buffer.from` in node `4.0 - 4.4`, a special check is needed:
|
||||
|
||||
```>test.js
|
||||
var Buffer_from = function(){};
|
||||
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The tests include JS validity tests (requiring or evaluating code):
|
||||
|
||||
```>test.js
|
||||
describe('source', function() {
|
||||
it('should load node', function() { cptable = require('./'); });
|
||||
it('should load sbcs', function() { sbcs = require('./sbcs'); });
|
||||
it('should load excel', function() { excel = require('./cpexcel'); });
|
||||
it('should process bits', function() {
|
||||
var files = fs.readdirSync('bits').filter(function(x){return x.substr(-3)==".js";});
|
||||
files.forEach(function(x) {
|
||||
vm.runInThisContext(fs.readFileSync('./bits/' + x));
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The README tests verify the snippets in the README:
|
||||
|
||||
```>test.js
|
||||
describe('README', function() {
|
||||
var readme = function() {
|
||||
var unicode_cp10000_255 = cptable[10000].dec[255]; //
|
||||
assert.equal(unicode_cp10000_255, "");
|
||||
|
||||
var cp10000_711 = cptable[10000].enc[String.fromCharCode(711)]; // 255
|
||||
assert.equal(cp10000_711, 255);
|
||||
|
||||
var b1 = [0xbb,0xe3,0xd7,0xdc];
|
||||
var s1 = b1.map(function(x) { return String.fromCharCode(x); }).join("");
|
||||
var = cptable.utils.decode(936, b1);
|
||||
var buf = cptable.utils.encode(936, );
|
||||
assert.equal(,"");
|
||||
assert.equal(buf.length, 4);
|
||||
for(var i = 0; i != 4; ++i) assert.equal(b1[i], buf[i]);
|
||||
|
||||
var b2 = [0xf0,0x9f,0x8d,0xa3];
|
||||
var sushi= cptable.utils.decode(65001, b2);
|
||||
var sbuf = cptable.utils.encode(65001, sushi);
|
||||
assert.equal(sushi,"");
|
||||
assert.equal(sbuf.length, 4);
|
||||
for(var i = 0; i != 4; ++i) assert.equal(b2[i], sbuf[i]);
|
||||
|
||||
};
|
||||
it('should be correct', function() {
|
||||
cptable.utils.cache.encache();
|
||||
readme();
|
||||
cptable.utils.cache.decache();
|
||||
readme();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The consistency tests make sure that encoding and decoding are pseudo inverses:
|
||||
|
||||
```>test.js
|
||||
describe('consistency', function() {
|
||||
cptable = require('./');
|
||||
U = cptable.utils;
|
||||
var chk = function(cptable, cacheit) { return function(x) {
|
||||
it('should consistently process CP ' + x, function() {
|
||||
var cp = cptable[x], D = cp.dec, E = cp.enc;
|
||||
if(cacheit) cptable.utils.cache.encache();
|
||||
else cptable.utils.cache.decache();
|
||||
Object.keys(D).forEach(function(d) {
|
||||
if(E[D[d]] != d) {
|
||||
if(typeof E[D[d]] !== "undefined") return;
|
||||
if(D[d].charCodeAt(0) == 0xFFFD) return;
|
||||
if(D[E[D[d]]] === D[d]) return;
|
||||
throw new Error(x + " e.d[" + d + "] = " + E[D[d]] + "; d[" + d + "]=" + D[d] + "; d.e.d[" + d + "] = " + D[E[D[d]]]);
|
||||
}
|
||||
});
|
||||
Object.keys(E).forEach(function(e) {
|
||||
if(D[E[e]] != e) {
|
||||
throw new Error(x + " d.e[" + e + "] = " + D[E[e]] + "; e[" + e + "]=" + E[e] + "; e.d.e[" + e + "] = " + E[D[E[e]]]);
|
||||
}
|
||||
});
|
||||
var corpus = ["foobar"];
|
||||
corpus.forEach(function(w){
|
||||
assert.equal(U.decode(x,U.encode(x,w)),w);
|
||||
});
|
||||
cptable.utils.cache.encache();
|
||||
});
|
||||
}; };
|
||||
describe('cached', function() {
|
||||
Object.keys(cptable).filter(function(w) { return w == +w; }).forEach(chk(cptable, true));
|
||||
});
|
||||
describe('direct', function() {
|
||||
Object.keys(cptable).filter(function(w) { return w == +w; }).forEach(chk(cptable, false));
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The next tests look at possible entry conditions:
|
||||
|
||||
```
|
||||
describe('entry conditions', function() {
|
||||
it('should fail to load utils if cptable unavailable', function() {
|
||||
var sandbox = {};
|
||||
var ctx = vm.createContext(sandbox);
|
||||
assert.throws(function() {
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx);
|
||||
});
|
||||
});
|
||||
it('should load utils if cptable is available', function() {
|
||||
var sandbox = {};
|
||||
var ctx = vm.createContext(sandbox);
|
||||
vm.runInContext(fs.readFileSync('cpexcel.js','utf8'),ctx);
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx);
|
||||
});
|
||||
var chken = function(cp, i) {
|
||||
var c = function(cp, i, e) {
|
||||
var str = cptable.utils.encode(cp,i,e);
|
||||
var arr = cptable.utils.encode(cp,i.split(""),e);
|
||||
assert.deepEqual(str,arr);
|
||||
if(typeof Buffer === 'undefined') return;
|
||||
var buf = cptable.utils.encode(cp,Buffer_from(i),e);
|
||||
assert.deepEqual(str,buf);
|
||||
};
|
||||
cptable.utils.cache.encache();
|
||||
c(cp,i);
|
||||
c(cp,i,'buf');
|
||||
c(cp,i,'arr');
|
||||
c(cp,i,'str');
|
||||
cptable.utils.cache.decache();
|
||||
c(cp,i);
|
||||
c(cp,i,'buf');
|
||||
c(cp,i,'arr');
|
||||
c(cp,i,'str');
|
||||
};
|
||||
describe('encode', function() {
|
||||
it('CP 1252 : sbcs', function() { chken(1252,"foobr"); });
|
||||
it('CP 708 : sbcs', function() { chken(708," and smiley faces");});
|
||||
it('CP 936 : dbcs', function() { chken(936, "");});
|
||||
});
|
||||
var chkde = function(cp, i) {
|
||||
var c = function(cp, i) {
|
||||
var s;
|
||||
if(typeof Buffer !== 'undefined' && i instanceof Buffer) s = [].map.call(i, function(s){return String.fromCharCode(s); });
|
||||
else s=(i.map) ? i.map(function(s){return String.fromCharCode(s); }) : i;
|
||||
var str = cptable.utils.decode(cp,i);
|
||||
var arr = cptable.utils.decode(cp,s.join?s.join(""):s);
|
||||
assert.deepEqual(str,arr);
|
||||
if(typeof Buffer === 'undefined') return;
|
||||
var buf = cptable.utils.decode(cp,Buffer_from(i));
|
||||
assert.deepEqual(str,buf);
|
||||
};
|
||||
cptable.utils.cache.encache();
|
||||
c(cp,i);
|
||||
cptable.utils.cache.decache();
|
||||
c(cp,i);
|
||||
};
|
||||
describe('decode', function() {
|
||||
it('CP 1252 : sbcs', function() { chkde(1252,[0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]); }); /* "foobar" */
|
||||
if(typeof Buffer !== 'undefined') it('CP 708 : sbcs', function() { chkde(708, Buffer_from([0xca, 0x20, 0x61, 0x6e, 0x64, 0x20, 0xcb, 0x20, 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x79, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73])); }); /* (" and smiley faces") */
|
||||
it('CP 936 : dbcs', function() { chkde(936, [0xd5, 0xe2, 0xca, 0xc7, 0xd6, 0xd0, 0xce, 0xc4, 0xd7, 0xd6, 0xb7, 0xfb, 0xb2, 0xe2, 0xca, 0xd4]);}); /* "" */
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `testfile` helper function reads a file and compares to node's read facilities:
|
||||
|
||||
```>test.js
|
||||
function testfile(f,cp,type,skip) {
|
||||
var d = fs.readFileSync(f);
|
||||
var x = fs.readFileSync(f, type);
|
||||
var a = x.split("");
|
||||
var chk = function(cp) {
|
||||
var y = cptable.utils.decode(cp, d);
|
||||
assert.equal(x,y);
|
||||
var z = cptable.utils.encode(cp, x);
|
||||
if(z.length != d.length) throw new Error(f + " " + JSON.stringify(z) + " != " + JSON.stringify(d) + " : " + z.length + " " + d.length);
|
||||
for(var i = 0; i != d.length; ++i) if(d[i] !== z[i]) throw new Error("" + i + " " + d[i] + "!=" + z[i]);
|
||||
if(skip) return;
|
||||
z = cptable.utils.encode(cp, a);
|
||||
if(z.length != d.length) throw new Error(f + " " + JSON.stringify(z) + " != " + JSON.stringify(d) + " : " + z.length + " " + d.length);
|
||||
for(var i = 0; i != d.length; ++i) if(d[i] !== z[i]) throw new Error("" + i + " " + d[i] + "!=" + z[i]);
|
||||
if(f.indexOf("cptable.js") == -1) {
|
||||
cptable.utils.encode(cp, d, 'str');
|
||||
cptable.utils.encode(cp, d, 'arr');
|
||||
}
|
||||
}
|
||||
cptable.utils.cache.encache();
|
||||
chk(cp);
|
||||
if(skip) return;
|
||||
cptable.utils.cache.decache();
|
||||
chk(cp);
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
```
|
||||
|
||||
The `utf8` tests verify UTF-8 encoding of the actual JS sources:
|
||||
|
||||
```>test.js
|
||||
describe('node natives', function() {
|
||||
var node = [[65001, 'utf8',1], [1200, 'utf16le',1], [20127, 'ascii',0]];
|
||||
var unicodefiles = ['codepage.md','README.md','cptable.js'];
|
||||
var asciifiles = ['cputils.js'];
|
||||
node.forEach(function(w) {
|
||||
describe(w[1], function() {
|
||||
cptable = require('./');
|
||||
asciifiles.forEach(function(f) {
|
||||
it('should process ' + f, function() { testfile('./misc/'+f+'.'+w[1],w[0],w[1]); });
|
||||
});
|
||||
if(!w[2]) return;
|
||||
unicodefiles.forEach(function(f) {
|
||||
it('should process ' + f, function() { testfile('./misc/'+f+'.'+w[1],w[0],w[1]); });
|
||||
});
|
||||
if(w[1] === 'utf8') it('should process bits', function() {
|
||||
var files = fs.readdirSync('bits').filter(function(x){return x.substr(-3)==".js";});
|
||||
files.forEach(function(f) { testfile('./bits/' + f,w[0],w[1],true); });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `utf*` and `ascii` tests attempt to test other magic formats:
|
||||
|
||||
```>test.js
|
||||
var m = cptable.utils.magic;
|
||||
function cmp(x,z) {
|
||||
assert.equal(x.length, z.length);
|
||||
for(var i = 0; i != z.length; ++i) assert.equal(i+"/"+x.length+""+x[i], i+"/"+z.length+""+z[i]);
|
||||
}
|
||||
Object.keys(m).forEach(function(t){if(t != 16969) describe(m[t], function() {
|
||||
it("should process codepage.md." + m[t], fs.existsSync('./misc/codepage.md.' + m[t]) ?
|
||||
function() {
|
||||
var b = fs.readFileSync('./misc/codepage.md.utf8', "utf8");
|
||||
if(m[t] === "ascii") b = b.replace(/[\u0080-\uffff]*/g,"");
|
||||
var x = fs.readFileSync('./misc/codepage.md.' + m[t]);
|
||||
var y, z;
|
||||
cptable.utils.cache.encache();
|
||||
y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
z = cptable.utils.encode(t, y);
|
||||
if(t != 65000) cmp(x,z);
|
||||
else { assert.equal(y, cptable.utils.decode(t, z)); }
|
||||
cptable.utils.cache.decache();
|
||||
y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
z = cptable.utils.encode(t, y);
|
||||
if(t != 65000) cmp(x,z);
|
||||
else { assert.equal(y, cptable.utils.decode(t, z)); }
|
||||
cptable.utils.cache.encache();
|
||||
cptable.utils.encode(t, y, 'str');
|
||||
cptable.utils.encode(t, y, 'arr');
|
||||
cptable.utils.cache.decache();
|
||||
cptable.utils.encode(t, y, 'str');
|
||||
cptable.utils.encode(t, y, 'arr');
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
: null);
|
||||
it("should process README.md." + m[t], fs.existsSync('./misc/README.md.' + m[t]) ?
|
||||
function() {
|
||||
var b = fs.readFileSync('./misc/README.md.utf8', "utf8");
|
||||
if(m[t] === "ascii") b = b.replace(/[\u0080-\uffff]*/g,"");
|
||||
var x = fs.readFileSync('./misc/README.md.' + m[t]);
|
||||
x = [].slice.call(x);
|
||||
cptable.utils.cache.encache();
|
||||
var y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
cptable.utils.cache.decache();
|
||||
var y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
: null);
|
||||
});});
|
||||
```
|
||||
|
||||
The codepage `6969` is not defined, so operations should fail:
|
||||
|
||||
```>test.js
|
||||
describe('failures', function() {
|
||||
it('should fail to find CP 6969', function() {
|
||||
assert.throws(function(){cptable[6969].dec});
|
||||
assert.throws(function(){cptable[6969].enc});
|
||||
});
|
||||
it('should fail using utils', function() {
|
||||
assert(!cptable.utils.hascp(6969));
|
||||
assert.throws(function(){return cptable.utils.encode(6969, "foobar"); });
|
||||
assert.throws(function(){return cptable.utils.decode(6969, [0x20]); });
|
||||
});
|
||||
it('should fail with black magic', function() {
|
||||
assert(cptable.utils.hascp(16969));
|
||||
assert.throws(function(){return cptable.utils.encode(16969, "foobar"); });
|
||||
assert.throws(function(){return cptable.utils.decode(16969, [0x20]); });
|
||||
});
|
||||
it('should fail when presented with invalid char codes', function() {
|
||||
assert.throws(function(){cptable.utils.cache.decache(); return cptable.utils.encode(20127, [String.fromCharCode(0xAA)]);});
|
||||
});
|
||||
it('should fail to propagate UTF8 BOM in UTF7', function() {
|
||||
["+/v8-abc", "+/v9"].forEach(function(m) { assert.throws(function() {
|
||||
assert.equal(m, cptable.utils.encode(65000, cptable.utils.decode(65000, m)));
|
||||
}); });
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
# Nitty Gritty
|
||||
|
||||
```json>package.json
|
||||
{
|
||||
"name": "codepage",
|
||||
"version": "1.14.0",
|
||||
"author": "SheetJS",
|
||||
"description": "pure-JS library to handle codepages",
|
||||
"keywords": [ "codepage", "iconv", "convert", "strings" ],
|
||||
"bin": {
|
||||
"codepage": "./bin/codepage.njs"
|
||||
},
|
||||
"main": "cputils.js",
|
||||
"types": "types",
|
||||
"browser": {
|
||||
"buffer": "false"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "~2.14.1",
|
||||
"exit-on-epipe": "~1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"voc": "~1.1.0",
|
||||
"mocha": "~2.5.3",
|
||||
"blanket": "~1.2.3",
|
||||
"@sheetjs/uglify-js": "~2.7.3",
|
||||
"@types/node": "^8.0.7",
|
||||
"@types/commander": "^2.12.0",
|
||||
"dtslint": "^0.1.2",
|
||||
"typescript": "2.2.0"
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-codepage.git"},
|
||||
"scripts": {
|
||||
"pretest": "git submodule init && git submodule update",
|
||||
"test": "make test",
|
||||
"build": "make js",
|
||||
"lint": "make fullint",
|
||||
"dtslint": "dtslint types"
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
"pattern": "[cputils.js]"
|
||||
}
|
||||
},
|
||||
"alex": {
|
||||
"allow": [
|
||||
"chinese",
|
||||
"european",
|
||||
"german",
|
||||
"japanese",
|
||||
"latin"
|
||||
]
|
||||
},
|
||||
"homepage": "http://sheetjs.com/opensource",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"bin",
|
||||
"bits/*.js",
|
||||
"types/index.d.ts",
|
||||
"types/*.json",
|
||||
"cptable.js",
|
||||
"cputils.js",
|
||||
"dist/sbcs.full.js",
|
||||
"dist/cpexcel.full.js"
|
||||
],
|
||||
"bugs": { "url": "https://github.com/SheetJS/js-codepage/issues" },
|
||||
"license": "Apache-2.0",
|
||||
"engines": { "node": ">=0.8" }
|
||||
}
|
||||
```
|
||||
|
||||
```>.vocrc
|
||||
{ "post": "make js" }
|
||||
```
|
||||
|
||||
```>.gitignore
|
||||
node_modules
|
||||
package-lock.json
|
||||
*.tgz
|
||||
.gitignore
|
||||
codepages/
|
||||
.vocrc
|
||||
make.sh
|
||||
make.njs
|
||||
misc/coverage.html
|
||||
codepage_mini.md
|
||||
ctest/sauce*
|
||||
```
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,14 +2,78 @@
|
||||
|
||||
The fields of the +AGA-pages.csv+AGA manifest are +AGA-codepage,url,bytes+AGA (SBCS+AD0-1, DBCS+AD0-2)
|
||||
|
||||
+AGAAYABgAD4-pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
863,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP863.TXT,1
|
||||
864,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP864.TXT,1
|
||||
865,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP865.TXT,1
|
||||
866,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP866.TXT,1
|
||||
869,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP869.TXT,1
|
||||
874,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT,1
|
||||
875,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT,1
|
||||
932,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT,2
|
||||
936,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT,2
|
||||
949,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT,2
|
||||
950,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT,2
|
||||
1026,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT,1
|
||||
1250,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT,1
|
||||
1251,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT,1
|
||||
1252,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT,1
|
||||
1253,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT,1
|
||||
1254,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT,1
|
||||
1255,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT,1
|
||||
1256,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT,1
|
||||
1257,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT,1
|
||||
1258,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT,1
|
||||
47451,http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/ATARIST.TXT,1
|
||||
+AGAAYABg
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private +AGA-0xF8FF+AGA code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
MICSFT. Codepages are an absolute pain :/
|
||||
|
||||
+AGAAYABgAD4-pages.csv
|
||||
10000,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ROMAN.TXT,1
|
||||
10006,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/GREEK.TXT,1
|
||||
10007,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/CYRILLIC.TXT,1
|
||||
10029,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT,1
|
||||
10079,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ICELAND.TXT,1
|
||||
10081,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/TURKISH.TXT,1
|
||||
+AGAAYABg
|
||||
|
||||
The numbering scheme for the +AGA-ISO-8859-X+AGA series is +AGA-28590 +- X+AGA:
|
||||
|
||||
+AGAAYABgAD4-pages.csv
|
||||
28591,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT,1
|
||||
28592,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-2.TXT,1
|
||||
28593,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-3.TXT,1
|
||||
28594,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-4.TXT,1
|
||||
28595,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-5.TXT,1
|
||||
28596,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-6.TXT,1
|
||||
28597,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-7.TXT,1
|
||||
28598,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-8.TXT,1
|
||||
28599,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-9.TXT,1
|
||||
28600,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-10.TXT,1
|
||||
28601,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-11.TXT,1
|
||||
28603,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-13.TXT,1
|
||||
28604,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-14.TXT,1
|
||||
28605,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT,1
|
||||
28606,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-16.TXT,1
|
||||
+AGAAYABg
|
||||
|
||||
+ACMAIw Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
@ -78,6 +142,11 @@ The following codepages are available in .NET on Windows:
|
||||
- 21866 Ukrainian (KOI8-U)+ADs Cyrillic (KOI8-U)
|
||||
- 29001 Europa 3
|
||||
- 38598 ISO 8859-8 Hebrew+ADs Hebrew (ISO-Logical)
|
||||
- 50220 ISO 2022 Japanese with no halfwidth Katakana+ADs Japanese (JIS)
|
||||
- 50221 ISO 2022 Japanese with halfwidth Katakana+ADs Japanese (JIS Allow 1 byte Kana)
|
||||
- 50222 ISO 2022 Japanese JIS X 0201-1989+ADs Japanese (JIS Allow 1 byte Kana - SO/SI)
|
||||
- 50225 ISO 2022 Korean
|
||||
- 50227 ISO 2022 Simplified Chinese+ADs Chinese Simplified (ISO 2022)
|
||||
- 51932 EUC Japanese
|
||||
- 51936 EUC Simplified Chinese+ADs Chinese Simplified (EUC)
|
||||
- 51949 EUC Korean
|
||||
@ -94,11 +163,107 @@ The following codepages are available in .NET on Windows:
|
||||
- 57010 ISCII Gujarati
|
||||
- 57011 ISCII Punjabi
|
||||
|
||||
+AGAAYABgAD4-pages.csv
|
||||
708,,1
|
||||
720,,1
|
||||
808,,1
|
||||
858,,1
|
||||
870,,1
|
||||
872,,1
|
||||
1010,,1
|
||||
1047,,1
|
||||
1132,,1
|
||||
1140,,1
|
||||
1141,,1
|
||||
1142,,1
|
||||
1143,,1
|
||||
1144,,1
|
||||
1145,,1
|
||||
1146,,1
|
||||
1147,,1
|
||||
1148,,1
|
||||
1149,,1
|
||||
1361,,2
|
||||
10001,,2
|
||||
10002,,2
|
||||
10003,,2
|
||||
10004,,1
|
||||
10005,,1
|
||||
10008,,2
|
||||
10010,,1
|
||||
10017,,1
|
||||
10021,,1
|
||||
10082,,1
|
||||
20000,,2
|
||||
20001,,2
|
||||
20002,,2
|
||||
20003,,2
|
||||
20004,,2
|
||||
20005,,2
|
||||
20105,,1
|
||||
20106,,1
|
||||
20107,,1
|
||||
20108,,1
|
||||
20261,,2
|
||||
20269,,1
|
||||
20273,,1
|
||||
20277,,1
|
||||
20278,,1
|
||||
20280,,1
|
||||
20284,,1
|
||||
20285,,1
|
||||
20290,,1
|
||||
20297,,1
|
||||
20420,,1
|
||||
20423,,1
|
||||
20424,,1
|
||||
20833,,1
|
||||
20838,,1
|
||||
20866,,1
|
||||
20871,,1
|
||||
20880,,1
|
||||
20905,,1
|
||||
20924,,1
|
||||
20932,,2
|
||||
20936,,2
|
||||
20949,,2
|
||||
21025,,1
|
||||
21027,,1
|
||||
21866,,1
|
||||
29001,,1
|
||||
38598,,1
|
||||
50220,,2
|
||||
50221,,2
|
||||
50222,,2
|
||||
50225,,2
|
||||
50227,,2
|
||||
51932,,2
|
||||
51936,,2
|
||||
51949,,2
|
||||
52936,,2
|
||||
54936,,2
|
||||
57002,,2
|
||||
57003,,2
|
||||
57004,,2
|
||||
57005,,2
|
||||
57006,,2
|
||||
57007,,2
|
||||
57008,,2
|
||||
57009,,2
|
||||
57010,,2
|
||||
57011,,2
|
||||
+AGAAYABg
|
||||
|
||||
The following codepages are dependencies for Visual FoxPro:
|
||||
|
||||
- 620 Mazovia (Polish) MS-DOS
|
||||
- 895 Kamenick+AP0 (Czech) MS-DOS
|
||||
|
||||
+AGAAYABgAD4-pages.csv
|
||||
620,,1
|
||||
895,,1
|
||||
+AGAAYABg
|
||||
|
||||
+ACMAIw Building Notes
|
||||
|
||||
The script +AGA-make.sh+AGA (described later) will get these files and massage the data
|
||||
@ -124,7 +289,13 @@ which implies that code +AGA-0xF6+AGA is +AGA-String.fromCharCode(0x02C6)+AGA an
|
||||
|
||||
To build the sources on windows, consult +AGA-dotnet/MakeEncoding.cs+AGA.
|
||||
|
||||
After saving standard output to +AGA-out+AGA, the +AGA-dotnet.sh+AGA script processes results.
|
||||
After saving the standard output to +AGA-out+AGA, a simple script processes the result:
|
||||
|
||||
+AGAAYABgAD4-dotnet.sh
|
||||
+ACMAIQ-/bin/bash
|
||||
if +AFs +ACE -e dotnet/out +AF0AOw then exit+ADs fi
|
||||
+ADw-dotnet/out tr -s ' ' '+AFw-t' +AHw awk 'NF+AD4-2 +AHs-if(outfile) close(outfile)+ADs outfile+AD0AIg-codepages/+ACI +ACQ-1 +ACI.TBL+ACIAfQ NF+AD0APQ-2 +AHs-print +AD4 outfile+AH0'
|
||||
+AGAAYABg
|
||||
|
||||
+ACM Building the script
|
||||
|
||||
@ -133,9 +304,43 @@ generates JS code for encoding and decoding:
|
||||
|
||||
+ACMAIw Raw Codepages
|
||||
|
||||
+AGAAYABgAD4-make.njs
|
||||
+ACMAIQ-/usr/bin/env node
|
||||
var argv +AD0 process.argv.slice(1), fs +AD0 require('fs')+ADs
|
||||
if(argv.length +ADw 2) +AHs
|
||||
console.error(+ACI-usage: make.njs +ADw-codepage+AF8-index+AD4 +AFs-variable+AF0AIg)+ADs
|
||||
process.exit(22)+ADs /+ACo EINVAL +ACo-/
|
||||
+AH0
|
||||
|
||||
var cp/+ACo:string+ACo-/ +AD0 argv+AFs-1+AF0AOw
|
||||
var jsvar/+ACo:string+ACo-/ +AD0 argv+AFs-2+AF0 +AHwAfA +ACI-cptable+ACIAOw
|
||||
var x/+ACo:string+ACo-/ +AD0 fs.readFileSync(+ACI-codepages/+ACI +- cp +- +ACI.TBL+ACI,+ACI-utf8+ACI)+ADs
|
||||
var maxcp +AD0 0, i +AD0 0, ii +AD0 0+ADs
|
||||
|
||||
var y/+ACo:Array+ADw-Array+ADw-number+AD4 +AD4AKg-/ +AD0 x.split(+ACIAXA-n+ACI).map(function(z/+ACo:string+ACo-/)/+ACo:Array+ADw-number+AD4AKg-/ +AHs
|
||||
var w/+ACo:Array+ADw-string+AD4AKg-/ +AD0 z.split(+ACIAXA-t+ACI)+ADs
|
||||
if(w.length +ADw 2) return +AFs-Number(w+AFs-0+AF0)+AF0AOw
|
||||
return +AFs-Number(w+AFs-0+AF0), Number(w+AFs-1+AF0)+AF0AOw
|
||||
+AH0).filter(function(z) +AHs return z.length +AD4 1+ADs +AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The DBCS and SBCS code generation strategies are different. The maximum code is
|
||||
used to distinguish (max +AGA-0xFF+AGA for SBCS).
|
||||
|
||||
+AGAAYABg
|
||||
for(i +AD0 0+ADs i +ACEAPQ y.length+ADs +-+-i) if(y+AFs-i+AF0AWw-0+AF0 +AD4 maxcp) maxcp +AD0 y+AFs-i+AF0AWw-0+AF0AOw
|
||||
|
||||
var enc/+ACo:+AHsAWw-key:string+AF0:number+AH0AKg-/ +AD0 +AHsAfQ, dec/+ACo:+AHsAWw-key:string+AF0:string+AH0AfA-Array+ADw-string+AD4AKg-/ +AD0 (maxcp +ADw 256 ? +AFsAXQ : +AHsAfQ)+ADs
|
||||
for(i +AD0 0+ADs i +ACEAPQ y.length+ADs +-+-i) +AHs
|
||||
/+ACo:: if(Array.isArray(dec)) +ACo-/ dec+AFs-y+AFs-i+AF0AWw-0+AF0AXQ +AD0 String.fromCharCode(y+AFs-i+AF0AWw-1+AF0)+ADs
|
||||
enc+AFs-String.fromCharCode(y+AFs-i+AF0AWw-1+AF0)+AF0 +AD0 y+AFs-i+AF0AWw-0+AF0AOw
|
||||
+AH0
|
||||
|
||||
var odec +AD0 +ACIAIg, outstr +AD0 +ACIAIgA7
|
||||
if(maxcp +ADw 256) +AHs
|
||||
/+ACo:: if(Array.isArray(dec)) +AHs +ACo-/
|
||||
+AGAAYABg
|
||||
|
||||
The Unicode character +AGA-0xFFFD+AGA (REPLACEMENT CHARACTER) is used as a placeholder
|
||||
for characters that are not specified in the map (for example, +AGA-0xF0+AGA is not in
|
||||
code page 10000).
|
||||
@ -143,6 +348,14 @@ code page 10000).
|
||||
For SBCS, the idea is to embed a raw string with the contents of the 256 codes.
|
||||
The +AGA-dec+AGA field is merely a split of the string, and +AGA-enc+AGA is an eversion:
|
||||
|
||||
+AGAAYABg
|
||||
for(i +AD0 0+ADs i +ACEAPQ 256+ADs +-+-i) if(typeof dec+AFs-i+AF0 +AD0APQA9 +ACI-undefined+ACI) dec+AFs-i+AF0 +AD0 String.fromCharCode(0xFFFD)+ADs
|
||||
odec +AD0 JSON.stringify(dec.join(+ACIAIg))+ADs
|
||||
outstr +AD0 '(function()+AHs var d +AD0 ' +- odec +- ', D +AD0 +AFsAXQ, e +AD0 +AHsAfQA7 for(var i+AD0-0+ADs-i+ACEAPQ-d.length+ADsAKwAr-i) +AHs if(d.charCodeAt(i) +ACEAPQA9 0xFFFD) e+AFs-d.charAt(i)+AF0 +AD0 i+ADs D+AFs-i+AF0 +AD0 d.charAt(i)+ADs +AH0 return +AHsAIg-enc+ACI: e, +ACI-dec+ACI: D +AH0AOw +AH0)()+ADs'+ADs
|
||||
/+ACo:: +AH0 +ACo-/
|
||||
+AH0 else +AHs
|
||||
+AGAAYABg
|
||||
|
||||
DBCS is similar, except that the space is sliced in chunks of 256 bytes (strings
|
||||
are only generated for those high-bytes represented in the codepage).
|
||||
|
||||
@ -150,6 +363,27 @@ The strategy is to construct an array-of-arrays so that +AGA-dd+AFs-high+AF0AWw-
|
||||
character associated with the code. This array is combined at runtime to yield
|
||||
the complete decoding object (and the encoding object is an eversion):
|
||||
|
||||
+AGAAYABg
|
||||
var dd +AD0 +AFsAXQA7
|
||||
/+ACo:: if(+ACE-Array.isArray(dec)) +AHs +ACo-/
|
||||
for(i in dec) if(dec.hasOwnProperty(i)) +AHs
|
||||
ii +AD0 +-i+ADs
|
||||
if(typeof dd+AFs-ii +AD4APg 8+AF0 +AD0APQA9 +ACI-undefined+ACI) dd+AFs-ii +AD4APg 8+AF0 +AD0 +AFsAXQA7
|
||||
dd+AFs-ii +AD4APg 8+AF0AWw-ii +ACU 256+AF0 +AD0 dec+AFs-i+AF0AOw
|
||||
+AH0
|
||||
/+ACo:: +AH0 +ACo-/
|
||||
outstr +AD0 '(function()+AHs var d +AD0 +AFsAXQ, e +AD0 +AHsAfQ, D +AD0 +AFsAXQ, j+ADsAXA-n'+ADs
|
||||
for(var i +AD0 0+ADs i +ACEAPQ 256+ADs +-+-i) if(dd+AFs-i+AF0) +AHs
|
||||
for(var j +AD0 0+ADs j +ACEAPQ 256+ADs +-+-j) if(typeof dd+AFs-i+AF0AWw-j+AF0 +AD0APQA9 +ACI-undefined+ACI) dd+AFs-i+AF0AWw-j+AF0 +AD0 String.fromCharCode(0xFFFD)+ADs
|
||||
outstr +-+AD0 'D+AFs' +- i +- '+AF0 +AD0 ' +- JSON.stringify(dd+AFs-i+AF0.join(+ACIAIg)) +- '.split(+ACIAIg)+ADsAXA-n'+ADs
|
||||
outstr +-+AD0 'for(j +AD0 0+ADs j +ACEAPQ D+AFs' +- i +- '+AF0.length+ADs +-+-j) if(D+AFs' +- i +- '+AF0AWw-j+AF0.charCodeAt(0) +ACEAPQA9 0xFFFD) +AHs e+AFs-D+AFs' +- i +- '+AF0AWw-j+AF0AXQ +AD0 ' +- (i+ACo-256) +- ' +- j+ADs d+AFs' +- (i+ACo-256) +- ' +- j+AF0 +AD0 D+AFs' +- i +- '+AF0AWw-j+AF0AOwB9AFw-n'
|
||||
+AH0
|
||||
outstr +-+AD0 'return +AHsAIg-enc+ACI: e, +ACI-dec+ACI: d +AH0AOw +AH0)()+ADs'+ADs
|
||||
+AH0
|
||||
process.stdout.write(jsvar +- +ACIAWwAi +- cp +- +ACIAXQ +AD0 +ACI +- outstr +- +ACIAXA-n+ACI)+ADs
|
||||
|
||||
+AGAAYABg
|
||||
|
||||
+AGA-make.sh+AGA generates the tables used by +AGA-make.njs+AGA. The raw Unicode TXT files
|
||||
are columnar: +AGA-code unicode +ACM-comments+AGA. For example, the last 10 lines of the
|
||||
text file +AGA-ROMAN.TXT+AGA (for CP 10000) are:
|
||||
@ -170,6 +404,35 @@ text file +AGA-ROMAN.TXT+AGA (for CP 10000) are:
|
||||
In processing the data, the comments (after the +AGAAIwBg) are stripped and undefined
|
||||
elements (like +AGA-0x7F+AGA for CP 10000) are removed.
|
||||
|
||||
+AGAAYABgAD4-make.sh
|
||||
+ACMAIQ-/bin/bash
|
||||
INFILE+AD0AJAB7-1:-pages.csv+AH0
|
||||
OUTFILE+AD0AJAB7-2:-cptable.js+AH0
|
||||
JSVAR+AD0AJAB7-3:-cptable+AH0
|
||||
VERSION+AD0AJA(cat package.json +AHw grep version +AHw tr -dc +AFs-0-9.+AF0)
|
||||
|
||||
mkdir -p codepages bits
|
||||
rm -f +ACQ-OUTFILE +ACQ-OUTFILE.tmp
|
||||
echo +ACI-/+ACo +ACQ-OUTFILE (C) 2013-present SheetJS -- http://sheetjs.com +ACo-/+ACI +AD4 +ACQ-OUTFILE.tmp
|
||||
echo +ACI-/+ACo-jshint -W100 +ACo-/+ACI +AD4APg +ACQ-OUTFILE.tmp
|
||||
echo +ACI-var +ACQ-JSVAR +AD0 +AHs-version:+AFwAIgAk-VERSION+AFwAIgB9ADsAIg +AD4APg +ACQ-OUTFILE.tmp
|
||||
if +AFs -e dotnet.sh +AF0AOw then bash dotnet.sh+ADs fi
|
||||
awk -F, '+AHs-print +ACQ-1, +ACQ-2, +ACQ-3+AH0' +ACQ-INFILE +AHw while read cp url cptype+ADs do
|
||||
echo +ACQ-cp +ACQ-url
|
||||
if +AFs +ACE -e codepages/+ACQ-cp.TBL +AF0AOw then
|
||||
curl +ACQ-url +AHw sed 's/+ACM.+ACo-//g' +AHw awk 'NF+AD0APQ-2' +AD4 codepages/+ACQ-cp.TBL
|
||||
fi
|
||||
echo +ACI-if(typeof +ACQ-JSVAR +AD0APQA9 'undefined') +ACQ-JSVAR +AD0 +AHsAfQA7ACI +AD4 bits/+ACQ-cp.js.tmp
|
||||
node make.njs +ACQ-cp +ACQ-JSVAR +AHw tee -a bits/+ACQ-cp.js.tmp +AD4APg +ACQ-OUTFILE.tmp
|
||||
sed 's/+ACIAXA(+AFs-0-9+AF0AKwBc)+ACI:/+AFw-1:/g' +ADw-bits/+ACQ-cp.js.tmp +AD4-bits/+ACQ-cp.js
|
||||
rm -f bits/+ACQ-cp.js.tmp
|
||||
done
|
||||
echo +ACI-// eslint-disable-next-line no-undef+ACI +AD4APg +ACQ-OUTFILE.tmp
|
||||
echo +ACI-if (typeof module +ACEAPQA9 'undefined' +ACYAJg module.exports +ACYAJg typeof DO+AF8-NOT+AF8-EXPORT+AF8-CODEPAGE +AD0APQA9 'undefined') module.exports +AD0 +ACQ-JSVAR+ADsAIg +AD4APg +ACQ-OUTFILE.tmp
|
||||
sed 's/+ACIAXA(+AFs-0-9+AF0AKwBc)+ACI:/+AFw-1:/g' +ADwAJA-OUTFILE.tmp +AD4AJA-OUTFILE
|
||||
rm -f +ACQ-OUTFILE.tmp
|
||||
+AGAAYABg
|
||||
|
||||
+ACMAIw Utilities
|
||||
|
||||
The encode and decode functions are kept in a separate script (+AGA-cputils.js+AGA).
|
||||
@ -183,8 +446,412 @@ Both encode and decode deal with data represented as:
|
||||
The +AGA-ofmt+AGA variable controls +AGA-encode+AGA output (+AGA-str+AGA, +AGA-arr+AGA respectively)
|
||||
while the input format is automatically determined.
|
||||
|
||||
+ACM Tests
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
var fs +AD0 require('fs'), assert +AD0 require('assert'), vm +AD0 require('vm')+ADs
|
||||
var cptable, sbcs+ADs
|
||||
|
||||
+AGAAYABg
|
||||
|
||||
Due to a bug in +AGA-Buffer.from+AGA in node +AGA-4.0 - 4.4+AGA, a special check is needed:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
var Buffer+AF8-from +AD0 function()+AHsAfQA7
|
||||
|
||||
if(typeof Buffer +ACEAPQA9 'undefined') +AHs
|
||||
var nbfs +AD0 +ACE-Buffer.from+ADs
|
||||
if(+ACE-nbfs) try +AHs Buffer.from(+ACI-foo+ACI, +ACI-utf8+ACI)+ADs +AH0 catch(e) +AHs nbfs +AD0 true+ADs +AH0
|
||||
Buffer+AF8-from +AD0 nbfs ? function(buf, enc) +AHs return (enc) ? new Buffer(buf, enc) : new Buffer(buf)+ADs +AH0 : Buffer.from.bind(Buffer)+ADs
|
||||
+AH0
|
||||
|
||||
+AGAAYABg
|
||||
|
||||
The tests include JS validity tests (requiring or evaluating code):
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
describe('source', function() +AHs
|
||||
it('should load node', function() +AHs cptable +AD0 require('./')+ADs +AH0)+ADs
|
||||
it('should load sbcs', function() +AHs sbcs +AD0 require('./sbcs')+ADs +AH0)+ADs
|
||||
it('should load excel', function() +AHs excel +AD0 require('./cpexcel')+ADs +AH0)+ADs
|
||||
it('should process bits', function() +AHs
|
||||
var files +AD0 fs.readdirSync('bits').filter(function(x)+AHs-return x.substr(-3)+AD0APQAi.js+ACIAOwB9)+ADs
|
||||
files.forEach(function(x) +AHs
|
||||
vm.runInThisContext(fs.readFileSync('./bits/' +- x))+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The README tests verify the snippets in the README:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
describe('README', function() +AHs
|
||||
var readme +AD0 function() +AHs
|
||||
var unicode+AF8-cp10000+AF8-255 +AD0 cptable+AFs-10000+AF0.dec+AFs-255+AF0AOw // +Asc
|
||||
assert.equal(unicode+AF8-cp10000+AF8-255, +ACICxwAi)+ADs
|
||||
|
||||
var cp10000+AF8-711 +AD0 cptable+AFs-10000+AF0.enc+AFs-String.fromCharCode(711)+AF0AOw // 255
|
||||
assert.equal(cp10000+AF8-711, 255)+ADs
|
||||
|
||||
var b1 +AD0 +AFs-0xbb,0xe3,0xd7,0xdc+AF0AOw
|
||||
var s1 +AD0 b1.map(function(x) +AHs return String.fromCharCode(x)+ADs +AH0).join(+ACIAIg)+ADs
|
||||
var +bEdgOw +AD0 cptable.utils.decode(936, b1)+ADs
|
||||
var buf +AD0 cptable.utils.encode(936, +bEdgOw)+ADs
|
||||
assert.equal(+bEdgOw,+ACJsR2A7ACI)+ADs
|
||||
assert.equal(buf.length, 4)+ADs
|
||||
for(var i +AD0 0+ADs i +ACEAPQ 4+ADs +-+-i) assert.equal(b1+AFs-i+AF0, buf+AFs-i+AF0)+ADs
|
||||
|
||||
var b2 +AD0 +AFs-0xf0,0x9f,0x8d,0xa3+AF0AOw
|
||||
var sushi+AD0 cptable.utils.decode(65001, b2)+ADs
|
||||
var sbuf +AD0 cptable.utils.encode(65001, sushi)+ADs
|
||||
assert.equal(sushi,+ACLYPN9jACI)+ADs
|
||||
assert.equal(sbuf.length, 4)+ADs
|
||||
for(var i +AD0 0+ADs i +ACEAPQ 4+ADs +-+-i) assert.equal(b2+AFs-i+AF0, sbuf+AFs-i+AF0)+ADs
|
||||
|
||||
+AH0AOw
|
||||
it('should be correct', function() +AHs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
readme()+ADs
|
||||
cptable.utils.cache.decache()+ADs
|
||||
readme()+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The consistency tests make sure that encoding and decoding are pseudo inverses:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
describe('consistency', function() +AHs
|
||||
cptable +AD0 require('./')+ADs
|
||||
U +AD0 cptable.utils+ADs
|
||||
var chk +AD0 function(cptable, cacheit) +AHs return function(x) +AHs
|
||||
it('should consistently process CP ' +- x, function() +AHs
|
||||
var cp +AD0 cptable+AFs-x+AF0, D +AD0 cp.dec, E +AD0 cp.enc+ADs
|
||||
if(cacheit) cptable.utils.cache.encache()+ADs
|
||||
else cptable.utils.cache.decache()+ADs
|
||||
Object.keys(D).forEach(function(d) +AHs
|
||||
if(E+AFs-D+AFs-d+AF0AXQ +ACEAPQ d) +AHs
|
||||
if(typeof E+AFs-D+AFs-d+AF0AXQ +ACEAPQA9 +ACI-undefined+ACI) return+ADs
|
||||
if(D+AFs-d+AF0.charCodeAt(0) +AD0APQ 0xFFFD) return+ADs
|
||||
if(D+AFs-E+AFs-D+AFs-d+AF0AXQBd +AD0APQA9 D+AFs-d+AF0) return+ADs
|
||||
throw new Error(x +- +ACI e.d+AFsAIg +- d +- +ACIAXQ +AD0 +ACI +- E+AFs-D+AFs-d+AF0AXQ +- +ACIAOw d+AFsAIg +- d +- +ACIAXQA9ACI +- D+AFs-d+AF0 +- +ACIAOw d.e.d+AFsAIg +- d +- +ACIAXQ +AD0 +ACI +- D+AFs-E+AFs-D+AFs-d+AF0AXQBd)+ADs
|
||||
+AH0
|
||||
+AH0)+ADs
|
||||
Object.keys(E).forEach(function(e) +AHs
|
||||
if(D+AFs-E+AFs-e+AF0AXQ +ACEAPQ e) +AHs
|
||||
throw new Error(x +- +ACI d.e+AFsAIg +- e +- +ACIAXQ +AD0 +ACI +- D+AFs-E+AFs-e+AF0AXQ +- +ACIAOw e+AFsAIg +- e +- +ACIAXQA9ACI +- E+AFs-e+AF0 +- +ACIAOw e.d.e+AFsAIg +- e +- +ACIAXQ +AD0 +ACI +- E+AFs-D+AFs-E+AFs-e+AF0AXQBd)+ADs
|
||||
+AH0
|
||||
+AH0)+ADs
|
||||
var corpus +AD0 +AFsAIg-foobar+ACIAXQA7
|
||||
corpus.forEach(function(w)+AHs
|
||||
assert.equal(U.decode(x,U.encode(x,w)),w)+ADs
|
||||
+AH0)+ADs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
+AH0)+ADs
|
||||
+AH0AOw +AH0AOw
|
||||
describe('cached', function() +AHs
|
||||
Object.keys(cptable).filter(function(w) +AHs return w +AD0APQ +-w+ADs +AH0).forEach(chk(cptable, true))+ADs
|
||||
+AH0)+ADs
|
||||
describe('direct', function() +AHs
|
||||
Object.keys(cptable).filter(function(w) +AHs return w +AD0APQ +-w+ADs +AH0).forEach(chk(cptable, false))+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The next tests look at possible entry conditions:
|
||||
|
||||
+AGAAYABg
|
||||
describe('entry conditions', function() +AHs
|
||||
it('should fail to load utils if cptable unavailable', function() +AHs
|
||||
var sandbox +AD0 +AHsAfQA7
|
||||
var ctx +AD0 vm.createContext(sandbox)+ADs
|
||||
assert.throws(function() +AHs
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx)+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
it('should load utils if cptable is available', function() +AHs
|
||||
var sandbox +AD0 +AHsAfQA7
|
||||
var ctx +AD0 vm.createContext(sandbox)+ADs
|
||||
vm.runInContext(fs.readFileSync('cpexcel.js','utf8'),ctx)+ADs
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx)+ADs
|
||||
+AH0)+ADs
|
||||
var chken +AD0 function(cp, i) +AHs
|
||||
var c +AD0 function(cp, i, e) +AHs
|
||||
var str +AD0 cptable.utils.encode(cp,i,e)+ADs
|
||||
var arr +AD0 cptable.utils.encode(cp,i.split(+ACIAIg),e)+ADs
|
||||
assert.deepEqual(str,arr)+ADs
|
||||
if(typeof Buffer +AD0APQA9 'undefined') return+ADs
|
||||
var buf +AD0 cptable.utils.encode(cp,Buffer+AF8-from(i),e)+ADs
|
||||
assert.deepEqual(str,buf)+ADs
|
||||
+AH0AOw
|
||||
cptable.utils.cache.encache()+ADs
|
||||
c(cp,i)+ADs
|
||||
c(cp,i,'buf')+ADs
|
||||
c(cp,i,'arr')+ADs
|
||||
c(cp,i,'str')+ADs
|
||||
cptable.utils.cache.decache()+ADs
|
||||
c(cp,i)+ADs
|
||||
c(cp,i,'buf')+ADs
|
||||
c(cp,i,'arr')+ADs
|
||||
c(cp,i,'str')+ADs
|
||||
+AH0AOw
|
||||
describe('encode', function() +AHs
|
||||
it('CP 1252 : sbcs', function() +AHs chken(1252,+ACI-foo+ICI-b+AP4-r+ACI)+ADs +AH0)+ADs
|
||||
it('CP 708 : sbcs', function() +AHs chken(708,+ACIGKg and +Bis smiley faces+ACI)+ADsAfQ)+ADs
|
||||
it('CP 936 : dbcs', function() +AHs chken(936, +ACKP2WYvTi1lh1tXeyZtS4vVACI)+ADsAfQ)+ADs
|
||||
+AH0)+ADs
|
||||
var chkde +AD0 function(cp, i) +AHs
|
||||
var c +AD0 function(cp, i) +AHs
|
||||
var s+ADs
|
||||
if(typeof Buffer +ACEAPQA9 'undefined' +ACYAJg i instanceof Buffer) s +AD0 +AFsAXQ.map.call(i, function(s)+AHs-return String.fromCharCode(s)+ADs +AH0)+ADs
|
||||
else s+AD0(i.map) ? i.map(function(s)+AHs-return String.fromCharCode(s)+ADs +AH0) : i+ADs
|
||||
var str +AD0 cptable.utils.decode(cp,i)+ADs
|
||||
var arr +AD0 cptable.utils.decode(cp,s.join?s.join(+ACIAIg):s)+ADs
|
||||
assert.deepEqual(str,arr)+ADs
|
||||
if(typeof Buffer +AD0APQA9 'undefined') return+ADs
|
||||
var buf +AD0 cptable.utils.decode(cp,Buffer+AF8-from(i))+ADs
|
||||
assert.deepEqual(str,buf)+ADs
|
||||
+AH0AOw
|
||||
cptable.utils.cache.encache()+ADs
|
||||
c(cp,i)+ADs
|
||||
cptable.utils.cache.decache()+ADs
|
||||
c(cp,i)+ADs
|
||||
+AH0AOw
|
||||
describe('decode', function() +AHs
|
||||
it('CP 1252 : sbcs', function() +AHs chkde(1252,+AFs-0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72+AF0)+ADs +AH0)+ADs /+ACo +ACI-foobar+ACI +ACo-/
|
||||
if(typeof Buffer +ACEAPQA9 'undefined') it('CP 708 : sbcs', function() +AHs chkde(708, Buffer+AF8-from(+AFs-0xca, 0x20, 0x61, 0x6e, 0x64, 0x20, 0xcb, 0x20, 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x79, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73+AF0))+ADs +AH0)+ADs /+ACo (+ACIGKg and +Bis smiley faces+ACI) +ACo-/
|
||||
it('CP 936 : dbcs', function() +AHs chkde(936, +AFs-0xd5, 0xe2, 0xca, 0xc7, 0xd6, 0xd0, 0xce, 0xc4, 0xd7, 0xd6, 0xb7, 0xfb, 0xb2, 0xe2, 0xca, 0xd4+AF0)+ADsAfQ)+ADs /+ACo +ACKP2WYvTi1lh1tXeyZtS4vVACI +ACo-/
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The +AGA-testfile+AGA helper function reads a file and compares to node's read facilities:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
function testfile(f,cp,type,skip) +AHs
|
||||
var d +AD0 fs.readFileSync(f)+ADs
|
||||
var x +AD0 fs.readFileSync(f, type)+ADs
|
||||
var a +AD0 x.split(+ACIAIg)+ADs
|
||||
var chk +AD0 function(cp) +AHs
|
||||
var y +AD0 cptable.utils.decode(cp, d)+ADs
|
||||
assert.equal(x,y)+ADs
|
||||
var z +AD0 cptable.utils.encode(cp, x)+ADs
|
||||
if(z.length +ACEAPQ d.length) throw new Error(f +- +ACI +ACI +- JSON.stringify(z) +- +ACI +ACEAPQ +ACI +- JSON.stringify(d) +- +ACI : +ACI +- z.length +- +ACI +ACI +- d.length)+ADs
|
||||
for(var i +AD0 0+ADs i +ACEAPQ d.length+ADs +-+-i) if(d+AFs-i+AF0 +ACEAPQA9 z+AFs-i+AF0) throw new Error(+ACIAIg +- i +- +ACI +ACI +- d+AFs-i+AF0 +- +ACIAIQA9ACI +- z+AFs-i+AF0)+ADs
|
||||
if(skip) return+ADs
|
||||
z +AD0 cptable.utils.encode(cp, a)+ADs
|
||||
if(z.length +ACEAPQ d.length) throw new Error(f +- +ACI +ACI +- JSON.stringify(z) +- +ACI +ACEAPQ +ACI +- JSON.stringify(d) +- +ACI : +ACI +- z.length +- +ACI +ACI +- d.length)+ADs
|
||||
for(var i +AD0 0+ADs i +ACEAPQ d.length+ADs +-+-i) if(d+AFs-i+AF0 +ACEAPQA9 z+AFs-i+AF0) throw new Error(+ACIAIg +- i +- +ACI +ACI +- d+AFs-i+AF0 +- +ACIAIQA9ACI +- z+AFs-i+AF0)+ADs
|
||||
if(f.indexOf(+ACI-cptable.js+ACI) +AD0APQ -1) +AHs
|
||||
cptable.utils.encode(cp, d, 'str')+ADs
|
||||
cptable.utils.encode(cp, d, 'arr')+ADs
|
||||
+AH0
|
||||
+AH0
|
||||
cptable.utils.cache.encache()+ADs
|
||||
chk(cp)+ADs
|
||||
if(skip) return+ADs
|
||||
cptable.utils.cache.decache()+ADs
|
||||
chk(cp)+ADs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
+AH0
|
||||
+AGAAYABg
|
||||
|
||||
The +AGA-utf8+AGA tests verify UTF-8 encoding of the actual JS sources:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
describe('node natives', function() +AHs
|
||||
var node +AD0 +AFsAWw-65001, 'utf8',1+AF0, +AFs-1200, 'utf16le',1+AF0, +AFs-20127, 'ascii',0+AF0AXQA7
|
||||
var unicodefiles +AD0 +AFs'codepage.md','README.md','cptable.js'+AF0AOw
|
||||
var asciifiles +AD0 +AFs'cputils.js'+AF0AOw
|
||||
node.forEach(function(w) +AHs
|
||||
describe(w+AFs-1+AF0, function() +AHs
|
||||
cptable +AD0 require('./')+ADs
|
||||
asciifiles.forEach(function(f) +AHs
|
||||
it('should process ' +- f, function() +AHs testfile('./misc/'+-f+-'.'+-w+AFs-1+AF0,w+AFs-0+AF0,w+AFs-1+AF0)+ADs +AH0)+ADs
|
||||
+AH0)+ADs
|
||||
if(+ACE-w+AFs-2+AF0) return+ADs
|
||||
unicodefiles.forEach(function(f) +AHs
|
||||
it('should process ' +- f, function() +AHs testfile('./misc/'+-f+-'.'+-w+AFs-1+AF0,w+AFs-0+AF0,w+AFs-1+AF0)+ADs +AH0)+ADs
|
||||
+AH0)+ADs
|
||||
if(w+AFs-1+AF0 +AD0APQA9 'utf8') it('should process bits', function() +AHs
|
||||
var files +AD0 fs.readdirSync('bits').filter(function(x)+AHs-return x.substr(-3)+AD0APQAi.js+ACIAOwB9)+ADs
|
||||
files.forEach(function(f) +AHs testfile('./bits/' +- f,w+AFs-0+AF0,w+AFs-1+AF0,true)+ADs +AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The +AGA-utf+ACoAYA and +AGA-ascii+AGA tests attempt to test other magic formats:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
var m +AD0 cptable.utils.magic+ADs
|
||||
function cmp(x,z) +AHs
|
||||
assert.equal(x.length, z.length)+ADs
|
||||
for(var i +AD0 0+ADs i +ACEAPQ z.length+ADs +-+-i) assert.equal(i+-+ACI-/+ACIAKw-x.length+-+ACIAIgAr-x+AFs-i+AF0, i+-+ACI-/+ACIAKw-z.length+-+ACIAIgAr-z+AFs-i+AF0)+ADs
|
||||
+AH0
|
||||
Object.keys(m).forEach(function(t)+AHs-if(t +ACEAPQ 16969) describe(m+AFs-t+AF0, function() +AHs
|
||||
it(+ACI-should process codepage.md.+ACI +- m+AFs-t+AF0, fs.existsSync('./misc/codepage.md.' +- m+AFs-t+AF0) ?
|
||||
function() +AHs
|
||||
var b +AD0 fs.readFileSync('./misc/codepage.md.utf8', +ACI-utf8+ACI)+ADs
|
||||
if(m+AFs-t+AF0 +AD0APQA9 +ACI-ascii+ACI) b +AD0 b.replace(/+AFsAXA-u0080-+AFw-uffff+AF0AKg-/g,+ACIAIg)+ADs
|
||||
var x +AD0 fs.readFileSync('./misc/codepage.md.' +- m+AFs-t+AF0)+ADs
|
||||
var y, z+ADs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
y +AD0 cptable.utils.decode(t, x)+ADs
|
||||
assert.equal(y,b)+ADs
|
||||
z +AD0 cptable.utils.encode(t, y)+ADs
|
||||
if(t +ACEAPQ 65000) cmp(x,z)+ADs
|
||||
else +AHs assert.equal(y, cptable.utils.decode(t, z))+ADs +AH0
|
||||
cptable.utils.cache.decache()+ADs
|
||||
y +AD0 cptable.utils.decode(t, x)+ADs
|
||||
assert.equal(y,b)+ADs
|
||||
z +AD0 cptable.utils.encode(t, y)+ADs
|
||||
if(t +ACEAPQ 65000) cmp(x,z)+ADs
|
||||
else +AHs assert.equal(y, cptable.utils.decode(t, z))+ADs +AH0
|
||||
cptable.utils.cache.encache()+ADs
|
||||
cptable.utils.encode(t, y, 'str')+ADs
|
||||
cptable.utils.encode(t, y, 'arr')+ADs
|
||||
cptable.utils.cache.decache()+ADs
|
||||
cptable.utils.encode(t, y, 'str')+ADs
|
||||
cptable.utils.encode(t, y, 'arr')+ADs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
+AH0
|
||||
: null)+ADs
|
||||
it(+ACI-should process README.md.+ACI +- m+AFs-t+AF0, fs.existsSync('./misc/README.md.' +- m+AFs-t+AF0) ?
|
||||
function() +AHs
|
||||
var b +AD0 fs.readFileSync('./misc/README.md.utf8', +ACI-utf8+ACI)+ADs
|
||||
if(m+AFs-t+AF0 +AD0APQA9 +ACI-ascii+ACI) b +AD0 b.replace(/+AFsAXA-u0080-+AFw-uffff+AF0AKg-/g,+ACIAIg)+ADs
|
||||
var x +AD0 fs.readFileSync('./misc/README.md.' +- m+AFs-t+AF0)+ADs
|
||||
x +AD0 +AFsAXQ.slice.call(x)+ADs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
var y +AD0 cptable.utils.decode(t, x)+ADs
|
||||
assert.equal(y,b)+ADs
|
||||
cptable.utils.cache.decache()+ADs
|
||||
var y +AD0 cptable.utils.decode(t, x)+ADs
|
||||
assert.equal(y,b)+ADs
|
||||
cptable.utils.cache.encache()+ADs
|
||||
+AH0
|
||||
: null)+ADs
|
||||
+AH0)+ADsAfQ)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
The codepage +AGA-6969+AGA is not defined, so operations should fail:
|
||||
|
||||
+AGAAYABgAD4-test.js
|
||||
describe('failures', function() +AHs
|
||||
it('should fail to find CP 6969', function() +AHs
|
||||
assert.throws(function()+AHs-cptable+AFs-6969+AF0.dec+AH0)+ADs
|
||||
assert.throws(function()+AHs-cptable+AFs-6969+AF0.enc+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
it('should fail using utils', function() +AHs
|
||||
assert(+ACE-cptable.utils.hascp(6969))+ADs
|
||||
assert.throws(function()+AHs-return cptable.utils.encode(6969, +ACI-foobar+ACI)+ADs +AH0)+ADs
|
||||
assert.throws(function()+AHs-return cptable.utils.decode(6969, +AFs-0x20+AF0)+ADs +AH0)+ADs
|
||||
+AH0)+ADs
|
||||
it('should fail with black magic', function() +AHs
|
||||
assert(cptable.utils.hascp(16969))+ADs
|
||||
assert.throws(function()+AHs-return cptable.utils.encode(16969, +ACI-foobar+ACI)+ADs +AH0)+ADs
|
||||
assert.throws(function()+AHs-return cptable.utils.decode(16969, +AFs-0x20+AF0)+ADs +AH0)+ADs
|
||||
+AH0)+ADs
|
||||
it('should fail when presented with invalid char codes', function() +AHs
|
||||
assert.throws(function()+AHs-cptable.utils.cache.decache()+ADs return cptable.utils.encode(20127, +AFs-String.fromCharCode(0xAA)+AF0)+ADsAfQ)+ADs
|
||||
+AH0)+ADs
|
||||
it('should fail to propagate UTF8 BOM in UTF7', function() +AHs
|
||||
+AFsAIgAr-/v8-abc+ACI, +ACIAKw-/v9+ACIAXQ.forEach(function(m) +AHs assert.throws(function() +AHs
|
||||
assert.equal(m, cptable.utils.encode(65000, cptable.utils.decode(65000, m)))+ADs
|
||||
+AH0)+ADs +AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AH0)+ADs
|
||||
+AGAAYABg
|
||||
|
||||
+ACM Nitty Gritty
|
||||
|
||||
+AGAAYABg-json+AD4-package.json
|
||||
+AHs
|
||||
+ACI-name+ACI: +ACI-codepage+ACI,
|
||||
+ACI-version+ACI: +ACI-1.14.0+ACI,
|
||||
+ACI-author+ACI: +ACI-SheetJS+ACI,
|
||||
+ACI-description+ACI: +ACI-pure-JS library to handle codepages+ACI,
|
||||
+ACI-keywords+ACI: +AFs +ACI-codepage+ACI, +ACI-iconv+ACI, +ACI-convert+ACI, +ACI-strings+ACI +AF0,
|
||||
+ACI-bin+ACI: +AHs
|
||||
+ACI-codepage+ACI: +ACI./bin/codepage.njs+ACI
|
||||
+AH0,
|
||||
+ACI-main+ACI: +ACI-cputils.js+ACI,
|
||||
+ACI-types+ACI: +ACI-types+ACI,
|
||||
+ACI-browser+ACI: +AHs
|
||||
+ACI-buffer+ACI: +ACI-false+ACI
|
||||
+AH0,
|
||||
+ACI-dependencies+ACI: +AHs
|
||||
+ACI-commander+ACI: +ACIAfg-2.14.1+ACI,
|
||||
+ACI-exit-on-epipe+ACI: +ACIAfg-1.0.1+ACI
|
||||
+AH0,
|
||||
+ACI-devDependencies+ACI: +AHs
|
||||
+ACI-voc+ACI: +ACIAfg-1.1.0+ACI,
|
||||
+ACI-mocha+ACI: +ACIAfg-2.5.3+ACI,
|
||||
+ACI-blanket+ACI: +ACIAfg-1.2.3+ACI,
|
||||
+ACIAQA-sheetjs/uglify-js+ACI: +ACIAfg-2.7.3+ACI,
|
||||
+ACIAQA-types/node+ACI: +ACIAXg-8.0.7+ACI,
|
||||
+ACIAQA-types/commander+ACI: +ACIAXg-2.12.0+ACI,
|
||||
+ACI-dtslint+ACI: +ACIAXg-0.1.2+ACI,
|
||||
+ACI-typescript+ACI: +ACI-2.2.0+ACI
|
||||
+AH0,
|
||||
+ACI-repository+ACI: +AHs +ACI-type+ACI:+ACI-git+ACI, +ACI-url+ACI:+ACI-git://github.com/SheetJS/js-codepage.git+ACIAfQ,
|
||||
+ACI-scripts+ACI: +AHs
|
||||
+ACI-pretest+ACI: +ACI-git submodule init +ACYAJg git submodule update+ACI,
|
||||
+ACI-test+ACI: +ACI-make test+ACI,
|
||||
+ACI-build+ACI: +ACI-make js+ACI,
|
||||
+ACI-lint+ACI: +ACI-make fullint+ACI,
|
||||
+ACI-dtslint+ACI: +ACI-dtslint types+ACI
|
||||
+AH0,
|
||||
+ACI-config+ACI: +AHs
|
||||
+ACI-blanket+ACI: +AHs
|
||||
+ACI-pattern+ACI: +ACIAWw-cputils.js+AF0AIg
|
||||
+AH0
|
||||
+AH0,
|
||||
+ACI-alex+ACI: +AHs
|
||||
+ACI-allow+ACI: +AFs
|
||||
+ACI-chinese+ACI,
|
||||
+ACI-european+ACI,
|
||||
+ACI-german+ACI,
|
||||
+ACI-japanese+ACI,
|
||||
+ACI-latin+ACI
|
||||
+AF0
|
||||
+AH0,
|
||||
+ACI-homepage+ACI: +ACI-http://sheetjs.com/opensource+ACI,
|
||||
+ACI-files+ACI: +AFs
|
||||
+ACI-LICENSE+ACI,
|
||||
+ACI-README.md+ACI,
|
||||
+ACI-bin+ACI,
|
||||
+ACI-bits/+ACo.js+ACI,
|
||||
+ACI-types/index.d.ts+ACI,
|
||||
+ACI-types/+ACo.json+ACI,
|
||||
+ACI-cptable.js+ACI,
|
||||
+ACI-cputils.js+ACI,
|
||||
+ACI-dist/sbcs.full.js+ACI,
|
||||
+ACI-dist/cpexcel.full.js+ACI
|
||||
+AF0,
|
||||
+ACI-bugs+ACI: +AHs +ACI-url+ACI: +ACI-https://github.com/SheetJS/js-codepage/issues+ACI +AH0,
|
||||
+ACI-license+ACI: +ACI-Apache-2.0+ACI,
|
||||
+ACI-engines+ACI: +AHs +ACI-node+ACI: +ACIAPgA9-0.8+ACI +AH0
|
||||
+AH0
|
||||
+AGAAYABg
|
||||
|
||||
+AGAAYABgAD4.vocrc
|
||||
+AHs +ACI-post+ACI: +ACI-make js+ACI +AH0
|
||||
+AGAAYABg
|
||||
|
||||
+AGAAYABgAD4.gitignore
|
||||
node+AF8-modules
|
||||
package-lock.json
|
||||
+ACo.tgz
|
||||
.gitignore
|
||||
codepages/
|
||||
.vocrc
|
||||
make.sh
|
||||
make.njs
|
||||
misc/coverage.html
|
||||
codepage+AF8-mini.md
|
||||
ctest/sauce+ACo
|
||||
+AGAAYABg
|
||||
|
@ -2,14 +2,78 @@
|
||||
|
||||
The fields of the `pages.csv` manifest are `codepage,url,bytes` (SBCS=1, DBCS=2)
|
||||
|
||||
```>pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
863,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP863.TXT,1
|
||||
864,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP864.TXT,1
|
||||
865,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP865.TXT,1
|
||||
866,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP866.TXT,1
|
||||
869,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP869.TXT,1
|
||||
874,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT,1
|
||||
875,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT,1
|
||||
932,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT,2
|
||||
936,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT,2
|
||||
949,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT,2
|
||||
950,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT,2
|
||||
1026,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT,1
|
||||
1250,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT,1
|
||||
1251,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT,1
|
||||
1252,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT,1
|
||||
1253,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT,1
|
||||
1254,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT,1
|
||||
1255,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT,1
|
||||
1256,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT,1
|
||||
1257,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT,1
|
||||
1258,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT,1
|
||||
47451,http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/ATARIST.TXT,1
|
||||
```
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private `0xF8FF` code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
MICSFT. Codepages are an absolute pain :/
|
||||
|
||||
```>pages.csv
|
||||
10000,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ROMAN.TXT,1
|
||||
10006,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/GREEK.TXT,1
|
||||
10007,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/CYRILLIC.TXT,1
|
||||
10029,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT,1
|
||||
10079,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ICELAND.TXT,1
|
||||
10081,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/TURKISH.TXT,1
|
||||
```
|
||||
|
||||
The numbering scheme for the `ISO-8859-X` series is `28590 + X`:
|
||||
|
||||
```>pages.csv
|
||||
28591,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT,1
|
||||
28592,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-2.TXT,1
|
||||
28593,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-3.TXT,1
|
||||
28594,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-4.TXT,1
|
||||
28595,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-5.TXT,1
|
||||
28596,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-6.TXT,1
|
||||
28597,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-7.TXT,1
|
||||
28598,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-8.TXT,1
|
||||
28599,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-9.TXT,1
|
||||
28600,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-10.TXT,1
|
||||
28601,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-11.TXT,1
|
||||
28603,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-13.TXT,1
|
||||
28604,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-14.TXT,1
|
||||
28605,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT,1
|
||||
28606,http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-16.TXT,1
|
||||
```
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
@ -78,6 +142,11 @@ The following codepages are available in .NET on Windows:
|
||||
- 21866 Ukrainian (KOI8-U); Cyrillic (KOI8-U)
|
||||
- 29001 Europa 3
|
||||
- 38598 ISO 8859-8 Hebrew; Hebrew (ISO-Logical)
|
||||
- 50220 ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
|
||||
- 50221 ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS Allow 1 byte Kana)
|
||||
- 50222 ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS Allow 1 byte Kana - SO/SI)
|
||||
- 50225 ISO 2022 Korean
|
||||
- 50227 ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)
|
||||
- 51932 EUC Japanese
|
||||
- 51936 EUC Simplified Chinese; Chinese Simplified (EUC)
|
||||
- 51949 EUC Korean
|
||||
@ -94,11 +163,107 @@ The following codepages are available in .NET on Windows:
|
||||
- 57010 ISCII Gujarati
|
||||
- 57011 ISCII Punjabi
|
||||
|
||||
```>pages.csv
|
||||
708,,1
|
||||
720,,1
|
||||
808,,1
|
||||
858,,1
|
||||
870,,1
|
||||
872,,1
|
||||
1010,,1
|
||||
1047,,1
|
||||
1132,,1
|
||||
1140,,1
|
||||
1141,,1
|
||||
1142,,1
|
||||
1143,,1
|
||||
1144,,1
|
||||
1145,,1
|
||||
1146,,1
|
||||
1147,,1
|
||||
1148,,1
|
||||
1149,,1
|
||||
1361,,2
|
||||
10001,,2
|
||||
10002,,2
|
||||
10003,,2
|
||||
10004,,1
|
||||
10005,,1
|
||||
10008,,2
|
||||
10010,,1
|
||||
10017,,1
|
||||
10021,,1
|
||||
10082,,1
|
||||
20000,,2
|
||||
20001,,2
|
||||
20002,,2
|
||||
20003,,2
|
||||
20004,,2
|
||||
20005,,2
|
||||
20105,,1
|
||||
20106,,1
|
||||
20107,,1
|
||||
20108,,1
|
||||
20261,,2
|
||||
20269,,1
|
||||
20273,,1
|
||||
20277,,1
|
||||
20278,,1
|
||||
20280,,1
|
||||
20284,,1
|
||||
20285,,1
|
||||
20290,,1
|
||||
20297,,1
|
||||
20420,,1
|
||||
20423,,1
|
||||
20424,,1
|
||||
20833,,1
|
||||
20838,,1
|
||||
20866,,1
|
||||
20871,,1
|
||||
20880,,1
|
||||
20905,,1
|
||||
20924,,1
|
||||
20932,,2
|
||||
20936,,2
|
||||
20949,,2
|
||||
21025,,1
|
||||
21027,,1
|
||||
21866,,1
|
||||
29001,,1
|
||||
38598,,1
|
||||
50220,,2
|
||||
50221,,2
|
||||
50222,,2
|
||||
50225,,2
|
||||
50227,,2
|
||||
51932,,2
|
||||
51936,,2
|
||||
51949,,2
|
||||
52936,,2
|
||||
54936,,2
|
||||
57002,,2
|
||||
57003,,2
|
||||
57004,,2
|
||||
57005,,2
|
||||
57006,,2
|
||||
57007,,2
|
||||
57008,,2
|
||||
57009,,2
|
||||
57010,,2
|
||||
57011,,2
|
||||
```
|
||||
|
||||
The following codepages are dependencies for Visual FoxPro:
|
||||
|
||||
- 620 Mazovia (Polish) MS-DOS
|
||||
- 895 Kamenický (Czech) MS-DOS
|
||||
|
||||
```>pages.csv
|
||||
620,,1
|
||||
895,,1
|
||||
```
|
||||
|
||||
## Building Notes
|
||||
|
||||
The script `make.sh` (described later) will get these files and massage the data
|
||||
@ -124,7 +289,13 @@ which implies that code `0xF6` is `String.fromCharCode(0x02C6)` and vice versa.
|
||||
|
||||
To build the sources on windows, consult `dotnet/MakeEncoding.cs`.
|
||||
|
||||
After saving standard output to `out`, the `dotnet.sh` script processes results.
|
||||
After saving the standard output to `out`, a simple script processes the result:
|
||||
|
||||
```>dotnet.sh
|
||||
#!/bin/bash
|
||||
if [ ! -e dotnet/out ]; then exit; fi
|
||||
<dotnet/out tr -s ' ' '\t' | awk 'NF>2 {if(outfile) close(outfile); outfile="codepages/" $1 ".TBL"} NF==2 {print > outfile}'
|
||||
```
|
||||
|
||||
# Building the script
|
||||
|
||||
@ -133,9 +304,43 @@ generates JS code for encoding and decoding:
|
||||
|
||||
## Raw Codepages
|
||||
|
||||
```>make.njs
|
||||
#!/usr/bin/env node
|
||||
var argv = process.argv.slice(1), fs = require('fs');
|
||||
if(argv.length < 2) {
|
||||
console.error("usage: make.njs <codepage_index> [variable]");
|
||||
process.exit(22); /* EINVAL */
|
||||
}
|
||||
|
||||
var cp/*:string*/ = argv[1];
|
||||
var jsvar/*:string*/ = argv[2] || "cptable";
|
||||
var x/*:string*/ = fs.readFileSync("codepages/" + cp + ".TBL","utf8");
|
||||
var maxcp = 0, i = 0, ii = 0;
|
||||
|
||||
var y/*:Array<Array<number> >*/ = x.split("\n").map(function(z/*:string*/)/*:Array<number>*/ {
|
||||
var w/*:Array<string>*/ = z.split("\t");
|
||||
if(w.length < 2) return [Number(w[0])];
|
||||
return [Number(w[0]), Number(w[1])];
|
||||
}).filter(function(z) { return z.length > 1; });
|
||||
```
|
||||
|
||||
The DBCS and SBCS code generation strategies are different. The maximum code is
|
||||
used to distinguish (max `0xFF` for SBCS).
|
||||
|
||||
```
|
||||
for(i = 0; i != y.length; ++i) if(y[i][0] > maxcp) maxcp = y[i][0];
|
||||
|
||||
var enc/*:{[key:string]:number}*/ = {}, dec/*:{[key:string]:string}|Array<string>*/ = (maxcp < 256 ? [] : {});
|
||||
for(i = 0; i != y.length; ++i) {
|
||||
/*:: if(Array.isArray(dec)) */ dec[y[i][0]] = String.fromCharCode(y[i][1]);
|
||||
enc[String.fromCharCode(y[i][1])] = y[i][0];
|
||||
}
|
||||
|
||||
var odec = "", outstr = "";
|
||||
if(maxcp < 256) {
|
||||
/*:: if(Array.isArray(dec)) { */
|
||||
```
|
||||
|
||||
The Unicode character `0xFFFD` (REPLACEMENT CHARACTER) is used as a placeholder
|
||||
for characters that are not specified in the map (for example, `0xF0` is not in
|
||||
code page 10000).
|
||||
@ -143,6 +348,14 @@ code page 10000).
|
||||
For SBCS, the idea is to embed a raw string with the contents of the 256 codes.
|
||||
The `dec` field is merely a split of the string, and `enc` is an eversion:
|
||||
|
||||
```
|
||||
for(i = 0; i != 256; ++i) if(typeof dec[i] === "undefined") dec[i] = String.fromCharCode(0xFFFD);
|
||||
odec = JSON.stringify(dec.join(""));
|
||||
outstr = '(function(){ var d = ' + odec + ', D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();';
|
||||
/*:: } */
|
||||
} else {
|
||||
```
|
||||
|
||||
DBCS is similar, except that the space is sliced in chunks of 256 bytes (strings
|
||||
are only generated for those high-bytes represented in the codepage).
|
||||
|
||||
@ -150,6 +363,27 @@ The strategy is to construct an array-of-arrays so that `dd[high][low]` is the
|
||||
character associated with the code. This array is combined at runtime to yield
|
||||
the complete decoding object (and the encoding object is an eversion):
|
||||
|
||||
```
|
||||
var dd = [];
|
||||
/*:: if(!Array.isArray(dec)) { */
|
||||
for(i in dec) if(dec.hasOwnProperty(i)) {
|
||||
ii = +i;
|
||||
if(typeof dd[ii >> 8] === "undefined") dd[ii >> 8] = [];
|
||||
dd[ii >> 8][ii % 256] = dec[i];
|
||||
}
|
||||
/*:: } */
|
||||
outstr = '(function(){ var d = [], e = {}, D = [], j;\n';
|
||||
for(var i = 0; i != 256; ++i) if(dd[i]) {
|
||||
for(var j = 0; j != 256; ++j) if(typeof dd[i][j] === "undefined") dd[i][j] = String.fromCharCode(0xFFFD);
|
||||
outstr += 'D[' + i + '] = ' + JSON.stringify(dd[i].join("")) + '.split("");\n';
|
||||
outstr += 'for(j = 0; j != D[' + i + '].length; ++j) if(D[' + i + '][j].charCodeAt(0) !== 0xFFFD) { e[D[' + i + '][j]] = ' + (i*256) + ' + j; d[' + (i*256) + ' + j] = D[' + i + '][j];}\n'
|
||||
}
|
||||
outstr += 'return {"enc": e, "dec": d }; })();';
|
||||
}
|
||||
process.stdout.write(jsvar + "[" + cp + "] = " + outstr + "\n");
|
||||
|
||||
```
|
||||
|
||||
`make.sh` generates the tables used by `make.njs`. The raw Unicode TXT files
|
||||
are columnar: `code unicode #comments`. For example, the last 10 lines of the
|
||||
text file `ROMAN.TXT` (for CP 10000) are:
|
||||
@ -170,6 +404,35 @@ text file `ROMAN.TXT` (for CP 10000) are:
|
||||
In processing the data, the comments (after the `#`) are stripped and undefined
|
||||
elements (like `0x7F` for CP 10000) are removed.
|
||||
|
||||
```>make.sh
|
||||
#!/bin/bash
|
||||
INFILE=${1:-pages.csv}
|
||||
OUTFILE=${2:-cptable.js}
|
||||
JSVAR=${3:-cptable}
|
||||
VERSION=$(cat package.json | grep version | tr -dc [0-9.])
|
||||
|
||||
mkdir -p codepages bits
|
||||
rm -f $OUTFILE $OUTFILE.tmp
|
||||
echo "/* $OUTFILE (C) 2013-present SheetJS -- http://sheetjs.com */" > $OUTFILE.tmp
|
||||
echo "/*jshint -W100 */" >> $OUTFILE.tmp
|
||||
echo "var $JSVAR = {version:\"$VERSION\"};" >> $OUTFILE.tmp
|
||||
if [ -e dotnet.sh ]; then bash dotnet.sh; fi
|
||||
awk -F, '{print $1, $2, $3}' $INFILE | while read cp url cptype; do
|
||||
echo $cp $url
|
||||
if [ ! -e codepages/$cp.TBL ]; then
|
||||
curl $url | sed 's/#.*//g' | awk 'NF==2' > codepages/$cp.TBL
|
||||
fi
|
||||
echo "if(typeof $JSVAR === 'undefined') $JSVAR = {};" > bits/$cp.js.tmp
|
||||
node make.njs $cp $JSVAR | tee -a bits/$cp.js.tmp >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <bits/$cp.js.tmp >bits/$cp.js
|
||||
rm -f bits/$cp.js.tmp
|
||||
done
|
||||
echo "// eslint-disable-next-line no-undef" >> $OUTFILE.tmp
|
||||
echo "if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = $JSVAR;" >> $OUTFILE.tmp
|
||||
sed 's/"\([0-9]+\)":/\1:/g' <$OUTFILE.tmp >$OUTFILE
|
||||
rm -f $OUTFILE.tmp
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
The encode and decode functions are kept in a separate script (`cputils.js`).
|
||||
@ -183,8 +446,412 @@ Both encode and decode deal with data represented as:
|
||||
The `ofmt` variable controls `encode` output (`str`, `arr` respectively)
|
||||
while the input format is automatically determined.
|
||||
|
||||
# Tests
|
||||
|
||||
```>test.js
|
||||
var fs = require('fs'), assert = require('assert'), vm = require('vm');
|
||||
var cptable, sbcs;
|
||||
|
||||
```
|
||||
|
||||
Due to a bug in `Buffer.from` in node `4.0 - 4.4`, a special check is needed:
|
||||
|
||||
```>test.js
|
||||
var Buffer_from = function(){};
|
||||
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The tests include JS validity tests (requiring or evaluating code):
|
||||
|
||||
```>test.js
|
||||
describe('source', function() {
|
||||
it('should load node', function() { cptable = require('./'); });
|
||||
it('should load sbcs', function() { sbcs = require('./sbcs'); });
|
||||
it('should load excel', function() { excel = require('./cpexcel'); });
|
||||
it('should process bits', function() {
|
||||
var files = fs.readdirSync('bits').filter(function(x){return x.substr(-3)==".js";});
|
||||
files.forEach(function(x) {
|
||||
vm.runInThisContext(fs.readFileSync('./bits/' + x));
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The README tests verify the snippets in the README:
|
||||
|
||||
```>test.js
|
||||
describe('README', function() {
|
||||
var readme = function() {
|
||||
var unicode_cp10000_255 = cptable[10000].dec[255]; // ˇ
|
||||
assert.equal(unicode_cp10000_255, "ˇ");
|
||||
|
||||
var cp10000_711 = cptable[10000].enc[String.fromCharCode(711)]; // 255
|
||||
assert.equal(cp10000_711, 255);
|
||||
|
||||
var b1 = [0xbb,0xe3,0xd7,0xdc];
|
||||
var s1 = b1.map(function(x) { return String.fromCharCode(x); }).join("");
|
||||
var 汇总 = cptable.utils.decode(936, b1);
|
||||
var buf = cptable.utils.encode(936, 汇总);
|
||||
assert.equal(汇总,"汇总");
|
||||
assert.equal(buf.length, 4);
|
||||
for(var i = 0; i != 4; ++i) assert.equal(b1[i], buf[i]);
|
||||
|
||||
var b2 = [0xf0,0x9f,0x8d,0xa3];
|
||||
var sushi= cptable.utils.decode(65001, b2);
|
||||
var sbuf = cptable.utils.encode(65001, sushi);
|
||||
assert.equal(sushi,"🍣");
|
||||
assert.equal(sbuf.length, 4);
|
||||
for(var i = 0; i != 4; ++i) assert.equal(b2[i], sbuf[i]);
|
||||
|
||||
};
|
||||
it('should be correct', function() {
|
||||
cptable.utils.cache.encache();
|
||||
readme();
|
||||
cptable.utils.cache.decache();
|
||||
readme();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The consistency tests make sure that encoding and decoding are pseudo inverses:
|
||||
|
||||
```>test.js
|
||||
describe('consistency', function() {
|
||||
cptable = require('./');
|
||||
U = cptable.utils;
|
||||
var chk = function(cptable, cacheit) { return function(x) {
|
||||
it('should consistently process CP ' + x, function() {
|
||||
var cp = cptable[x], D = cp.dec, E = cp.enc;
|
||||
if(cacheit) cptable.utils.cache.encache();
|
||||
else cptable.utils.cache.decache();
|
||||
Object.keys(D).forEach(function(d) {
|
||||
if(E[D[d]] != d) {
|
||||
if(typeof E[D[d]] !== "undefined") return;
|
||||
if(D[d].charCodeAt(0) == 0xFFFD) return;
|
||||
if(D[E[D[d]]] === D[d]) return;
|
||||
throw new Error(x + " e.d[" + d + "] = " + E[D[d]] + "; d[" + d + "]=" + D[d] + "; d.e.d[" + d + "] = " + D[E[D[d]]]);
|
||||
}
|
||||
});
|
||||
Object.keys(E).forEach(function(e) {
|
||||
if(D[E[e]] != e) {
|
||||
throw new Error(x + " d.e[" + e + "] = " + D[E[e]] + "; e[" + e + "]=" + E[e] + "; e.d.e[" + e + "] = " + E[D[E[e]]]);
|
||||
}
|
||||
});
|
||||
var corpus = ["foobar"];
|
||||
corpus.forEach(function(w){
|
||||
assert.equal(U.decode(x,U.encode(x,w)),w);
|
||||
});
|
||||
cptable.utils.cache.encache();
|
||||
});
|
||||
}; };
|
||||
describe('cached', function() {
|
||||
Object.keys(cptable).filter(function(w) { return w == +w; }).forEach(chk(cptable, true));
|
||||
});
|
||||
describe('direct', function() {
|
||||
Object.keys(cptable).filter(function(w) { return w == +w; }).forEach(chk(cptable, false));
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The next tests look at possible entry conditions:
|
||||
|
||||
```
|
||||
describe('entry conditions', function() {
|
||||
it('should fail to load utils if cptable unavailable', function() {
|
||||
var sandbox = {};
|
||||
var ctx = vm.createContext(sandbox);
|
||||
assert.throws(function() {
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx);
|
||||
});
|
||||
});
|
||||
it('should load utils if cptable is available', function() {
|
||||
var sandbox = {};
|
||||
var ctx = vm.createContext(sandbox);
|
||||
vm.runInContext(fs.readFileSync('cpexcel.js','utf8'),ctx);
|
||||
vm.runInContext(fs.readFileSync('cputils.js','utf8'),ctx);
|
||||
});
|
||||
var chken = function(cp, i) {
|
||||
var c = function(cp, i, e) {
|
||||
var str = cptable.utils.encode(cp,i,e);
|
||||
var arr = cptable.utils.encode(cp,i.split(""),e);
|
||||
assert.deepEqual(str,arr);
|
||||
if(typeof Buffer === 'undefined') return;
|
||||
var buf = cptable.utils.encode(cp,Buffer_from(i),e);
|
||||
assert.deepEqual(str,buf);
|
||||
};
|
||||
cptable.utils.cache.encache();
|
||||
c(cp,i);
|
||||
c(cp,i,'buf');
|
||||
c(cp,i,'arr');
|
||||
c(cp,i,'str');
|
||||
cptable.utils.cache.decache();
|
||||
c(cp,i);
|
||||
c(cp,i,'buf');
|
||||
c(cp,i,'arr');
|
||||
c(cp,i,'str');
|
||||
};
|
||||
describe('encode', function() {
|
||||
it('CP 1252 : sbcs', function() { chken(1252,"foo•bþr"); });
|
||||
it('CP 708 : sbcs', function() { chken(708,"ت and ث smiley faces");});
|
||||
it('CP 936 : dbcs', function() { chken(936, "这是中文字符测试");});
|
||||
});
|
||||
var chkde = function(cp, i) {
|
||||
var c = function(cp, i) {
|
||||
var s;
|
||||
if(typeof Buffer !== 'undefined' && i instanceof Buffer) s = [].map.call(i, function(s){return String.fromCharCode(s); });
|
||||
else s=(i.map) ? i.map(function(s){return String.fromCharCode(s); }) : i;
|
||||
var str = cptable.utils.decode(cp,i);
|
||||
var arr = cptable.utils.decode(cp,s.join?s.join(""):s);
|
||||
assert.deepEqual(str,arr);
|
||||
if(typeof Buffer === 'undefined') return;
|
||||
var buf = cptable.utils.decode(cp,Buffer_from(i));
|
||||
assert.deepEqual(str,buf);
|
||||
};
|
||||
cptable.utils.cache.encache();
|
||||
c(cp,i);
|
||||
cptable.utils.cache.decache();
|
||||
c(cp,i);
|
||||
};
|
||||
describe('decode', function() {
|
||||
it('CP 1252 : sbcs', function() { chkde(1252,[0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]); }); /* "foobar" */
|
||||
if(typeof Buffer !== 'undefined') it('CP 708 : sbcs', function() { chkde(708, Buffer_from([0xca, 0x20, 0x61, 0x6e, 0x64, 0x20, 0xcb, 0x20, 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x79, 0x20, 0x66, 0x61, 0x63, 0x65, 0x73])); }); /* ("ت and ث smiley faces") */
|
||||
it('CP 936 : dbcs', function() { chkde(936, [0xd5, 0xe2, 0xca, 0xc7, 0xd6, 0xd0, 0xce, 0xc4, 0xd7, 0xd6, 0xb7, 0xfb, 0xb2, 0xe2, 0xca, 0xd4]);}); /* "这是中文字符测试" */
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `testfile` helper function reads a file and compares to node's read facilities:
|
||||
|
||||
```>test.js
|
||||
function testfile(f,cp,type,skip) {
|
||||
var d = fs.readFileSync(f);
|
||||
var x = fs.readFileSync(f, type);
|
||||
var a = x.split("");
|
||||
var chk = function(cp) {
|
||||
var y = cptable.utils.decode(cp, d);
|
||||
assert.equal(x,y);
|
||||
var z = cptable.utils.encode(cp, x);
|
||||
if(z.length != d.length) throw new Error(f + " " + JSON.stringify(z) + " != " + JSON.stringify(d) + " : " + z.length + " " + d.length);
|
||||
for(var i = 0; i != d.length; ++i) if(d[i] !== z[i]) throw new Error("" + i + " " + d[i] + "!=" + z[i]);
|
||||
if(skip) return;
|
||||
z = cptable.utils.encode(cp, a);
|
||||
if(z.length != d.length) throw new Error(f + " " + JSON.stringify(z) + " != " + JSON.stringify(d) + " : " + z.length + " " + d.length);
|
||||
for(var i = 0; i != d.length; ++i) if(d[i] !== z[i]) throw new Error("" + i + " " + d[i] + "!=" + z[i]);
|
||||
if(f.indexOf("cptable.js") == -1) {
|
||||
cptable.utils.encode(cp, d, 'str');
|
||||
cptable.utils.encode(cp, d, 'arr');
|
||||
}
|
||||
}
|
||||
cptable.utils.cache.encache();
|
||||
chk(cp);
|
||||
if(skip) return;
|
||||
cptable.utils.cache.decache();
|
||||
chk(cp);
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
```
|
||||
|
||||
The `utf8` tests verify UTF-8 encoding of the actual JS sources:
|
||||
|
||||
```>test.js
|
||||
describe('node natives', function() {
|
||||
var node = [[65001, 'utf8',1], [1200, 'utf16le',1], [20127, 'ascii',0]];
|
||||
var unicodefiles = ['codepage.md','README.md','cptable.js'];
|
||||
var asciifiles = ['cputils.js'];
|
||||
node.forEach(function(w) {
|
||||
describe(w[1], function() {
|
||||
cptable = require('./');
|
||||
asciifiles.forEach(function(f) {
|
||||
it('should process ' + f, function() { testfile('./misc/'+f+'.'+w[1],w[0],w[1]); });
|
||||
});
|
||||
if(!w[2]) return;
|
||||
unicodefiles.forEach(function(f) {
|
||||
it('should process ' + f, function() { testfile('./misc/'+f+'.'+w[1],w[0],w[1]); });
|
||||
});
|
||||
if(w[1] === 'utf8') it('should process bits', function() {
|
||||
var files = fs.readdirSync('bits').filter(function(x){return x.substr(-3)==".js";});
|
||||
files.forEach(function(f) { testfile('./bits/' + f,w[0],w[1],true); });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `utf*` and `ascii` tests attempt to test other magic formats:
|
||||
|
||||
```>test.js
|
||||
var m = cptable.utils.magic;
|
||||
function cmp(x,z) {
|
||||
assert.equal(x.length, z.length);
|
||||
for(var i = 0; i != z.length; ++i) assert.equal(i+"/"+x.length+""+x[i], i+"/"+z.length+""+z[i]);
|
||||
}
|
||||
Object.keys(m).forEach(function(t){if(t != 16969) describe(m[t], function() {
|
||||
it("should process codepage.md." + m[t], fs.existsSync('./misc/codepage.md.' + m[t]) ?
|
||||
function() {
|
||||
var b = fs.readFileSync('./misc/codepage.md.utf8', "utf8");
|
||||
if(m[t] === "ascii") b = b.replace(/[\u0080-\uffff]*/g,"");
|
||||
var x = fs.readFileSync('./misc/codepage.md.' + m[t]);
|
||||
var y, z;
|
||||
cptable.utils.cache.encache();
|
||||
y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
z = cptable.utils.encode(t, y);
|
||||
if(t != 65000) cmp(x,z);
|
||||
else { assert.equal(y, cptable.utils.decode(t, z)); }
|
||||
cptable.utils.cache.decache();
|
||||
y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
z = cptable.utils.encode(t, y);
|
||||
if(t != 65000) cmp(x,z);
|
||||
else { assert.equal(y, cptable.utils.decode(t, z)); }
|
||||
cptable.utils.cache.encache();
|
||||
cptable.utils.encode(t, y, 'str');
|
||||
cptable.utils.encode(t, y, 'arr');
|
||||
cptable.utils.cache.decache();
|
||||
cptable.utils.encode(t, y, 'str');
|
||||
cptable.utils.encode(t, y, 'arr');
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
: null);
|
||||
it("should process README.md." + m[t], fs.existsSync('./misc/README.md.' + m[t]) ?
|
||||
function() {
|
||||
var b = fs.readFileSync('./misc/README.md.utf8', "utf8");
|
||||
if(m[t] === "ascii") b = b.replace(/[\u0080-\uffff]*/g,"");
|
||||
var x = fs.readFileSync('./misc/README.md.' + m[t]);
|
||||
x = [].slice.call(x);
|
||||
cptable.utils.cache.encache();
|
||||
var y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
cptable.utils.cache.decache();
|
||||
var y = cptable.utils.decode(t, x);
|
||||
assert.equal(y,b);
|
||||
cptable.utils.cache.encache();
|
||||
}
|
||||
: null);
|
||||
});});
|
||||
```
|
||||
|
||||
The codepage `6969` is not defined, so operations should fail:
|
||||
|
||||
```>test.js
|
||||
describe('failures', function() {
|
||||
it('should fail to find CP 6969', function() {
|
||||
assert.throws(function(){cptable[6969].dec});
|
||||
assert.throws(function(){cptable[6969].enc});
|
||||
});
|
||||
it('should fail using utils', function() {
|
||||
assert(!cptable.utils.hascp(6969));
|
||||
assert.throws(function(){return cptable.utils.encode(6969, "foobar"); });
|
||||
assert.throws(function(){return cptable.utils.decode(6969, [0x20]); });
|
||||
});
|
||||
it('should fail with black magic', function() {
|
||||
assert(cptable.utils.hascp(16969));
|
||||
assert.throws(function(){return cptable.utils.encode(16969, "foobar"); });
|
||||
assert.throws(function(){return cptable.utils.decode(16969, [0x20]); });
|
||||
});
|
||||
it('should fail when presented with invalid char codes', function() {
|
||||
assert.throws(function(){cptable.utils.cache.decache(); return cptable.utils.encode(20127, [String.fromCharCode(0xAA)]);});
|
||||
});
|
||||
it('should fail to propagate UTF8 BOM in UTF7', function() {
|
||||
["+/v8-abc", "+/v9"].forEach(function(m) { assert.throws(function() {
|
||||
assert.equal(m, cptable.utils.encode(65000, cptable.utils.decode(65000, m)));
|
||||
}); });
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
# Nitty Gritty
|
||||
|
||||
```json>package.json
|
||||
{
|
||||
"name": "codepage",
|
||||
"version": "1.14.0",
|
||||
"author": "SheetJS",
|
||||
"description": "pure-JS library to handle codepages",
|
||||
"keywords": [ "codepage", "iconv", "convert", "strings" ],
|
||||
"bin": {
|
||||
"codepage": "./bin/codepage.njs"
|
||||
},
|
||||
"main": "cputils.js",
|
||||
"types": "types",
|
||||
"browser": {
|
||||
"buffer": "false"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "~2.14.1",
|
||||
"exit-on-epipe": "~1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"voc": "~1.1.0",
|
||||
"mocha": "~2.5.3",
|
||||
"blanket": "~1.2.3",
|
||||
"@sheetjs/uglify-js": "~2.7.3",
|
||||
"@types/node": "^8.0.7",
|
||||
"@types/commander": "^2.12.0",
|
||||
"dtslint": "^0.1.2",
|
||||
"typescript": "2.2.0"
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-codepage.git"},
|
||||
"scripts": {
|
||||
"pretest": "git submodule init && git submodule update",
|
||||
"test": "make test",
|
||||
"build": "make js",
|
||||
"lint": "make fullint",
|
||||
"dtslint": "dtslint types"
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
"pattern": "[cputils.js]"
|
||||
}
|
||||
},
|
||||
"alex": {
|
||||
"allow": [
|
||||
"chinese",
|
||||
"european",
|
||||
"german",
|
||||
"japanese",
|
||||
"latin"
|
||||
]
|
||||
},
|
||||
"homepage": "http://sheetjs.com/opensource",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"bin",
|
||||
"bits/*.js",
|
||||
"types/index.d.ts",
|
||||
"types/*.json",
|
||||
"cptable.js",
|
||||
"cputils.js",
|
||||
"dist/sbcs.full.js",
|
||||
"dist/cpexcel.full.js"
|
||||
],
|
||||
"bugs": { "url": "https://github.com/SheetJS/js-codepage/issues" },
|
||||
"license": "Apache-2.0",
|
||||
"engines": { "node": ">=0.8" }
|
||||
}
|
||||
```
|
||||
|
||||
```>.vocrc
|
||||
{ "post": "make js" }
|
||||
```
|
||||
|
||||
```>.gitignore
|
||||
node_modules
|
||||
package-lock.json
|
||||
*.tgz
|
||||
.gitignore
|
||||
codepages/
|
||||
.vocrc
|
||||
make.sh
|
||||
make.njs
|
||||
misc/coverage.html
|
||||
codepage_mini.md
|
||||
ctest/sauce*
|
||||
```
|
||||
|
@ -2,22 +2,16 @@
|
||||
|
||||
The fields of the `pages.csv` manifest are `codepage,url,bytes` (SBCS=1, DBCS=2)
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private `0xF8FF` code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
|
||||
The numbering scheme for the `ISO-8859-X` series is `28590 + X`:
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
|
||||
- 708 Arabic (ASMO 708)
|
||||
- 720 Arabic (Transparent ASMO); Arabic (DOS)
|
||||
- 858 OEM Multilingual Latin 1 + Euro symbol
|
||||
- 870 IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2
|
||||
- 1047 IBM EBCDIC Latin 1/Open System
|
||||
- 1140 IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)
|
||||
- 1141 IBM EBCDIC Germany (20273 + Euro sym
|
||||
```>pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,22 +2,16 @@
|
||||
|
||||
The fields of the +AGA-pages.csv+AGA manifest are +AGA-codepage,url,bytes+AGA (SBCS+AD0-1, DBCS+AD0-2)
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private +AGA-0xF8FF+AGA code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
|
||||
The numbering scheme for the +AGA-ISO-8859-X+AGA series is +AGA-28590 +- X+AGA:
|
||||
|
||||
+ACMAIw Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
|
||||
- 708 Arabic (ASMO 708)
|
||||
- 720 Arabic (Transparent ASMO)+ADs Arabic (DOS)
|
||||
- 858 OEM Multilingual Latin 1 +- Euro symbol
|
||||
- 870 IBM EBCDIC Multilingual/ROECE (Latin 2)+ADs IBM EBCDIC Multilingual Latin 2
|
||||
- 1047 IBM EBCDIC Latin 1/Open System
|
||||
- 1140 IBM EBCDIC US-Canada (037 +- Euro symbol)+ADs IBM EBCDIC (US-Canada-Euro)
|
||||
- 1141 IBM EBCDIC Germany (20273 +- Euro sym
|
||||
+AGAAYABgAD4-pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
|
@ -2,22 +2,16 @@
|
||||
|
||||
The fields of the `pages.csv` manifest are `codepage,url,bytes` (SBCS=1, DBCS=2)
|
||||
|
||||
Note that the Windows rendering is used for the Mac code pages. The primary
|
||||
difference is the use of the private `0xF8FF` code (which renders as an Apple
|
||||
logo on macs but as garbage on other operating systems). It may be desirable
|
||||
to fall back to the behavior, in which case the files are under APPLE and not
|
||||
MICSFT. This affects codepages 10000, 10006, 10007, 10029, 10079, 10081
|
||||
|
||||
The numbering scheme for the `ISO-8859-X` series is `28590 + X`:
|
||||
|
||||
## Generated Codepages
|
||||
|
||||
The following codepages are available in .NET on Windows:
|
||||
|
||||
- 708 Arabic (ASMO 708)
|
||||
- 720 Arabic (Transparent ASMO); Arabic (DOS)
|
||||
- 858 OEM Multilingual Latin 1 + Euro symbol
|
||||
- 870 IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2
|
||||
- 1047 IBM EBCDIC Latin 1/Open System
|
||||
- 1140 IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)
|
||||
- 1141 IBM EBCDIC Germany (20273 + Euro sym
|
||||
```>pages.csv
|
||||
37,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT,1
|
||||
437,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT,1
|
||||
500,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT,1
|
||||
737,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP737.TXT,1
|
||||
775,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP775.TXT,1
|
||||
850,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT,1
|
||||
852,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP852.TXT,1
|
||||
855,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP855.TXT,1
|
||||
857,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP857.TXT,1
|
||||
860,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP860.TXT,1
|
||||
861,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP861.TXT,1
|
||||
862,http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP862.TXT,1
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6662
misc/cptable.js.utf7
6662
misc/cptable.js.utf7
File diff suppressed because it is too large
Load Diff
1700
misc/cptable.js.utf8
1700
misc/cptable.js.utf8
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
@ -40,11 +40,11 @@
|
||||
var cca = function cca(x) { return x.charCodeAt(0); };
|
||||
|
||||
var has_buf = (typeof Buffer !== 'undefined');
|
||||
var Buffer_from = function(){};
|
||||
var Buffer_from = function(){};
|
||||
if(has_buf) {
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
// $FlowIgnore
|
||||
if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); };
|
||||
|
||||
@ -246,10 +246,7 @@
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
/+ACoAIQ cputils.js (C) 2013-present SheetJS -- http://sheetjs.com +ACo-/
|
||||
/+ACo cputils.js (C) 2013-present SheetJS -- http://sheetjs.com +ACo-/
|
||||
/+ACo vim: set ft+AD0-javascript: +ACo-/
|
||||
/+ACo-jshint newcap: false +ACo-/
|
||||
(function(root, factory) +AHs
|
||||
@ -40,18 +40,18 @@
|
||||
var cca +AD0 function cca(x) +AHs return x.charCodeAt(0)+ADs +AH0AOw
|
||||
|
||||
var has+AF8-buf +AD0 (typeof Buffer +ACEAPQA9 'undefined')+ADs
|
||||
var Buffer+AF8-from +AD0 function()+AHsAfQA7
|
||||
var Buffer+AF8-from +AD0 function()+AHsAfQA7
|
||||
if(has+AF8-buf) +AHs
|
||||
var nbfs +AD0 +ACE-Buffer.from+ADs
|
||||
if(+ACE-nbfs) try +AHs Buffer.from(+ACI-foo+ACI, +ACI-utf8+ACI)+ADs +AH0 catch(e) +AHs nbfs +AD0 true+ADs +AH0
|
||||
Buffer+AF8-from +AD0 nbfs ? function(buf, enc) +AHs return (enc) ? new Buffer(buf, enc) : new Buffer(buf)+ADs +AH0 : Buffer.from.bind(Buffer)+ADs
|
||||
var nbfs +AD0 +ACE-Buffer.from+ADs
|
||||
if(+ACE-nbfs) try +AHs Buffer.from(+ACI-foo+ACI, +ACI-utf8+ACI)+ADs +AH0 catch(e) +AHs nbfs +AD0 true+ADs +AH0
|
||||
Buffer+AF8-from +AD0 nbfs ? function(buf, enc) +AHs return (enc) ? new Buffer(buf, enc) : new Buffer(buf)+ADs +AH0 : Buffer.from.bind(Buffer)+ADs
|
||||
// +ACQ-FlowIgnore
|
||||
if(+ACE-Buffer.allocUnsafe) Buffer.allocUnsafe +AD0 function(n) +AHs return new Buffer(n)+ADs +AH0AOw
|
||||
|
||||
var mdl +AD0 1024, mdb +AD0 Buffer.allocUnsafe(mdl)+ADs
|
||||
var make+AF8-EE +AD0 function make+AF8-EE(E)+AHs
|
||||
var EE +AD0 Buffer.allocUnsafe(65536)+ADs
|
||||
for(var i +AD0 0+ADs i +ADw 65536+ADs-+-+-i) EE+AFs-i+AF0 +AD0 0+ADs
|
||||
for(var i +AD0 0+ADs i +ADw 65536+ADsAKwAr-i) EE+AFs-i+AF0 +AD0 0+ADs
|
||||
var keys +AD0 Object.keys(E), len +AD0 keys.length+ADs
|
||||
for(var ee +AD0 0, e +AD0 keys+AFs-ee+AF0AOw ee +ADw len+ADs +-+-ee) +AHs
|
||||
if(+ACE(e +AD0 keys+AFs-ee+AF0)) continue+ADs
|
||||
@ -94,7 +94,7 @@
|
||||
var sbcs+AF8-decode +AD0 function make+AF8-sbcs+AF8-decode(cp) +AHs
|
||||
var D +AD0 cpt+AFs-cp+AF0.dec+ADs
|
||||
var DD +AD0 Buffer.allocUnsafe(131072), d+AD0-0, c+AD0AIgAiADs
|
||||
for(d+AD0-0+ADs-d+ADw-D.length+ADs-+-+-d) +AHs
|
||||
for(d+AD0-0+ADs-d+ADw-D.length+ADsAKwAr-d) +AHs
|
||||
if(+ACE(c+AD0-D+AFs-d+AF0)) continue+ADs
|
||||
var w +AD0 c.charCodeAt(0)+ADs
|
||||
DD+AFs-2+ACo-d+AF0 +AD0 w+ACY-255+ADs DD+AFs-2+ACo-d+-1+AF0 +AD0 w+AD4APg-8+ADs
|
||||
@ -246,10 +246,7 @@
|
||||
mdb+AFs-j+-+-+AF0 +AD0 128 +- (w+ACY-63)+ADs
|
||||
+AH0
|
||||
+AH0
|
||||
if(+ACE-ofmt +AHwAfA ofmt +AD0APQA9 'buf') +AHs
|
||||
var res +AD0 mdb.slice(0,j)+ADs
|
||||
return has+AF8-buf +ACYAJg Buffer.isBuffer(res) ? Buffer+AF8-from(res) : res+ADs
|
||||
+AH0
|
||||
if(+ACE-ofmt +AHwAfA ofmt +AD0APQA9 'buf') return mdb.slice(0,j)+ADs
|
||||
if(ofmt +ACEAPQA9 'arr') return mdb.slice(0,j).toString('binary')+ADs
|
||||
return +AFsAXQ.slice.call(mdb, 0, j)+ADs
|
||||
+AH0AOw
|
||||
@ -315,7 +312,7 @@
|
||||
w +AD0 E+AFs-isstr? data.charAt(i) : data+AFs-i+AF0AXQA7
|
||||
if(w +AD4 255) +AHs
|
||||
out+AFs-j+AF0 +AD0 w+AD4APg-8+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 w+ACY-255+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 w+ACY-255+ADs
|
||||
+AH0 else out+AFs-j+AF0 +AD0 w+ACY-255+ADs
|
||||
+AH0
|
||||
else if((M+AD0-magic+AFs-cp+AF0)) switch(M) +AHs
|
||||
@ -326,18 +323,18 @@
|
||||
if(w +ADwAPQ 0x007F) out+AFs-j+AF0 +AD0 w+ADs
|
||||
else if(w +ADwAPQ 0x07FF) +AHs
|
||||
out+AFs-j+AF0 +AD0 192 +- (w +AD4APg 6)+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 128 +- (w+ACY-63)+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 128 +- (w+ACY-63)+ADs
|
||||
+AH0 else if(w +AD4APQ 0xD800 +ACYAJg w +ADwAPQ 0xDFFF) +AHs
|
||||
w -+AD0 0xD800+ADs
|
||||
ww +AD0 (isstr ? data.charCodeAt(+-+-i) : data+AFs-+-+-i+AF0.charCodeAt(0)) - 0xDC00 +- (w +ADwAPA 10)+ADs
|
||||
ww +AD0 (isstr ? data.charCodeAt(+-+-i) : data+AFsAKwAr-i+AF0.charCodeAt(0)) - 0xDC00 +- (w +ADwAPA 10)+ADs
|
||||
out+AFs-j+AF0 +AD0 240 +- ((ww+AD4APgA+-18) +ACY 0x07)+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 144 +- ((ww+AD4APgA+-12) +ACY 0x3F)+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 128 +- ((ww+AD4APgA+-6) +ACY 0x3F)+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 128 +- (ww +ACY 0x3F)+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 144 +- ((ww+AD4APgA+-12) +ACY 0x3F)+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 128 +- ((ww+AD4APgA+-6) +ACY 0x3F)+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 128 +- (ww +ACY 0x3F)+ADs
|
||||
+AH0 else +AHs
|
||||
out+AFs-j+AF0 +AD0 224 +- (w +AD4APg 12)+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 128 +- ((w +AD4APg 6)+ACY-63)+ADs
|
||||
out+AFs-+-+-j+AF0 +AD0 128 +- (w+ACY-63)+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 128 +- ((w +AD4APg 6)+ACY-63)+ADs
|
||||
out+AFsAKwAr-j+AF0 +AD0 128 +- (w+ACY-63)+ADs
|
||||
+AH0
|
||||
+AH0
|
||||
break+ADs
|
||||
@ -367,7 +364,7 @@
|
||||
case +ACI-utf32le+ACI:
|
||||
for(i +AD0 0+ADs i +ADw len+ADs +-+-i) +AHs
|
||||
w +AD0 isstr ? data.charCodeAt(i) : data+AFs-i+AF0.charCodeAt(0)+ADs
|
||||
if(w +AD4APQ 0xD800 +ACYAJg w +ADwAPQ 0xDFFF) w +AD0 0x10000 +- ((w - 0xD800) +ADwAPA 10) +- (data+AFs-+-+-i+AF0.charCodeAt(0) - 0xDC00)+ADs
|
||||
if(w +AD4APQ 0xD800 +ACYAJg w +ADwAPQ 0xDFFF) w +AD0 0x10000 +- ((w - 0xD800) +ADwAPA 10) +- (data+AFsAKwAr-i+AF0.charCodeAt(0) - 0xDC00)+ADs
|
||||
out+AFs-j+-+-+AF0 +AD0 w+ACY-255+ADs w +AD4APgA9 8+ADs
|
||||
out+AFs-j+-+-+AF0 +AD0 w+ACY-255+ADs w +AD4APgA9 8+ADs
|
||||
out+AFs-j+-+-+AF0 +AD0 w+ACY-255+ADs w +AD4APgA9 8+ADs
|
||||
@ -377,7 +374,7 @@
|
||||
case +ACI-utf32be+ACI:
|
||||
for(i +AD0 0+ADs i +ADw len+ADs +-+-i) +AHs
|
||||
w +AD0 isstr ? data.charCodeAt(i) : data+AFs-i+AF0.charCodeAt(0)+ADs
|
||||
if(w +AD4APQ 0xD800 +ACYAJg w +ADwAPQ 0xDFFF) w +AD0 0x10000 +- ((w - 0xD800) +ADwAPA 10) +- (data+AFs-+-+-i+AF0.charCodeAt(0) - 0xDC00)+ADs
|
||||
if(w +AD4APQ 0xD800 +ACYAJg w +ADwAPQ 0xDFFF) w +AD0 0x10000 +- ((w - 0xD800) +ADwAPA 10) +- (data+AFsAKwAr-i+AF0.charCodeAt(0) - 0xDC00)+ADs
|
||||
out+AFs-j+-3+AF0 +AD0 w+ACY-255+ADs w +AD4APgA9 8+ADs
|
||||
out+AFs-j+-2+AF0 +AD0 w+ACY-255+ADs w +AD4APgA9 8+ADs
|
||||
out+AFs-j+-1+AF0 +AD0 w+ACY-255+ADs w +AD4APgA9 8+ADs
|
||||
@ -388,7 +385,7 @@
|
||||
case +ACI-utf7+ACI:
|
||||
for(i +AD0 0+ADs i +ADw len+ADs i+-+-) +AHs
|
||||
var c +AD0 isstr ? data.charAt(i) : data+AFs-i+AF0.charAt(0)+ADs
|
||||
if(c +AD0APQA9 +ACI-+-+ACI) +AHs out+AFs-j+-+-+AF0 +AD0 0x2b+ADs out+AFs-j+-+-+AF0 +AD0 0x2d+ADs continue+ADs +AH0
|
||||
if(c +AD0APQA9 +ACIAKwAi) +AHs out+AFs-j+-+-+AF0 +AD0 0x2b+ADs out+AFs-j+-+-+AF0 +AD0 0x2d+ADs continue+ADs +AH0
|
||||
if(SetD.indexOf(c) +AD4 -1) +AHs out+AFs-j+-+-+AF0 +AD0 c.charCodeAt(0)+ADs continue+ADs +AH0
|
||||
var tt +AD0 encode(1201, c)+ADs
|
||||
out+AFs-j+-+-+AF0 +AD0 0x2b+ADs
|
||||
@ -493,7 +490,7 @@
|
||||
for(+ADs i +ADw len+ADs i+-+AD0-j) +AHs
|
||||
if(data+AFs-i+AF0 +ACEAPQA9 0x2b) +AHs j+AD0-1+ADs out+AFs-k+-+-+AF0 +AD0 String.fromCharCode(data+AFs-i+AF0)+ADs continue+ADs +AH0
|
||||
j+AD0-1+ADs
|
||||
if(data+AFs-i+-1+AF0 +AD0APQA9 0x2d) +AHs j +AD0 2+ADs out+AFs-k+-+-+AF0 +AD0 +ACI-+-+ACIAOw continue+ADs +AH0
|
||||
if(data+AFs-i+-1+AF0 +AD0APQA9 0x2d) +AHs j +AD0 2+ADs out+AFs-k+-+-+AF0 +AD0 +ACIAKwAiADs continue+ADs +AH0
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
while(String.fromCharCode(data+AFs-i+-j+AF0).match(/+AFs-A-Za-z0-9+-+AFw-/+AF0-/)) j+-+-+ADs
|
||||
var dash +AD0 0+ADs
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ft=javascript: */
|
||||
/*jshint newcap: false */
|
||||
(function(root, factory) {
|
||||
@ -40,11 +40,11 @@
|
||||
var cca = function cca(x) { return x.charCodeAt(0); };
|
||||
|
||||
var has_buf = (typeof Buffer !== 'undefined');
|
||||
var Buffer_from = function(){};
|
||||
var Buffer_from = function(){};
|
||||
if(has_buf) {
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
var nbfs = !Buffer.from;
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
// $FlowIgnore
|
||||
if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); };
|
||||
|
||||
@ -246,10 +246,7 @@
|
||||
mdb[j++] = 128 + (w&63);
|
||||
}
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') {
|
||||
var res = mdb.slice(0,j);
|
||||
return has_buf && Buffer.isBuffer(res) ? Buffer_from(res) : res;
|
||||
}
|
||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
||||
return [].slice.call(mdb, 0, j);
|
||||
};
|
||||
|
31
package.json
31
package.json
@ -1,19 +1,21 @@
|
||||
{
|
||||
"name": "codepage",
|
||||
"version": "1.15.0+pi",
|
||||
"version": "1.14.0",
|
||||
"author": "SheetJS",
|
||||
"description": "pure-JS library to handle codepages",
|
||||
"keywords": [
|
||||
"codepage",
|
||||
"iconv",
|
||||
"convert",
|
||||
"strings"
|
||||
],
|
||||
"keywords": [ "codepage", "iconv", "convert", "strings" ],
|
||||
"bin": {
|
||||
"codepage": "./bin/codepage.njs"
|
||||
},
|
||||
"main": "cputils.js",
|
||||
"types": "types",
|
||||
"browser": {
|
||||
"buffer": "false"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "~2.14.1",
|
||||
"exit-on-epipe": "~1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"voc": "~1.1.0",
|
||||
"mocha": "~2.5.3",
|
||||
@ -24,10 +26,7 @@
|
||||
"dtslint": "^0.1.2",
|
||||
"typescript": "2.2.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/SheetJS/js-codepage.git"
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-codepage.git"},
|
||||
"scripts": {
|
||||
"pretest": "git submodule init && git submodule update",
|
||||
"test": "make test",
|
||||
@ -49,7 +48,7 @@
|
||||
"latin"
|
||||
]
|
||||
},
|
||||
"homepage": "https://sheetjs.com/",
|
||||
"homepage": "http://sheetjs.com/opensource",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
@ -62,11 +61,7 @@
|
||||
"dist/sbcs.full.js",
|
||||
"dist/cpexcel.full.js"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/SheetJS/js-codepage/issues"
|
||||
},
|
||||
"bugs": { "url": "https://github.com/SheetJS/js-codepage/issues" },
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
"engines": { "node": ">=0.8" }
|
||||
}
|
||||
|
1
packages/codepage-cli/.gitignore
vendored
1
packages/codepage-cli/.gitignore
vendored
@ -1 +0,0 @@
|
||||
node_modules/
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/* js-codepage (C) 2014-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2 ft=javascript: */
|
||||
/* eslint-env node */
|
||||
var cli = require('../');
|
||||
|
||||
cli();
|
@ -1,102 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/* js-codepage (C) 2014-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2 ft=javascript: */
|
||||
/* eslint-env node */
|
||||
var codepage = require('codepage');
|
||||
require('exit-on-epipe');
|
||||
var fs = require('fs'), program/*:any*/ = (require('commander')/*:any*/);
|
||||
function run() {
|
||||
program
|
||||
.version(codepage.version)
|
||||
.usage('[options] <file>')
|
||||
.option('-f, --from-code <code>', 'codepage of input (default 65001 utf8)')
|
||||
.option('-t, --to-code <code>', 'codepage of output (default 65001 utf8)')
|
||||
.option('-o, --output <file>', 'output file (<file>.<to> if specified)')
|
||||
.option('-B, --bom', 'write BOM (for unicode codepages)')
|
||||
.option('-F, --force', 'force writing to stdout for non-utf8 codepages')
|
||||
.option('-l, --list', 'List supported codepages');
|
||||
|
||||
program.on('--help', function () {
|
||||
console.log(' Codepage descriptions can be found in the README');
|
||||
console.log(' http://oss.sheetjs.com/js-codepage/README.md');
|
||||
console.log(' Support email: dev.codepage@sheetjs.com');
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
if (program.list) {
|
||||
var l/*:Array<number>*/ = [];
|
||||
Object.keys(codepage).forEach(function (x) { if (parseInt(x, 10) == +x) l.push(+x); });
|
||||
Object.keys(codepage.utils.magic).forEach(function (x) { if (parseInt(x, 10) == +x && +x != 16969) l.push(+x); });
|
||||
l.sort(function (a, b) { return a - b; }).forEach(function (x) { console.log(x); });
|
||||
process.exit();
|
||||
}
|
||||
|
||||
var fr = +program.fromCode || 65001;
|
||||
var to = +program.toCode || 65001;
|
||||
var f = program.args[0];
|
||||
var o = program.output;
|
||||
|
||||
if (!process.stdin.isTTY) f = f || "-";
|
||||
|
||||
if (f !== "-" && !fs.existsSync(f)) {
|
||||
console.error('codepage: must specify a filename');
|
||||
process.exit(13);
|
||||
}
|
||||
|
||||
function concat(func) {
|
||||
// $FlowIgnore
|
||||
var writable = require('stream').Writable();
|
||||
var buf = [];
|
||||
writable._write = function (chunk, e, cb) { buf.push(chunk); cb(); };
|
||||
writable._writev = function (chunks, cb) { chunks.forEach(function (c) { buf.push(c.chunk); cb(); }); };
|
||||
writable.on('finish', function () { func(Buffer.concat(buf)); });
|
||||
return writable;
|
||||
}
|
||||
|
||||
if (f === "-") process.stdin.pipe(concat(process_text));
|
||||
else process_text(fs.readFileSync(f));
|
||||
|
||||
function process_text(text/*:Buffer*/) {
|
||||
var dec/*:Buffer*/ = (codepage.utils.decode(fr, text)/*:any*/);
|
||||
|
||||
var bom/*:Array<Buffer>*/ = [];
|
||||
bom[1200] = new Buffer([0xFF, 0xFE]);
|
||||
bom[1201] = new Buffer([0xFE, 0xFF]);
|
||||
bom[12000] = new Buffer([0xFF, 0xFE, 0x00, 0x00]);
|
||||
bom[12001] = new Buffer([0x00, 0x00, 0xFE, 0xFF]);
|
||||
bom[16969] = new Buffer([0x69, 0x69]);
|
||||
bom[65000] = new Buffer([0x2B, 0x2F, 0x76, 0x2B]);
|
||||
bom[65001] = new Buffer([0xEF, 0xBB, 0xBF]);
|
||||
|
||||
var mybom = (program.bom && bom[to] ? bom[to] : "");
|
||||
var out/*:any*/ = to === 65001 ? dec.toString('utf8') : codepage.utils.encode(to, dec);
|
||||
|
||||
/* if output file is specified */
|
||||
if (o) writefile(o, out, mybom);
|
||||
/* utf8 -> print to stdout */
|
||||
else if (to === 65001) logit(out, mybom);
|
||||
/* stdout piped to process -> print */
|
||||
else if (!process.stdout.isTTY) logit(out, mybom);
|
||||
/* forced */
|
||||
else if (program.force) logit(out, mybom);
|
||||
/* input file specified -> write to file */
|
||||
else if (f !== "-") writefile(f + "." + to, out, mybom);
|
||||
else {
|
||||
console.error('codepage: use force (-F, --force) to print ' + to + ' codes');
|
||||
process.exit(14);
|
||||
}
|
||||
}
|
||||
|
||||
function logit(out/*:Buffer*/, bom) {
|
||||
process.stdout.write(bom);
|
||||
process.stdout.write(out);
|
||||
}
|
||||
|
||||
function writefile(o, out/*:Buffer*/, bom) {
|
||||
fs.writeFileSync(o, bom);
|
||||
fs.appendFileSync(o, out);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = run;
|
39
packages/codepage-cli/package-lock.json
generated
39
packages/codepage-cli/package-lock.json
generated
@ -1,39 +0,0 @@
|
||||
{
|
||||
"name": "codepage-cli",
|
||||
"version": "1.0.3",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"codepage": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
|
||||
"integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
|
||||
"requires": {
|
||||
"commander": "~2.14.1",
|
||||
"exit-on-epipe": "~1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.14.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
|
||||
"integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
|
||||
},
|
||||
"exit-on-epipe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
|
||||
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
|
||||
},
|
||||
"fs": {
|
||||
"version": "0.0.1-security",
|
||||
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
|
||||
"integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "codepage-cli",
|
||||
"version": "1.0.5",
|
||||
"description": "CLI for js-codepage",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"codepage-cli": "./bin/codepage.njs"
|
||||
},
|
||||
"author": "Garrett Luu",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"codepage": "^1.14.0",
|
||||
"commander": "^5.1.0",
|
||||
"exit-on-epipe": "^1.0.1"
|
||||
}
|
||||
}
|
@ -121,6 +121,11 @@
|
||||
21866,,1
|
||||
29001,,1
|
||||
38598,,1
|
||||
50220,,2
|
||||
50221,,2
|
||||
50222,,2
|
||||
50225,,2
|
||||
50227,,2
|
||||
51932,,2
|
||||
51936,,2
|
||||
51949,,2
|
||||
|
|
4
sbcs.js
4
sbcs.js
@ -1,6 +1,6 @@
|
||||
/*! sbcs.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* sbcs.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W100 */
|
||||
var cptable = {version:"1.15.0"};
|
||||
var cptable = {version:"1.14.0"};
|
||||
cptable[37] = (function(){ var d = "\u0000\u0001\u0002\u0003\t\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013
\b\u0018\u0019\u001c\u001d\u001e\u001f\n\u0017\u001b\u0005\u0006\u0007\u0016\u0004\u0014\u0015\u001a âäàáãåçñ¢.<(+|&éêëèíîïìß!$*);¬-/ÂÄÀÁÃÅÇѦ,%_>?øÉÊËÈÍÎÏÌ`:#@'=\"Øabcdefghi«»ðýþ±°jklmnopqrªºæ¸Æ¤µ~stuvwxyz¡¿ÐÝÞ®^£¥·©§¶¼½¾[]¯¨´×{ABCDEFGHIôöòóõ}JKLMNOPQR¹ûüùúÿ\\÷STUVWXYZ²ÔÖÒÓÕ0123456789³ÛÜÙÚ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
cptable[500] = (function(){ var d = "\u0000\u0001\u0002\u0003\t\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013
\b\u0018\u0019\u001c\u001d\u001e\u001f\n\u0017\u001b\u0005\u0006\u0007\u0016\u0004\u0014\u0015\u001a âäàáãåçñ[.<(+!&éêëèíîïìß]$*);^-/ÂÄÀÁÃÅÇѦ,%_>?øÉÊËÈÍÎÏÌ`:#@'=\"Øabcdefghi«»ðýþ±°jklmnopqrªºæ¸Æ¤µ~stuvwxyz¡¿ÐÝÞ®¢£¥·©§¶¼½¾¬|¯¨´×{ABCDEFGHIôöòóõ}JKLMNOPQR¹ûüùúÿ\\÷STUVWXYZ²ÔÖÒÓÕ0123456789³ÛÜÙÚ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
|
||||
|
2
test.js
2
test.js
@ -1,6 +1,5 @@
|
||||
var fs = require('fs'), assert = require('assert'), vm = require('vm');
|
||||
var cptable, sbcs;
|
||||
|
||||
var Buffer_from = function(){};
|
||||
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
@ -8,7 +7,6 @@ if(typeof Buffer !== 'undefined') {
|
||||
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
|
||||
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
|
||||
}
|
||||
|
||||
describe('source', function() {
|
||||
it('should load node', function() { cptable = require('./'); });
|
||||
it('should load sbcs', function() { sbcs = require('./sbcs'); });
|
||||
|
56
types/index.d.ts
vendored
56
types/index.d.ts
vendored
@ -1,39 +1,43 @@
|
||||
/* codepage.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
// TypeScript Version: 2.2
|
||||
|
||||
/** Codepage index type (integer or string representation) */
|
||||
export type CP$Index = number | string;
|
||||
declare namespace cptable {
|
||||
/** Codepage index type (integer or string representation) */
|
||||
export type CP$Index = number | string;
|
||||
|
||||
/* Individual codepage converter */
|
||||
export interface CP$Conv {
|
||||
enc: {[n: string]: number; };
|
||||
dec: {[n: number]: string; };
|
||||
}
|
||||
|
||||
/** Encode input type (string, array of characters, Buffer) */
|
||||
export type CP$String = string | string[] | Uint8Array;
|
||||
|
||||
/** Encode output / decode input type */
|
||||
export type CP$Data = string | number[] | Uint8Array;
|
||||
|
||||
/** General utilities */
|
||||
export interface CP$Utils {
|
||||
decode(cp: CP$Index, data: CP$Data): string;
|
||||
encode(cp: CP$Index, data: CP$String, opts?: any): CP$Data;
|
||||
hascp(n: number): boolean;
|
||||
magic: {[cp: string]: string};
|
||||
}
|
||||
|
||||
/* Individual codepage converter */
|
||||
export interface CP$Conv {
|
||||
enc: {[n: string]: number; };
|
||||
dec: {[n: number]: string; };
|
||||
}
|
||||
|
||||
/** Encode input type (string, array of characters, Buffer) */
|
||||
export type CP$String = string | string[] | Uint8Array;
|
||||
|
||||
/** Encode output / decode input type */
|
||||
export type CP$Data = string | number[] | Uint8Array;
|
||||
|
||||
/** General utilities */
|
||||
export interface CP$Utils {
|
||||
decode(cp: CP$Index, data: CP$Data): string;
|
||||
encode(cp: CP$Index, data: CP$String, opts?: any): CP$Data;
|
||||
hascp(n: number): boolean;
|
||||
magic: {[cp: string]: string};
|
||||
}
|
||||
|
||||
/* note: TS cannot export top-level indexer, hence default workaround */
|
||||
export interface CP$Module {
|
||||
interface CP$Module {
|
||||
/** Version string */
|
||||
version: string;
|
||||
|
||||
/** Utility Functions */
|
||||
utils: CP$Utils;
|
||||
utils: cptable.CP$Utils;
|
||||
|
||||
/** Codepage Converters */
|
||||
[cp: number]: CP$Conv;
|
||||
[cp: number]: cptable.CP$Conv;
|
||||
}
|
||||
export const cptable: CP$Module;
|
||||
export default cptable;
|
||||
|
||||
declare const cptable:CP$Module;
|
||||
|
||||
export = cptable;
|
||||
|
@ -9,7 +9,6 @@
|
||||
"paths": { "codepage": ["."] },
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"strictFunctionTypes": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user