tarballize legacies
This commit is contained in:
parent
83f67728ff
commit
4ab5276bdc
3440 changed files with 417 additions and 339256 deletions
1
index.js
1
index.js
|
@ -1 +0,0 @@
|
|||
const { Parser } = require('jison');
|
|
@ -1,321 +0,0 @@
|
|||
# Ch1 定義抽象語法樹和語法
|
||||
|
||||
## 抽象語法樹
|
||||
|
||||
C語言、Python語言就算有許多的關鍵字、操作符、符號或是常數變數,在編譯器分析語法以後,最後會轉成編譯器可以操作的樹結構,然後再轉成我們想要的另一個語言的樹,最後輸出另一個語言的程式碼。
|
||||
|
||||
但是什麼叫做抽象語法樹呢?我們先從一點句法知識來談。
|
||||
|
||||
學過中學國文文法的課程,會背一堆類似「主詞+動詞+受詞」、「主詞+(有/無)+受詞」的結構。可以換個說法,是句子=「主詞+動詞+受詞」或是「主詞+(有/無)+賓詞」的形式。我們將「=」寫成「::=」,「/」(或是)寫成「|」,「動詞」擴充變成「動詞片語」,就變成:
|
||||
|
||||
```
|
||||
句子 ::= (主詞 動詞片語 受詞) | (主詞 (有 | 無) 受詞)...
|
||||
|
||||
```
|
||||
|
||||
為了易讀所以寫成:
|
||||
|
||||
```
|
||||
句子 ::= 主詞 動詞片語 受詞
|
||||
| 主詞 (有 | 無) 受詞
|
||||
| ...
|
||||
|
||||
```
|
||||
|
||||
用這種形式表示的語言句法,叫做「BNF文法」。這種句法看起來很語言學,但是我們想:受詞和主詞可以為名詞、專有名詞或是「形容詞+名詞」;動詞片語可以為動詞或是「副詞+動詞」。因此這樣之規則,就可以生成許多句子,比如「我有筆」、「張三養貓」、「小芳慢慢移動檯燈」等等的句子。然後句子可以用上述規則,分析成語法的樹狀結構,如下圖把「我曾旅居新竹」寫成語法樹。
|
||||
|
||||
<figure markdown>
|
||||
![「我曾旅居新竹」的語法樹](syntaxtree.svg "")
|
||||
<figcaption>「我曾旅居新竹」的語法樹</figcaption>
|
||||
</figure>
|
||||
|
||||
|
||||
|
||||
|
||||
同理,程式語言通常也有更嚴謹的這樣生成文法,可以用幾個簡單規則生出繁多的程式碼,而且合乎語法規定。這種生成文法也可檢查輸入的程式碼有沒有符合句法的規定。而這種語法生成的程式碼,去掉不需要的逗號等等符號,當然也可以做成語法樹,就是抽象語法樹 (abstract syntax tree, AST),如下圖所示。
|
||||
<figure markdown>
|
||||
![「(2+2) == 4」的語法樹。注意括號已經刪除。](syntaxtree2.svg "")
|
||||
<figcaption>「(2+2) == 4」的語法樹。注意括號已經刪除。</figcaption>
|
||||
</figure>
|
||||
|
||||
|
||||
而上文的抽象語法樹,可以是我們把程式經過編譯器分析之後,用「樹」儲存的資料結構。而樹形結構我們可以使用Lisp語言的S表達式(S-expressiom; S-exp)來表示,本文採用這樣的表示方法。所以上文的`(2+2)==4`即`(== (+ 2 2) 4)`;`let baz = foo("bar")`,若是把foo("bar")這種函數套用(apply)寫成`(APPLY foo "bar")`,則其S-exp語法樹可寫為`(let baz(APPLY foo "bar"))`。
|
||||
|
||||
## 決定語法
|
||||
那我們要如何制定這個語言的語法,這樣我們才能夠寫出符合這個語法的函數,然後再用tokenizer和parser轉成AST樹。
|
||||
|
||||
函數可以用`ID arg1 arg2`這種方式來表示,其中`arg_x`是引數,`ID`是識別子(identifier,可以把它想成變函數的名字)。
|
||||
|
||||
變數可以是`ID`,`arg_n`可以是`ID`或常數(量)。
|
||||
|
||||
常數(量)的表示法可以是下列任一:
|
||||
|
||||
- 浮點數如0.0, 36.8,BNF風格的表達法為:`[0-9]+ '.' [0-9]+`。`'c'`指c這個文字,`+`表示前面的重複1次以上;`[0-9]`表示數字0到9。
|
||||
|
||||
- 整數如22、0:`[0-9]+`
|
||||
|
||||
- 字串:`'"' (不是「"」的任一字元|('\' '"')) '"'`(`.`表示任何一個字元)
|
||||
|
||||
然而我們還是需要綁定變數`let int x = var in body`(在`body`裡面,`x`指代`var`)、改變變數值)、lambda`fn (int x) (int y) -> + x y`(採用前綴表示法,`+`在前)。另外為了要區別要在PDF印上去的一般字元,在這個檔案的常數、變數、函數、關鍵字等前後需要加@表示(但是函數、lambda裡面的變數不用)。比如`@foo a b@`、`@let int x = 3 in toString (+ x 2)@`、`@"IAmAString"@`、`@2.2@`、`@3@`(後三者應該很少用到)可是若需在PDF印`@`時怎辦?那就用`\@`。比如`foo\@example.com`。
|
||||
|
||||
所以我們可以定義以下的BNF風文法:
|
||||
|
||||
```
|
||||
FLO = \d+[.]\d+ // 浮點數
|
||||
INT = \d+ // 整數
|
||||
AT = '@' // @
|
||||
ID = [_\w][_\d\w]* // 識別子
|
||||
R_ARR = [-][>] // 右箭頭 ->
|
||||
SEMICOLON = ";"
|
||||
// 括號
|
||||
L_PAR = '('
|
||||
R_PAR = ')'
|
||||
ASSIGN = '='
|
||||
OP = [+-*/] | [=][=] | [!<>][=] // 運算子
|
||||
HASH = [#]
|
||||
COM = #[^#]*# # 註解 #
|
||||
SPACE = \s+ # 空白字元
|
||||
B_SLASH = [\\] // 反斜線
|
||||
STR = \"([^"]|[\\\"])*\"
|
||||
LIT_STR = ([^\\]?) // 文字模式的不貪婪模式
|
||||
```
|
||||
|
||||
程式語法定義如下:
|
||||
```BNF
|
||||
Main ::= (LitStr | Prog)* ; 主體
|
||||
LitStr ::= ( not(AT) | B_SLASH AT | B_SLATH HASH)+ ;基本文字模式
|
||||
Prog ::= '@' BODY '@' ;程式模式
|
||||
BODY ::= LET | EXPR | DEFINE
|
||||
DEFINE ::= "define" TYPE VAR ASSIGN BODY SEMICOLON ; 全局定義
|
||||
LET ::= "let" TYPE VAR ASSIGN "in" BODY ; 局域定義
|
||||
EXPR ::= APPLY | FN | LIST | CONST | VAR | "(" EXPR ")"
|
||||
APPLY ::= OP EXPR+ | EXPR EXPR+
|
||||
FN ::= "fn" ARGS R_ARR BODY
|
||||
ARGS ::= ARG | ARG ARGS
|
||||
* ARG ::= "(" TYPE VAR ")"
|
||||
* CONST ::= FLO | STR | INT
|
||||
* VAR ::= ID
|
||||
* TYPE ::= ID
|
||||
LIST ::= [LIST_INNER]
|
||||
LIST_INNER ::= EXPR | EXPR SEMICOLON LIST_INNER
|
||||
```
|
||||
|
||||
## 用ts-parsec和regexp進行tokenize
|
||||
Parser combinator(分析器組合子)是一種利用高階函數來簡化分析器撰寫的辦法。這講到頭來會涉及「遞歸下降分析」以及其他編譯理論的東西,但太難了(聽說可以讀編譯理論的「龍書我們可以製作一個小的tokenizer。但是因為自己寫parser combinator太累了,所以我們就用nom來幫我們代勞。
|
||||
」)。講一個簡單的案例吧:
|
||||
|
||||
假設我們想要將字串的開頭match 0~9 之中的其中一個,我們可以寫一個函數match0to9如下:
|
||||
|
||||
```
|
||||
function match0to9(string){
|
||||
if (string[0] in 0,1,..,9){
|
||||
let rest = string[1:];
|
||||
let matched = string[0];
|
||||
return {type: "OK", rest : rest, matched : matched};
|
||||
}
|
||||
else{
|
||||
return {type : "Nothing"};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
假設我們要將字串`s`的前3個字的match 0~9呢?如果會高階函數的話,引入一個`then`函數,然後把`match0to9`傳進去,這樣寫起來比較不會太糾結,比較好維護:
|
||||
|
||||
```
|
||||
function thenDo(input, fun){
|
||||
if (input.type != "Nothing"{
|
||||
|
||||
middle = fun(input.rest);
|
||||
if (middle.type != "Nothing"){
|
||||
// add the matched character of input to the head of the result
|
||||
middle.matched = input.matched + middle.matched
|
||||
return middle;
|
||||
}else{
|
||||
return middle; // return nothing
|
||||
}
|
||||
}else{
|
||||
input; // return nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// "s" should be wrapped in a object
|
||||
let sWrapped = {type : "OK", rest : s, matched : ""};
|
||||
|
||||
// match0~9 3 times
|
||||
thenDo(thenDo(thenDo(sWrapped, match0to9), match0to9), match0to9)
|
||||
```
|
||||
我們可以製作一個小的tokenizer。但是因為自己寫parser combinator太累了,所以我們就用`ts-parsec`來幫我們代勞。
|
||||
|
||||
|
||||
安裝`ts-parsec`可以用:`npm install -g typescript-parsec`。底下的程式使用的函數的詳細說明可以參考[官方文件](https://github.com/microsoft/ts-parsec/blob/master/doc/ParserCombinators.md)。
|
||||
|
||||
因為這個軟體在 tokenize 的時候使用regex,所以我們就用這個東西來處理。
|
||||
|
||||
我們編輯Node.js的進入點程式(假設為src/index.js`),底下為定義tokenizer的型別和regex pattern:
|
||||
|
||||
```typescript
|
||||
|
||||
```
|
||||
|
||||
### 常數parsing
|
||||
|
||||
增加儲存實際變數值的`ASTNode`型別
|
||||
|
||||
```typescript
|
||||
// add "actualValue" in the parsed Token
|
||||
export interface ASTNode extends parsec.Token<TokenKind>{
|
||||
// number is for float number;
|
||||
//it's optional. since keyword has no value
|
||||
actualValue? : bigint | number | string;
|
||||
}
|
||||
```
|
||||
|
||||
增加處理常數的parser。`...value`有擴充object的意思。
|
||||
```typescript
|
||||
function applyInteger(value: parsec.Token<TokenKind.Int>): ASTNode {
|
||||
// extend value to ASTNode
|
||||
const newNode : ASTNode = {
|
||||
actualValue : BigInt(value.text) ,
|
||||
...value};
|
||||
return newNode;
|
||||
}
|
||||
|
||||
function applyFloat(value: parsec.Token<TokenKind.Flo>): ASTNode {
|
||||
// extend value to ASTNode
|
||||
const newNode : ASTNode = {
|
||||
actualValue : parseFloat(value.text) ,
|
||||
...value};
|
||||
return newNode;
|
||||
}
|
||||
|
||||
function applyString(value: parsec.Token<TokenKind.Str>): ASTNode {
|
||||
// extend value to ASTNode
|
||||
const newNode : ASTNode = {
|
||||
// get only text[1,2,...,the second last char]
|
||||
actualValue : value.text.slice(1,value.text.length-1).replace(/\\\"/g, "\"") ,
|
||||
...value};
|
||||
return newNode;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
製作`CONST`這個parser,然後再加上rule:
|
||||
|
||||
```typescript
|
||||
const CONST = parsec.rule<TokenKind, ASTNode>();
|
||||
/*
|
||||
CONST ::= INT | FLOAT | STRING
|
||||
*/
|
||||
CONST.setPattern(
|
||||
parsec.alt(
|
||||
parsec.apply(parsec.tok(TokenKind.Int), applyInteger),
|
||||
parsec.apply(parsec.tok(TokenKind.Flo), applyFloat),
|
||||
parsec.apply(parsec.tok(TokenKind.Str), applyString),
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
最後包起來進行測試:
|
||||
|
||||
|
||||
```typescript
|
||||
function mainParse(inputStr : string){
|
||||
return parsec.expectSingleResult(parsec.expectEOF(
|
||||
CONST.parse(tokenizer.parse(inputStr))));
|
||||
}
|
||||
|
||||
|
||||
// test
|
||||
function main(){
|
||||
// bigint has suffix `n`
|
||||
assert.strictEqual(mainParse('123455667').actualValue, 123455667n);
|
||||
assert.strictEqual(mainParse('000').actualValue, 0n);
|
||||
assert.strictEqual(mainParse('1.22').actualValue, 1.22);
|
||||
assert.strictEqual(mainParse('0.0').actualValue, 0.0);
|
||||
assert.strictEqual(mainParse(`""`).actualValue, "");
|
||||
assert.strictEqual(mainParse(`"the little town"`).actualValue, `the little town`);
|
||||
assert.strictEqual(mainParse(`"\\\"Alice\\\""`).actualValue, `"Alice"`);
|
||||
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
### 表達式
|
||||
定義`AST型別`:
|
||||
|
||||
```type AST = AST[] | ASTNode;
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 平面操作
|
||||
|
||||
### 基本函數與直譯器
|
||||
我們藉由以上的概念,可以定義一個將文字、線條等形狀排列到2D平面的語法,畢竟不論輸出PDF、SVG等等,粗略而言,就是一種2D平面安放文字的語言。另外PDF的格式相當晦澀,就算_PDF Explained_的PDF教學,也還是要輔助使用其他的工具,沒辦法看了就自己手刻PDF,所以還是用`printpdf`來教學吧。
|
||||
|
||||
現在我們初始化一個專案目錄,然後將需要的S-exp函式庫和pdf函數庫指定為相依函式庫:
|
||||
|
||||
```
|
||||
cargo init;
|
||||
|
||||
cargo add rsexp printpdf;
|
||||
```
|
||||
|
||||
我們可以定義一些表達式(包含函數、資料結構,S-exp形式)的說明如下。`'()`表示空列表(empty list),因為都要表達是函數的引用,所有的函數寫成形式`(Func "函數名稱" (引數1 引數2 ....))`。Float指64位元浮點數:
|
||||
|
||||
```
|
||||
(px Float) ; px表達pixel單位,儲存浮點數
|
||||
(pt Float) ; pt表達point單位,儲存浮點數
|
||||
(style (str pt)) ; 文字樣式。String表示字型的路徑[fontPath],Float表示字型大小(in Pt) (fontSize)
|
||||
(str String) ; 儲存字串
|
||||
(func "createPDF" '()) ;新增PDF
|
||||
(func "createPage" '()) ;新增頁面
|
||||
(func "writePdf" '(str)) ;寫入PDF頁面,String是PATH
|
||||
|
||||
(func "putchar" '(str style x y)) ; x 軸向右,y 軸向下,str 表示字元(char),style 表示文字樣式
|
||||
```
|
||||
|
||||
`main.rs`先引用函式庫:
|
||||
`use printpdf::*;`
|
||||
|
||||
|
||||
其中 `px`、`pt`是單位,所以可以在`main.rs`這樣定義:
|
||||
|
||||
```
|
||||
enum Measure{
|
||||
Pt(f64),
|
||||
Px(f64)
|
||||
}
|
||||
```
|
||||
|
||||
最後一次定義expression:
|
||||
```
|
||||
enum Expr{
|
||||
Mea(Measure), // wrapper for measure
|
||||
Str(&str),
|
||||
Style{font_path : Measure, size : Measure},
|
||||
Func(&str, Vec<Expr>),
|
||||
Void // return nothing
|
||||
}
|
||||
```
|
||||
|
||||
然後我們可以這樣定義一個處理輸入輸出的interpreter於`interp`,並修改`main.rs`如下,縱使我們準時:
|
||||
```
|
||||
fn interp(exp : Expr)->(){
|
||||
// the function will be extended.
|
||||
match exp {
|
||||
Expr::Mea(Measure::Pt(x)) => println!("{:?} pt", x),
|
||||
Expr::Mea(Measure::Px(x)) => println!("{:?} px", x),
|
||||
|
||||
_ => println!("not found expression"),
|
||||
};
|
||||
}
|
||||
|
||||
// exexute interpreter
|
||||
fn main() {
|
||||
interp(Expr::Mea(Measure::Pt(2.2)));
|
||||
interp(Expr::Flo(2.2));
|
||||
}
|
||||
```
|
|
@ -1,26 +0,0 @@
|
|||
# Another Typesetter - 另一個排版器
|
||||
|
||||
## 摘要
|
||||
本文是講一個排版器的雛形如何製作的考察,使用Rust語言。
|
||||
|
||||
###序言
|
||||
|
||||
以前從國中時候試用Linux以及架站以後,就開始想用LaTeX排版些自己所寫的東西,其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路,還是希望有天至少能夠完成個能用的雛形。
|
||||
|
||||
但是這是涉及字體檔案的處理、PDF的處理、語法分析,後來自己因為不知道如何開發,所以一直停擺。不是遇到很多蟲,就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的 _Digital Typography_,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。
|
||||
|
||||
另外筆者一個分支興趣是編譯器的相關知識,所以開始讀和王垠的編譯器思想系出同門的Jeremy G. Siek所著作之 *Essential of Complication: An Incremental Approach in Racket*(編譯之要素:Racket語言的遞增的方法)。我想到:既然編譯器這種複雜的軟體,可以一層一層的用pass來遞增功能,就像水彩從背景、大物體一直由少漸多的完成。而排版軟體也是把使用者輸入的排版之領域特定語言(DSL)轉換成文字、圖形和二維座標對應關係(最後匯出成PDF或SVG等等)的編譯器,若是能夠用層層遞增的方法來完成,相信也能夠避免結構的複雜化導致錯誤容易發生的挫折。
|
||||
|
||||
然而排版語言不只是輸入文字轉圖形而已,更重要的是還要有因應美觀的自動斷行(justification)和斷字(hyphenation)等等的演算法、還有PDF的基本知識、字型函式庫的取用、排版要求(多欄)、甚至還牽涉到語言特有的特性:比如東亞全形文字(漢字、諺文、日文假名、注音符號)和非全形文字中間要加空白,以及從左寫到右的文字(希伯來字母和阿拉伯字母等)的排版方法,不一而足。
|
||||
|
||||
為了簡化起見,且目標讀者是臺灣的受眾,本書僅涉及到ASCII英文字母——頂多加些一些附加符號(diacritics)和漢字的排版。其他的功能希望讀者可以漸次由少漸多的附加。另外這邊會使用到一些LISP的表達式來表達抽象語法樹,若是不懂的話,可以看一點教 Lisp或是Scheme的書,如SICP。另外這本書不是編譯原理和描述PDF規格的書,不涉獵底層的知識,有需要的可以參考相關領域的書。
|
||||
|
||||
### 先備知識
|
||||
|
||||
這不是教一位入門使用者如從零知識撰寫排版軟體的書,讀者應該有知道如何使用靜態型別語言的經驗,比如一點C、或是Rust等等,還要會些正規表達式regex。另外抽象語法樹為求方便,使用LISP撰寫,所以需要會LISP和Scheme的知識(知名教科書SICP的開頭可以讀一讀)。
|
||||
|
||||
這本書也不教編譯理論和tokenizing、parsing、狀態機等等的,頂多只會帶到一些很基礎的知識,有需要的請另外再讀。所以使用者需要會有使用正規表達式(regex)的能力。
|
||||
|
||||
操作環境使用Linux作業系統和TypeScript程式語言(Nodejs框架)。需要安裝fontconfig等套件。
|
||||
|
||||
- [定義抽象語法樹和語法](./defineASTandGrammar)
|
|
@ -1,17 +0,0 @@
|
|||
# Welcome to MkDocs
|
||||
|
||||
For full documentation visit [mkdocs.org](https://www.mkdocs.org).
|
||||
|
||||
## Commands
|
||||
|
||||
* `mkdocs new [dir-name]` - Create a new project.
|
||||
* `mkdocs serve` - Start the live-reloading docs server.
|
||||
* `mkdocs build` - Build the documentation site.
|
||||
* `mkdocs -h` - Print help message and exit.
|
||||
|
||||
## Project layout
|
||||
|
||||
mkdocs.yml # The configuration file.
|
||||
docs/
|
||||
index.md # The documentation homepage.
|
||||
... # Other markdown pages, images and other files.
|
Binary file not shown.
|
@ -1,193 +0,0 @@
|
|||
#set heading(numbering: "1.1.1.1.")
|
||||
|
||||
#show raw: set text(font: "Noto Sans Mono CJK TC")
|
||||
|
||||
|
||||
#set page("a5")
|
||||
|
||||
#set text(
|
||||
font: ("New Computer Modern", "AR PL UMing TW"),
|
||||
size: 11pt
|
||||
)
|
||||
|
||||
#show heading: it => [
|
||||
#set text(font: "Noto Serif CJK TC",
|
||||
weight: "black")
|
||||
#it.body
|
||||
]
|
||||
|
||||
#set par( justify: true,leading: 1em,
|
||||
)
|
||||
|
||||
#align(center)[#set text(
|
||||
font: ("EB Garamond 08"),
|
||||
weight:"medium",
|
||||
size: 20pt,
|
||||
)
|
||||
Clo: another typesetter]
|
||||
#align(center)[#box([#set text(size: 15pt,
|
||||
font: "Noto Serif CJK TC",
|
||||
weight:"medium")
|
||||
一個排版器的實作心得])]
|
||||
#box(
|
||||
height:0.5em
|
||||
)
|
||||
#align(center)[#box([#set text(size: 11pt,
|
||||
font: "AR PL UMing TW",
|
||||
weight:"light")
|
||||
陳建町])]
|
||||
|
||||
#pagebreak()
|
||||
|
||||
|
||||
|
||||
|
||||
#set page(
|
||||
margin: (top: 60pt, bottom: 20pt),
|
||||
header: locate(
|
||||
loc => if (calc.odd(loc.page()) == true){
|
||||
[#set align(right)
|
||||
#numbering("i", loc.page())
|
||||
]
|
||||
} else {
|
||||
[#set align(left)
|
||||
#numbering("i", loc.page())]
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
|
||||
#heading(level:2, "版權聲明",outlined:false)
|
||||
|
||||
(c) 2023 陳建町 (Tan, Kian-ting)
|
||||
|
||||
本書內容非經許可,禁止複製、分發、商業使用等違反著作權法之行為。
|
||||
|
||||
然書中之程式碼,採用 #link("https://opensource.org/license/mit/")[MIT許可證]授權。
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#outline(
|
||||
title: align(left, [目#box(width:1em)錄 #box(
|
||||
height:1.5em)]),
|
||||
target: heading.where(outlined: true),
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#set page(
|
||||
numbering: "i",
|
||||
number-align: top+right)
|
||||
|
||||
#heading(numbering: none, "序言")
|
||||
|
||||
以前從國中時候試用Linux以及架站以後,就開始想用LaTeX排版些自己所寫的東西,其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路,還是希望有天至少能夠完成個能用的雛形。
|
||||
|
||||
但是這是涉及字體檔案的處理、PDF的處理、語法分析,後來自己因為不知道如何開發,所以一直停擺。不是遇到很多蟲,就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的 _Digital Typography_,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。
|
||||
|
||||
另外筆者一個分支興趣是編譯器的相關知識,所以開始讀和王垠的編譯器思想系出同門的Jeremy G. Siek所著作之_Essential of Complication: An Incremental Approach in Racket_(編譯之要素:Racket語言的遞增的方法)。我想到:既然編譯器這種複雜的軟體,可以一層一層的用pass來遞增功能,就像水彩從背景、大物體一直由少漸多的完成。而排版軟體也是把使用者輸入的排版之領域特定語言(DSL)轉換成文字、圖形和二維座標對應關係(最後匯出成PDF或SVG等等)的編譯器,若是能夠用層層遞增的方法來完成,相信也能夠避免結構的複雜化導致錯誤容易發生的挫折。
|
||||
|
||||
然而排版語言不只是輸入文字轉圖形而已,更重要的是還要有因應美觀的自動斷行(justification)和斷字(hyphenation)等等的演算法、還有PDF的基本知識、字型函式庫的取用、排版要求(多欄)、甚至還牽涉到語言特有的特性:比如東亞全形文字(漢字、諺文、日文假名、注音符號)和非全形文字中間要加空白,以及從左寫到右的文字(希伯來字母和阿拉伯字母等)的排版方法,不一而足。
|
||||
|
||||
為了簡化起見,且目標讀者是臺灣的受眾,本書僅涉及到ASCII英文字母——頂多加些一些附加符號(diacritics)和漢字的排版。其他的功能希望讀者可以漸次由少漸多的附加。另外這邊會使用到一些LISP的表達式來表達抽象語法樹,若是不懂的話,可以看一點教 Lisp或是Scheme的書,如SICP。另外這本書不是編譯原理和描述PDF規格的書,不涉獵底層的知識,有需要的可以參考相關領域的書。
|
||||
|
||||
#heading(numbering: none, "致謝")
|
||||
|
||||
感謝Donald Knuth教授開發出這麼一套排版系統以及排版的演算法,除了造福科學排版的諸多用戶外,也間接鼓舞我想要研究排版軟體如何實作;感謝Jeremy G.Siek老師的_Essential of Complication: An Incremental Approach in Racket_,讓我獲得排版語言編譯器設計的啟發。感謝王垠讓我對編譯器相關的技術有興趣,從而斷斷續續學習相關的資訊。
|
||||
|
||||
感謝愛爾蘭語,除了讓我對語言和語言復興的知識打開新的世界以外,這個軟體的名字Clo也是從這裡來的(cló有「活字」的意思,因為技術限制抱歉沒辦法輸入長音符號)。
|
||||
|
||||
感謝我的父母,雖然專長不是電腦資訊科技,但是要感謝他們讓我讓我有餘力能夠在中學的時候研究這種興趣,這條路才能走下去。
|
||||
|
||||
感謝這本書閱讀的人們,讓我知道筆者不是孤單的。
|
||||
|
||||
Siōng-āu Kám-siā góa ê Siōng Chú, nā-bô i ê hû-chhî kap pó-siú, chit-pún chheh iā bô-hó oân-sêng.(最後感謝上主,若無扶持保守,這本書也很難完成)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
|
||||
#set page(
|
||||
margin: (top: 60pt, bottom: 20pt),
|
||||
header: locate(
|
||||
loc =>{
|
||||
let chapter_query = query(selector(heading.where(level: 1)).after(loc),loc)
|
||||
let section_query = query(selector(heading.where(level: 2)).after(loc),loc)
|
||||
let chapter = "";
|
||||
let section = "";
|
||||
if chapter_query == (){chapter = ""}
|
||||
else{chapter = chapter_query.at(0).body};
|
||||
if section_query == (){section = ""}
|
||||
else{section = section_query.at(0).body}
|
||||
|
||||
|
||||
|
||||
|
||||
if (calc.odd(loc.page()) == true){
|
||||
grid(
|
||||
columns: (0.333333fr, 0.333333fr, 0.333333fr),
|
||||
|
||||
text(style: "italic")[ ],
|
||||
[#set align(center)
|
||||
#chapter],
|
||||
[ #h(1fr) #loc.page-numbering()])
|
||||
} else {
|
||||
grid(
|
||||
columns: (0.333333fr, 0.333333fr, 0.333333fr),
|
||||
|
||||
text(style: "italic")[#loc.page-numbering()],
|
||||
[#set align(center)
|
||||
#section],
|
||||
[ ])
|
||||
}}
|
||||
));
|
||||
|
||||
#show heading: it => [
|
||||
#set text(font: ("New Computer Modern", "Noto Serif CJK TC"),
|
||||
weight: "black")
|
||||
#counter(heading).display() #it
|
||||
]
|
||||
|
||||
|
||||
#set page(numbering: "1")
|
||||
#counter(page).update(1)
|
||||
#set heading(numbering: "1.1.1.1.1")
|
||||
= 先備知識
|
||||
|
||||
這不是教一位入門使用者如從零知識撰寫排版軟體的書,讀者應該有知道如何使用靜態型別語言的經驗,比如一點C、或是Rust等等。另外抽象語法樹為求方便,使用LISP撰寫,所以需要會LISP和Scheme的知識(知名教科書SICP的開頭可以讀一讀)。
|
||||
|
||||
這本書也不教編譯理論和tokenizing、parsing、狀態機等等的,頂多只會帶到一些很基礎的知識,有需要的請另外再讀。所以使用者需要會有使用正規表達式(regex)的能力。
|
||||
|
||||
== 抽象語法樹
|
||||
|
||||
C語言、Python語言就算有許多的關鍵字、操作符、符號或是常數變數,在編譯器分析語法以後,最後會轉成編譯器可以操作的樹結構,然後再轉成我們想要的另一個語言的樹,最後輸出另一個語言的程式碼。
|
||||
|
||||
但是什麼叫做抽象語法樹呢?我們先從一點句法知識來談。
|
||||
|
||||
學過中學國文文法的課程,會背一堆類似「主詞+動詞+受詞」、「主詞+(有/無)+受詞」的結構。可以換個說法,是句子=「主詞+動詞+受詞」或是「主詞+(有/無)+賓詞」的形式。我們將「=」寫成「::=」,「/」(或是)寫成「|」,動詞擴充變成「動詞片語」,就變成:
|
||||
|
||||
```
|
||||
句子 ::= (主詞 動詞片語 受詞) | (主詞 (有 | 無) 受詞)...
|
||||
|
||||
```
|
||||
|
||||
用這種形式表示的語言句法,叫做「BNF文法」。這種句法看起來很語言學,但是我們想:受詞和主詞可以為名詞、專有名詞或是「形容詞+名詞」;動詞片語可以為動詞或是「副詞+動詞」。因此這樣之規則,就可以生成許多句子,比如「我有筆」、「張三養貓」、「小芳慢慢移動檯燈」等等的句子。然後句子可以用上述規則,分析成語法的樹狀結構,如圖1把「我曾旅居新竹」寫成語法樹。
|
||||
|
||||
#figure(
|
||||
image("syntaxtree.svg", width: 40%),
|
||||
caption: [
|
||||
「我曾旅居新竹」的語法樹
|
||||
],
|
||||
supplement: [圖],
|
||||
)
|
||||
|
||||
同理,程式語言通常也有更嚴謹的這樣生成文法,可以用幾個簡單規則生出繁多的程式碼,而且合乎語法規定。這種生成文法也可檢查輸入的程式碼有沒有符合句法的規定。而這種語法生成的程式碼,去掉不需要的逗號等等符號,當然也可以做成語法樹,就是抽象語法樹 (abstract syntax tree, AST),如圖2所示。
|
||||
|
||||
#figure(
|
||||
image("syntaxtree2.svg", width: 30%),
|
||||
caption: [
|
||||
`(2+2) == 4`的語法樹。注意括號已經刪除。
|
||||
],
|
||||
supplement: [圖],
|
||||
)
|
||||
|
||||
而上文的抽象語法樹,可以是我們把程式經過編譯器分析之後,用「樹」儲存的資料結構。而樹形結構我們可以使用Lisp語言的S表達式(S-expressiom; S-exp)來表示,本文採用這樣的表示方法。所以上文的`(2+2)==4`即`(== (+ 2 2) 4)`;`let baz = foo("bar")`,若是把foo("bar")這種函數套用(apply)寫成`(APPLY foo "bar")`,則其S-exp語法樹可寫為`(let baz(APPLY foo "bar"))`。
|
|
@ -1,24 +0,0 @@
|
|||
[ Clo: another typesetter]{align="center"} [[
|
||||
一個排版器的實作心得]{.box}]{align="center"} []{.box} [[
|
||||
陳建町]{.box}]{align="center"}
|
||||
|
||||
版權聲明
|
||||
|
||||
\(c\) 2023 陳建町 (Tan, Kian-ting)
|
||||
|
||||
本書內容非經許可,禁止複製、分發、商業使用等違反著作權法之行為。
|
||||
|
||||
然書中之程式碼,採用
|
||||
[MIT許可證](https://opensource.org/license/mit/)授權。
|
||||
|
||||
序言
|
||||
|
||||
以前從國中時候試用Linux以及架站以後,就開始想用LaTeX排版些自己所寫的東西,其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路,還是希望有天至少能夠完成個能用的雛形。
|
||||
|
||||
但是這是涉及字體檔案的處理、PDF的處理、語法分析,後來自己因為不知道如何開發,所以一直停擺。不是遇到很多蟲,就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的
|
||||
*Digital
|
||||
Typography*,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。
|
||||
|
||||
另外筆者一個分支興趣是編譯器的相關知識,所以開始讀和王垠的編譯器思想系出同門的Jeremy
|
||||
G. Siek所著作之_Essential of Complication: An Incremental Approach in
|
||||
Racket
|
|
@ -1 +0,0 @@
|
|||
<svg baseProfile="full" height="248px" preserveAspectRatio="xMidYMid meet" style="font-family: times, serif; font-weight: normal; font-style: normal; font-size: 16px;" version="1.1" viewBox="0,0,144.0,248.0" width="144px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">句子</text></svg><svg width="27.7778%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">主詞</text></svg><svg width="100%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">代詞 </text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">我</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="72px" /></svg><line stroke="black" x1="50%" x2="50%" y1="19.2px" y2="56px" /></svg><line stroke="black" x1="50%" x2="13.8889%" y1="19.2px" y2="48px" /><svg width="72.2222%" x="27.7778%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">謂語</text></svg><svg width="69.2308%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">動詞</text><text text-anchor="middle" x="50%" y="32px">片語 </text></svg><svg width="44.4444%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">副詞</text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">曾</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="22.2222%" y1="35.2px" y2="72px" /><svg width="55.5556%" x="44.4444%" y="64px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">動詞 </text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">旅居</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="72.2222%" y1="35.2px" y2="72px" /></svg><line stroke="black" x1="50%" x2="34.6154%" y1="19.2px" y2="48px" /><svg width="30.7692%" x="69.2308%" y="48px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">受詞</text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">專有</text><text text-anchor="middle" x="50%" y="32px">名詞</text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">新竹</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="35.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="84.6154%" y1="19.2px" y2="56px" /></svg><line stroke="black" x1="50%" x2="63.8889%" y1="19.2px" y2="48px" /></svg>
|
Before Width: | Height: | Size: 3.1 KiB |
|
@ -1 +0,0 @@
|
|||
<svg baseProfile="full" height="120px" preserveAspectRatio="xMidYMid meet" style="font-family: times, serif; font-weight: normal; font-style: normal; font-size: 16px;" version="1.1" viewBox="0,0,72.0,120.0" width="72px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">==</text></svg><svg width="66.6667%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">+</text></svg><svg width="50%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">1</text></svg></svg><line stroke="black" x1="50%" x2="25%" y1="19.2px" y2="48px" /><svg width="50%" x="50%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">1</text></svg></svg><line stroke="black" x1="50%" x2="75%" y1="19.2px" y2="48px" /></svg><line stroke="black" x1="50%" x2="33.3333%" y1="19.2px" y2="48px" /><svg width="33.3333%" x="66.6667%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">2</text></svg></svg><line stroke="black" x1="50%" x2="83.3333%" y1="19.2px" y2="48px" /></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
BIN
legacies/src/ch2/target/debug/ch1 → legacies/legacies.tar.bz2
Executable file → Normal file
BIN
legacies/src/ch2/target/debug/ch1 → legacies/legacies.tar.bz2
Executable file → Normal file
Binary file not shown.
|
@ -1,11 +0,0 @@
|
|||
site_name: Another Typesetter 另一個排版器
|
||||
site_url: https://blog.kianting.info/pages/docs/anotherTypeSetter/
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Ch 1: defineASTandGrammar.md
|
||||
- Ch 2: 2DManipulating.md
|
||||
theme: readthedocs
|
||||
|
||||
markdown_extensions:
|
||||
- attr_list
|
||||
- md_in_html
|
|
@ -1,128 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
|
||||
<link rel="shortcut icon" href="/pages/docs/anotherTypeSetter/img/favicon.ico">
|
||||
<title>Another Typesetter 另一個排版器</title>
|
||||
<link rel="stylesheet" href="/pages/docs/anotherTypeSetter/css/theme.css" />
|
||||
<link rel="stylesheet" href="/pages/docs/anotherTypeSetter/css/theme_extra.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
|
||||
|
||||
<script src="/pages/docs/anotherTypeSetter/js/jquery-2.1.1.min.js" defer></script>
|
||||
<script src="/pages/docs/anotherTypeSetter/js/modernizr-2.8.3.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search">
|
||||
<a href="/pages/docs/anotherTypeSetter/." class="icon icon-home"> Another Typesetter 另一個排版器</a>
|
||||
<div role="search">
|
||||
<form id ="rtd-search-form" class="wy-form" action="/pages/docs/anotherTypeSetter//search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" title="Type search term here" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="/pages/docs/anotherTypeSetter/.">Home</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="/pages/docs/anotherTypeSetter/defineASTandGrammar/">Ch 1</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="" href="/pages/docs/anotherTypeSetter/2DManipulating.md">Ch 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="/pages/docs/anotherTypeSetter/.">Another Typesetter 另一個排版器</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="/pages/docs/anotherTypeSetter/.">Docs</a> »</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main">
|
||||
<div class="section">
|
||||
|
||||
|
||||
<h1 id="404-page-not-found">404</h1>
|
||||
|
||||
<p><strong>Page not found</strong></p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<!-- Copyright etc -->
|
||||
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
|
||||
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<script>var base_url = '/pages/docs/anotherTypeSetter/';</script>
|
||||
<script src="/pages/docs/anotherTypeSetter/js/theme.js" defer></script>
|
||||
<script src="/pages/docs/anotherTypeSetter/search/main.js" defer></script>
|
||||
<script defer>
|
||||
window.onload = function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* Wrap inline code samples otherwise they shoot of the side and
|
||||
* can't be read at all.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/313
|
||||
* https://github.com/mkdocs/mkdocs/issues/233
|
||||
* https://github.com/mkdocs/mkdocs/issues/834
|
||||
*/
|
||||
.rst-content code {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make code blocks display as blocks and give them the appropriate
|
||||
* font size and padding.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/855
|
||||
* https://github.com/mkdocs/mkdocs/issues/834
|
||||
* https://github.com/mkdocs/mkdocs/issues/233
|
||||
*/
|
||||
.rst-content pre code {
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
display: block;
|
||||
padding: 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix code colors
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/2027
|
||||
*/
|
||||
.rst-content code {
|
||||
color: #E74C3C;
|
||||
}
|
||||
|
||||
.rst-content pre code {
|
||||
color: #000;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix link colors when the link text is inline code.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/718
|
||||
*/
|
||||
a code {
|
||||
color: #2980B9;
|
||||
}
|
||||
a:hover code {
|
||||
color: #3091d1;
|
||||
}
|
||||
a:visited code {
|
||||
color: #9B59B6;
|
||||
}
|
||||
|
||||
/*
|
||||
* The CSS classes from highlight.js seem to clash with the
|
||||
* ReadTheDocs theme causing some code to be incorrectly made
|
||||
* bold and italic.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/411
|
||||
*/
|
||||
pre .cs, pre .c {
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix some issues with the theme and non-highlighted code
|
||||
* samples. Without and highlighting styles attached the
|
||||
* formatting is broken.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/319
|
||||
*/
|
||||
.rst-content .no-highlight {
|
||||
display: block;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Additions specific to the search functionality provided by MkDocs
|
||||
*/
|
||||
|
||||
.search-results {
|
||||
margin-top: 23px;
|
||||
}
|
||||
|
||||
.search-results article {
|
||||
border-top: 1px solid #E1E4E5;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.search-results article:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
form .search-query {
|
||||
width: 100%;
|
||||
border-radius: 50px;
|
||||
padding: 6px 12px; /* csslint allow: box-model */
|
||||
border-color: #D1D4D5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improve inline code blocks within admonitions.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/656
|
||||
*/
|
||||
.rst-content .admonition code {
|
||||
color: #404040;
|
||||
border: 1px solid #c7c9cb;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
background: #f8fbfd;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
/*
|
||||
* Account for wide tables which go off the side.
|
||||
* Override borders to avoid wierdness on narrow tables.
|
||||
*
|
||||
* https://github.com/mkdocs/mkdocs/issues/834
|
||||
* https://github.com/mkdocs/mkdocs/pull/1034
|
||||
*/
|
||||
.rst-content .section .docutils {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
border: none;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 1px solid #e1e4e5 !important; /* csslint allow: important */
|
||||
border-collapse: collapse;
|
||||
}
|
|
@ -1,312 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
<link rel="canonical" href="https://blog.kianting.info/pages/docs/anotherTypeSetter/defineASTandGrammar/">
|
||||
<link rel="shortcut icon" href="../img/favicon.ico">
|
||||
<title>Ch 1 - Another Typesetter 另一個排版器</title>
|
||||
<link rel="stylesheet" href="../css/theme.css" />
|
||||
<link rel="stylesheet" href="../css/theme_extra.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
|
||||
|
||||
<script>
|
||||
// Current page data
|
||||
var mkdocs_page_name = "Ch 1";
|
||||
var mkdocs_page_input_path = "defineASTandGrammar.md";
|
||||
var mkdocs_page_url = "/pages/docs/anotherTypeSetter/defineASTandGrammar/";
|
||||
</script>
|
||||
|
||||
<script src="../js/jquery-2.1.1.min.js" defer></script>
|
||||
<script src="../js/modernizr-2.8.3.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search">
|
||||
<a href=".." class="icon icon-home"> Another Typesetter 另一個排版器</a>
|
||||
<div role="search">
|
||||
<form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" title="Type search term here" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="..">Home</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="reference internal current" href="./">Ch 1</a>
|
||||
<ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="#_1">抽象語法樹</a>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#_2">決定語法</a>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#parsercombinatortokenize">用ParserCombinator進行tokenize</a>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#_3">平面操作</a>
|
||||
<ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#_4">基本函數與直譯器</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="" href="../2DManipulating.md">Ch 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="..">Another Typesetter 另一個排版器</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="..">Docs</a> »</li>
|
||||
|
||||
|
||||
|
||||
<li>Ch 1</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main">
|
||||
<div class="section">
|
||||
|
||||
<h1 id="ch1">Ch1 定義抽象語法樹和語法</h1>
|
||||
<h2 id="_1">抽象語法樹</h2>
|
||||
<p>C語言、Python語言就算有許多的關鍵字、操作符、符號或是常數變數,在編譯器分析語法以後,最後會轉成編譯器可以操作的樹結構,然後再轉成我們想要的另一個語言的樹,最後輸出另一個語言的程式碼。</p>
|
||||
<p>但是什麼叫做抽象語法樹呢?我們先從一點句法知識來談。</p>
|
||||
<p>學過中學國文文法的課程,會背一堆類似「主詞+動詞+受詞」、「主詞+(有/無)+受詞」的結構。可以換個說法,是句子=「主詞+動詞+受詞」或是「主詞+(有/無)+賓詞」的形式。我們將「=」寫成「::=」,「/」(或是)寫成「|」,「動詞」擴充變成「動詞片語」,就變成:</p>
|
||||
<pre><code> 句子 ::= (主詞 動詞片語 受詞) | (主詞 (有 | 無) 受詞)...
|
||||
|
||||
</code></pre>
|
||||
<p>為了易讀所以寫成:</p>
|
||||
<pre><code>句子 ::= 主詞 動詞片語 受詞
|
||||
| 主詞 (有 | 無) 受詞
|
||||
| ...
|
||||
|
||||
</code></pre>
|
||||
<p>用這種形式表示的語言句法,叫做「BNF文法」。這種句法看起來很語言學,但是我們想:受詞和主詞可以為名詞、專有名詞或是「形容詞+名詞」;動詞片語可以為動詞或是「副詞+動詞」。因此這樣之規則,就可以生成許多句子,比如「我有筆」、「張三養貓」、「小芳慢慢移動檯燈」等等的句子。然後句子可以用上述規則,分析成語法的樹狀結構,如下圖把「我曾旅居新竹」寫成語法樹。</p>
|
||||
<figure>
|
||||
<p><img alt="「我曾旅居新竹」的語法樹" src="../syntaxtree.svg" title="" />
|
||||
</p>
|
||||
<figcaption>「我曾旅居新竹」的語法樹</figcaption>
|
||||
</figure>
|
||||
<p>同理,程式語言通常也有更嚴謹的這樣生成文法,可以用幾個簡單規則生出繁多的程式碼,而且合乎語法規定。這種生成文法也可檢查輸入的程式碼有沒有符合句法的規定。而這種語法生成的程式碼,去掉不需要的逗號等等符號,當然也可以做成語法樹,就是抽象語法樹 (abstract syntax tree, AST),如下圖所示。</p>
|
||||
<figure>
|
||||
<p><img alt="「(2+2) == 4」的語法樹。注意括號已經刪除。" src="../syntaxtree2.svg" title="" />
|
||||
</p>
|
||||
<figcaption>「(2+2) == 4」的語法樹。注意括號已經刪除。</figcaption>
|
||||
</figure>
|
||||
<p>而上文的抽象語法樹,可以是我們把程式經過編譯器分析之後,用「樹」儲存的資料結構。而樹形結構我們可以使用Lisp語言的S表達式(S-expressiom; S-exp)來表示,本文採用這樣的表示方法。所以上文的<code>(2+2)==4</code>即<code>(== (+ 2 2) 4)</code>;<code>let baz = foo("bar")</code>,若是把foo("bar")這種函數套用(apply)寫成<code>(APPLY foo "bar")</code>,則其S-exp語法樹可寫為<code>(let baz(APPLY foo "bar"))</code>。</p>
|
||||
<h2 id="_2">決定語法</h2>
|
||||
<p>那我們要如何制定這個語言的語法,這樣我們才能夠寫出符合這個語法的函數,然後再用tokenizer和parser轉成AST樹。</p>
|
||||
<p>不考慮<code>+ - * /</code>這種運算子,以及向量的表示子,函數可以用<code>ID(arg1, arg2, ...)</code>這種方式來表示,其中<code>arg_x</code>是引數,<code>ID</code>是識別子(identifier,可以把它想成變函數的名字)。</p>
|
||||
<p>變數可以是<code>ID</code>,<code>arg_n</code>可以是<code>ID</code>或常數(量)。</p>
|
||||
<p>常數(量)的表示法可以是下列任一:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>浮點數如0.0, 36.8,BNF風格的表達法為:<code>[0-9]+ '.' [0-9]+</code>。<code>'c'</code>指c這個文字,<code>+</code>表示前面的重複1次以上;<code>[0-9]</code>表示數字0到9。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>整數如22、0:<code>[0-9]+</code></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>字串:<code>'"' (不是「"」的任一字元|('\' '"')) '"'</code>(<code>.</code>表示任何一個字元)</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>然而我們還是需要綁定變數<code>let x = var in boby</code>(在<code>body</code>裡面,<code>x</code>指代<code>var</code>)、<code>set x = var</code>(改變變數值)、lambda<code>lambda (x)=>{body}</code>。另外為了要區別要在PDF印上去的一般字元,在這個檔案的常數、變數、函數、關鍵字等前後需要加@表示(但是函數、lambda裡面的變數不用)。比如<code>@foo(a, b)@</code>、<code>@lambda(x)@</code>、<code>@"IAmAString"@</code>、<code>@2.2@</code>、<code>@3@</code>(後三者應該很少用到)可是若需在PDF印<code>@</code>時怎辦?那就用<code>\@</code>。比如<code>foo\@example.com</code>。</p>
|
||||
<p>所以我們可以定義以下的BNF風文法:</p>
|
||||
<pre><code>Language ::= PrintTxt | Exprs
|
||||
|
||||
PrintTxt ::= (('\' '@')| 非@字元)+ //「我是一隻貓」或是「www\@example.com」
|
||||
|
||||
Exprs ::= @ Expr* @ // *表示前面的重複0次以上(包含不出現)
|
||||
|
||||
Expr ::= (Letting | Setting | Lambda | Apply | Var| Const) | "(" Expr ")"
|
||||
|
||||
Letting ::= "let" Var "=" Expr "in" Expr // let foo = 12 in ...
|
||||
|
||||
Setting ::= Var ":=" Expr "in" Expr // foo := a in ...
|
||||
|
||||
Lambda ::= "fn" Var "->" Expr // fn x -> 12
|
||||
|
||||
Apply ::= Expr Expr // foo 3 即foo(3)
|
||||
|
||||
Var ::= ID
|
||||
|
||||
Const ::= String | Float | Int
|
||||
|
||||
Int ::= [0-9]+
|
||||
|
||||
Float ::= [0-9]+ "." [0-9]+
|
||||
|
||||
String ::= '"' (不是「"」的任一字元|('\' '"')) '"'
|
||||
</code></pre>
|
||||
<h2 id="parsercombinatortokenize">用ParserCombinator進行tokenize</h2>
|
||||
<p>Parser combinator(分析器組合子)是一種利用高階函數來簡化分析器撰寫的辦法。講一個簡單的案例吧:</p>
|
||||
<p>假設我們想要將字串的開頭match 0~9 之中的其中一個,我們可以寫一個函數match0to9如下:</p>
|
||||
<pre><code>function match0to9(string){
|
||||
if (string[0] in 0,1,..,9){
|
||||
let rest = string[1:];
|
||||
let matched = string[0];
|
||||
return {type: "OK", rest : rest, matched : matched};
|
||||
}
|
||||
else{
|
||||
return {type : "Nothing"};
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>假設我們要將字串的前兩個字的match 0~9呢?如果會高階函數的話,引入一個<code>then</code>函數,然後把<code>match0to9</code>傳進去,這樣寫起來比較簡潔:</p>
|
||||
<pre><code>function thenDo(input, fun){
|
||||
if (input.type != "Nothing"{
|
||||
|
||||
middle = fun(input.rest);
|
||||
if (middle.type != "Nothing"){
|
||||
middle.matched = input.matched + middle.matched
|
||||
return middle;
|
||||
}else{
|
||||
return middle; // return nothing
|
||||
}
|
||||
}else{
|
||||
input; // return nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</code></pre>
|
||||
<h2 id="_3">平面操作</h2>
|
||||
<h3 id="_4">基本函數與直譯器</h3>
|
||||
<p>我們藉由以上的概念,可以定義一個將文字、線條等形狀排列到2D平面的語法,畢竟不論輸出PDF、SVG等等,粗略而言,就是一種2D平面安放文字的語言。另外PDF的格式相當晦澀,就算_PDF Explained_的PDF教學,也還是要輔助使用其他的工具,沒辦法看了就自己手刻PDF,所以還是用<code>printpdf</code>來教學吧。</p>
|
||||
<p>現在我們初始化一個專案目錄,然後將需要的S-exp函式庫和pdf函數庫指定為相依函式庫:</p>
|
||||
<pre><code>cargo init;
|
||||
|
||||
cargo add rsexp printpdf;
|
||||
</code></pre>
|
||||
<p>我們可以定義一些表達式(包含函數、資料結構,S-exp形式)的說明如下。<code>'()</code>表示空列表(empty list),因為都要表達是函數的引用,所有的函數寫成形式<code>(Func "函數名稱" (引數1 引數2 ....))</code>。Float指64位元浮點數:</p>
|
||||
<pre><code>(px Float) ; px表達pixel單位,儲存浮點數
|
||||
(pt Float) ; pt表達point單位,儲存浮點數
|
||||
(style (str pt)) ; 文字樣式。String表示字型的路徑[fontPath],Float表示字型大小(in Pt) (fontSize)
|
||||
(str String) ; 儲存字串
|
||||
(func "createPDF" '()) ;新增PDF
|
||||
(func "createPage" '()) ;新增頁面
|
||||
(func "writePdf" '(str)) ;寫入PDF頁面,String是PATH
|
||||
|
||||
(func "putchar" '(str style x y)) ; x 軸向右,y 軸向下,str 表示字元(char),style 表示文字樣式
|
||||
</code></pre>
|
||||
<p><code>main.rs</code>先引用函式庫:
|
||||
<code>use printpdf::*;</code></p>
|
||||
<p>其中 <code>px</code>、<code>pt</code>是單位,所以可以在<code>main.rs</code>這樣定義:</p>
|
||||
<pre><code>enum Measure{
|
||||
Pt(f64),
|
||||
Px(f64)
|
||||
}
|
||||
</code></pre>
|
||||
<p>最後一次定義expression:</p>
|
||||
<pre><code>enum Expr{
|
||||
Mea(Measure), // wrapper for measure
|
||||
Str(&str),
|
||||
Style{font_path : Measure, size : Measure},
|
||||
Func(&str, Vec<Expr>),
|
||||
Void // return nothing
|
||||
}
|
||||
</code></pre>
|
||||
<p>然後我們可以這樣定義一個處理輸入輸出的interpreter於<code>interp</code>,並修改<code>main.rs</code>如下,縱使我們準時:</p>
|
||||
<pre><code>fn interp(exp : Expr)->(){
|
||||
// the function will be extended.
|
||||
match exp {
|
||||
Expr::Mea(Measure::Pt(x)) => println!("{:?} pt", x),
|
||||
Expr::Mea(Measure::Px(x)) => println!("{:?} px", x),
|
||||
|
||||
_ => println!("not found expression"),
|
||||
};
|
||||
}
|
||||
|
||||
// exexute interpreter
|
||||
fn main() {
|
||||
interp(Expr::Mea(Measure::Pt(2.2)));
|
||||
interp(Expr::Flo(2.2));
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
|
||||
<a href=".." class="btn btn-neutral" title="Home"><span class="icon icon-circle-arrow-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<!-- Copyright etc -->
|
||||
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
|
||||
|
||||
<span><a href=".." style="color: #fcfcfc;">« Previous</a></span>
|
||||
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<script>var base_url = '..';</script>
|
||||
<script src="../js/theme.js" defer></script>
|
||||
<script src="../search/main.js" defer></script>
|
||||
<script defer>
|
||||
window.onload = function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
Before Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,172 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="None">
|
||||
|
||||
<link rel="canonical" href="https://blog.kianting.info/pages/docs/anotherTypeSetter/">
|
||||
<link rel="shortcut icon" href="img/favicon.ico">
|
||||
<title>Another Typesetter 另一個排版器</title>
|
||||
<link rel="stylesheet" href="css/theme.css" />
|
||||
<link rel="stylesheet" href="css/theme_extra.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
|
||||
|
||||
<script>
|
||||
// Current page data
|
||||
var mkdocs_page_name = "Home";
|
||||
var mkdocs_page_input_path = "index.md";
|
||||
var mkdocs_page_url = "/pages/docs/anotherTypeSetter/";
|
||||
</script>
|
||||
|
||||
<script src="js/jquery-2.1.1.min.js" defer></script>
|
||||
<script src="js/modernizr-2.8.3.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search">
|
||||
<a href="." class="icon icon-home"> Another Typesetter 另一個排版器</a>
|
||||
<div role="search">
|
||||
<form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" title="Type search term here" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="reference internal current" href=".">Home</a>
|
||||
<ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="#_1">摘要</a>
|
||||
<ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#_2">序言</a>
|
||||
</li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#_3">先備知識</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="defineASTandGrammar/">Ch 1</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="" href="2DManipulating.md">Ch 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href=".">Another Typesetter 另一個排版器</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href=".">Docs</a> »</li>
|
||||
|
||||
|
||||
|
||||
<li>Home</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main">
|
||||
<div class="section">
|
||||
|
||||
<h1 id="another-typesetter-">Another Typesetter - 另一個排版器</h1>
|
||||
<h2 id="_1">摘要</h2>
|
||||
<p>本文是講一個排版器的雛形如何製作的考察,使用Rust語言。</p>
|
||||
<h3 id="_2">序言</h3>
|
||||
<p>以前從國中時候試用Linux以及架站以後,就開始想用LaTeX排版些自己所寫的東西,其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路,還是希望有天至少能夠完成個能用的雛形。</p>
|
||||
<p>但是這是涉及字體檔案的處理、PDF的處理、語法分析,後來自己因為不知道如何開發,所以一直停擺。不是遇到很多蟲,就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的 <em>Digital Typography</em>,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。</p>
|
||||
<p>另外筆者一個分支興趣是編譯器的相關知識,所以開始讀和王垠的編譯器思想系出同門的Jeremy G. Siek所著作之 <em>Essential of Complication: An Incremental Approach in Racket</em>(編譯之要素:Racket語言的遞增的方法)。我想到:既然編譯器這種複雜的軟體,可以一層一層的用pass來遞增功能,就像水彩從背景、大物體一直由少漸多的完成。而排版軟體也是把使用者輸入的排版之領域特定語言(DSL)轉換成文字、圖形和二維座標對應關係(最後匯出成PDF或SVG等等)的編譯器,若是能夠用層層遞增的方法來完成,相信也能夠避免結構的複雜化導致錯誤容易發生的挫折。</p>
|
||||
<p>然而排版語言不只是輸入文字轉圖形而已,更重要的是還要有因應美觀的自動斷行(justification)和斷字(hyphenation)等等的演算法、還有PDF的基本知識、字型函式庫的取用、排版要求(多欄)、甚至還牽涉到語言特有的特性:比如東亞全形文字(漢字、諺文、日文假名、注音符號)和非全形文字中間要加空白,以及從左寫到右的文字(希伯來字母和阿拉伯字母等)的排版方法,不一而足。</p>
|
||||
<p>為了簡化起見,且目標讀者是臺灣的受眾,本書僅涉及到ASCII英文字母——頂多加些一些附加符號(diacritics)和漢字的排版。其他的功能希望讀者可以漸次由少漸多的附加。另外這邊會使用到一些LISP的表達式來表達抽象語法樹,若是不懂的話,可以看一點教 Lisp或是Scheme的書,如SICP。另外這本書不是編譯原理和描述PDF規格的書,不涉獵底層的知識,有需要的可以參考相關領域的書。</p>
|
||||
<h3 id="_3">先備知識</h3>
|
||||
<p>這不是教一位入門使用者如從零知識撰寫排版軟體的書,讀者應該有知道如何使用靜態型別語言的經驗,比如一點C、或是Rust等等。另外抽象語法樹為求方便,使用LISP撰寫,所以需要會LISP和Scheme的知識(知名教科書SICP的開頭可以讀一讀)。</p>
|
||||
<p>這本書也不教編譯理論和tokenizing、parsing、狀態機等等的,頂多只會帶到一些很基礎的知識,有需要的請另外再讀。所以使用者需要會有使用正規表達式(regex)的能力。</p>
|
||||
<p>操作環境使用Linux。需要安裝fontconfig等套件。</p>
|
||||
<ul>
|
||||
<li><a href="./defineASTandGrammar">定義抽象語法樹和語法</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="defineASTandGrammar/" class="btn btn-neutral float-right" title="Ch 1">Next <span class="icon icon-circle-arrow-right"></span></a>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<!-- Copyright etc -->
|
||||
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
|
||||
|
||||
|
||||
<span style="margin-left: 15px"><a href="defineASTandGrammar/" style="color: #fcfcfc">Next »</a></span>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<script>var base_url = '.';</script>
|
||||
<script src="js/theme.js" defer></script>
|
||||
<script src="search/main.js" defer></script>
|
||||
<script defer>
|
||||
window.onload = function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!--
|
||||
MkDocs version : 1.1.2
|
||||
Build Date UTC : 2023-12-01 16:29:33.709363+00:00
|
||||
-->
|
|
@ -1,17 +0,0 @@
|
|||
# Welcome to MkDocs
|
||||
|
||||
For full documentation visit [mkdocs.org](https://www.mkdocs.org).
|
||||
|
||||
## Commands
|
||||
|
||||
* `mkdocs new [dir-name]` - Create a new project.
|
||||
* `mkdocs serve` - Start the live-reloading docs server.
|
||||
* `mkdocs build` - Build the documentation site.
|
||||
* `mkdocs -h` - Print help message and exit.
|
||||
|
||||
## Project layout
|
||||
|
||||
mkdocs.yml # The configuration file.
|
||||
docs/
|
||||
index.md # The documentation homepage.
|
||||
... # Other markdown pages, images and other files.
|
Binary file not shown.
|
@ -1,193 +0,0 @@
|
|||
#set heading(numbering: "1.1.1.1.")
|
||||
|
||||
#show raw: set text(font: "Noto Sans Mono CJK TC")
|
||||
|
||||
|
||||
#set page("a5")
|
||||
|
||||
#set text(
|
||||
font: ("New Computer Modern", "AR PL UMing TW"),
|
||||
size: 11pt
|
||||
)
|
||||
|
||||
#show heading: it => [
|
||||
#set text(font: "Noto Serif CJK TC",
|
||||
weight: "black")
|
||||
#it.body
|
||||
]
|
||||
|
||||
#set par( justify: true,leading: 1em,
|
||||
)
|
||||
|
||||
#align(center)[#set text(
|
||||
font: ("EB Garamond 08"),
|
||||
weight:"medium",
|
||||
size: 20pt,
|
||||
)
|
||||
Clo: another typesetter]
|
||||
#align(center)[#box([#set text(size: 15pt,
|
||||
font: "Noto Serif CJK TC",
|
||||
weight:"medium")
|
||||
一個排版器的實作心得])]
|
||||
#box(
|
||||
height:0.5em
|
||||
)
|
||||
#align(center)[#box([#set text(size: 11pt,
|
||||
font: "AR PL UMing TW",
|
||||
weight:"light")
|
||||
陳建町])]
|
||||
|
||||
#pagebreak()
|
||||
|
||||
|
||||
|
||||
|
||||
#set page(
|
||||
margin: (top: 60pt, bottom: 20pt),
|
||||
header: locate(
|
||||
loc => if (calc.odd(loc.page()) == true){
|
||||
[#set align(right)
|
||||
#numbering("i", loc.page())
|
||||
]
|
||||
} else {
|
||||
[#set align(left)
|
||||
#numbering("i", loc.page())]
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
|
||||
#heading(level:2, "版權聲明",outlined:false)
|
||||
|
||||
(c) 2023 陳建町 (Tan, Kian-ting)
|
||||
|
||||
本書內容非經許可,禁止複製、分發、商業使用等違反著作權法之行為。
|
||||
|
||||
然書中之程式碼,採用 #link("https://opensource.org/license/mit/")[MIT許可證]授權。
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#outline(
|
||||
title: align(left, [目#box(width:1em)錄 #box(
|
||||
height:1.5em)]),
|
||||
target: heading.where(outlined: true),
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#set page(
|
||||
numbering: "i",
|
||||
number-align: top+right)
|
||||
|
||||
#heading(numbering: none, "序言")
|
||||
|
||||
以前從國中時候試用Linux以及架站以後,就開始想用LaTeX排版些自己所寫的東西,其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路,還是希望有天至少能夠完成個能用的雛形。
|
||||
|
||||
但是這是涉及字體檔案的處理、PDF的處理、語法分析,後來自己因為不知道如何開發,所以一直停擺。不是遇到很多蟲,就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的 _Digital Typography_,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。
|
||||
|
||||
另外筆者一個分支興趣是編譯器的相關知識,所以開始讀和王垠的編譯器思想系出同門的Jeremy G. Siek所著作之_Essential of Complication: An Incremental Approach in Racket_(編譯之要素:Racket語言的遞增的方法)。我想到:既然編譯器這種複雜的軟體,可以一層一層的用pass來遞增功能,就像水彩從背景、大物體一直由少漸多的完成。而排版軟體也是把使用者輸入的排版之領域特定語言(DSL)轉換成文字、圖形和二維座標對應關係(最後匯出成PDF或SVG等等)的編譯器,若是能夠用層層遞增的方法來完成,相信也能夠避免結構的複雜化導致錯誤容易發生的挫折。
|
||||
|
||||
然而排版語言不只是輸入文字轉圖形而已,更重要的是還要有因應美觀的自動斷行(justification)和斷字(hyphenation)等等的演算法、還有PDF的基本知識、字型函式庫的取用、排版要求(多欄)、甚至還牽涉到語言特有的特性:比如東亞全形文字(漢字、諺文、日文假名、注音符號)和非全形文字中間要加空白,以及從左寫到右的文字(希伯來字母和阿拉伯字母等)的排版方法,不一而足。
|
||||
|
||||
為了簡化起見,且目標讀者是臺灣的受眾,本書僅涉及到ASCII英文字母——頂多加些一些附加符號(diacritics)和漢字的排版。其他的功能希望讀者可以漸次由少漸多的附加。另外這邊會使用到一些LISP的表達式來表達抽象語法樹,若是不懂的話,可以看一點教 Lisp或是Scheme的書,如SICP。另外這本書不是編譯原理和描述PDF規格的書,不涉獵底層的知識,有需要的可以參考相關領域的書。
|
||||
|
||||
#heading(numbering: none, "致謝")
|
||||
|
||||
感謝Donald Knuth教授開發出這麼一套排版系統以及排版的演算法,除了造福科學排版的諸多用戶外,也間接鼓舞我想要研究排版軟體如何實作;感謝Jeremy G.Siek老師的_Essential of Complication: An Incremental Approach in Racket_,讓我獲得排版語言編譯器設計的啟發。感謝王垠讓我對編譯器相關的技術有興趣,從而斷斷續續學習相關的資訊。
|
||||
|
||||
感謝愛爾蘭語,除了讓我對語言和語言復興的知識打開新的世界以外,這個軟體的名字Clo也是從這裡來的(cló有「活字」的意思,因為技術限制抱歉沒辦法輸入長音符號)。
|
||||
|
||||
感謝我的父母,雖然專長不是電腦資訊科技,但是要感謝他們讓我讓我有餘力能夠在中學的時候研究這種興趣,這條路才能走下去。
|
||||
|
||||
感謝這本書閱讀的人們,讓我知道筆者不是孤單的。
|
||||
|
||||
Siōng-āu Kám-siā góa ê Siōng Chú, nā-bô i ê hû-chhî kap pó-siú, chit-pún chheh iā bô-hó oân-sêng.(最後感謝上主,若無扶持保守,這本書也很難完成)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
|
||||
#set page(
|
||||
margin: (top: 60pt, bottom: 20pt),
|
||||
header: locate(
|
||||
loc =>{
|
||||
let chapter_query = query(selector(heading.where(level: 1)).after(loc),loc)
|
||||
let section_query = query(selector(heading.where(level: 2)).after(loc),loc)
|
||||
let chapter = "";
|
||||
let section = "";
|
||||
if chapter_query == (){chapter = ""}
|
||||
else{chapter = chapter_query.at(0).body};
|
||||
if section_query == (){section = ""}
|
||||
else{section = section_query.at(0).body}
|
||||
|
||||
|
||||
|
||||
|
||||
if (calc.odd(loc.page()) == true){
|
||||
grid(
|
||||
columns: (0.333333fr, 0.333333fr, 0.333333fr),
|
||||
|
||||
text(style: "italic")[ ],
|
||||
[#set align(center)
|
||||
#chapter],
|
||||
[ #h(1fr) #loc.page-numbering()])
|
||||
} else {
|
||||
grid(
|
||||
columns: (0.333333fr, 0.333333fr, 0.333333fr),
|
||||
|
||||
text(style: "italic")[#loc.page-numbering()],
|
||||
[#set align(center)
|
||||
#section],
|
||||
[ ])
|
||||
}}
|
||||
));
|
||||
|
||||
#show heading: it => [
|
||||
#set text(font: ("New Computer Modern", "Noto Serif CJK TC"),
|
||||
weight: "black")
|
||||
#counter(heading).display() #it
|
||||
]
|
||||
|
||||
|
||||
#set page(numbering: "1")
|
||||
#counter(page).update(1)
|
||||
#set heading(numbering: "1.1.1.1.1")
|
||||
= 先備知識
|
||||
|
||||
這不是教一位入門使用者如從零知識撰寫排版軟體的書,讀者應該有知道如何使用靜態型別語言的經驗,比如一點C、或是Rust等等。另外抽象語法樹為求方便,使用LISP撰寫,所以需要會LISP和Scheme的知識(知名教科書SICP的開頭可以讀一讀)。
|
||||
|
||||
這本書也不教編譯理論和tokenizing、parsing、狀態機等等的,頂多只會帶到一些很基礎的知識,有需要的請另外再讀。所以使用者需要會有使用正規表達式(regex)的能力。
|
||||
|
||||
== 抽象語法樹
|
||||
|
||||
C語言、Python語言就算有許多的關鍵字、操作符、符號或是常數變數,在編譯器分析語法以後,最後會轉成編譯器可以操作的樹結構,然後再轉成我們想要的另一個語言的樹,最後輸出另一個語言的程式碼。
|
||||
|
||||
但是什麼叫做抽象語法樹呢?我們先從一點句法知識來談。
|
||||
|
||||
學過中學國文文法的課程,會背一堆類似「主詞+動詞+受詞」、「主詞+(有/無)+受詞」的結構。可以換個說法,是句子=「主詞+動詞+受詞」或是「主詞+(有/無)+賓詞」的形式。我們將「=」寫成「::=」,「/」(或是)寫成「|」,動詞擴充變成「動詞片語」,就變成:
|
||||
|
||||
```
|
||||
句子 ::= (主詞 動詞片語 受詞) | (主詞 (有 | 無) 受詞)...
|
||||
|
||||
```
|
||||
|
||||
用這種形式表示的語言句法,叫做「BNF文法」。這種句法看起來很語言學,但是我們想:受詞和主詞可以為名詞、專有名詞或是「形容詞+名詞」;動詞片語可以為動詞或是「副詞+動詞」。因此這樣之規則,就可以生成許多句子,比如「我有筆」、「張三養貓」、「小芳慢慢移動檯燈」等等的句子。然後句子可以用上述規則,分析成語法的樹狀結構,如圖1把「我曾旅居新竹」寫成語法樹。
|
||||
|
||||
#figure(
|
||||
image("syntaxtree.svg", width: 40%),
|
||||
caption: [
|
||||
「我曾旅居新竹」的語法樹
|
||||
],
|
||||
supplement: [圖],
|
||||
)
|
||||
|
||||
同理,程式語言通常也有更嚴謹的這樣生成文法,可以用幾個簡單規則生出繁多的程式碼,而且合乎語法規定。這種生成文法也可檢查輸入的程式碼有沒有符合句法的規定。而這種語法生成的程式碼,去掉不需要的逗號等等符號,當然也可以做成語法樹,就是抽象語法樹 (abstract syntax tree, AST),如圖2所示。
|
||||
|
||||
#figure(
|
||||
image("syntaxtree2.svg", width: 30%),
|
||||
caption: [
|
||||
`(2+2) == 4`的語法樹。注意括號已經刪除。
|
||||
],
|
||||
supplement: [圖],
|
||||
)
|
||||
|
||||
而上文的抽象語法樹,可以是我們把程式經過編譯器分析之後,用「樹」儲存的資料結構。而樹形結構我們可以使用Lisp語言的S表達式(S-expressiom; S-exp)來表示,本文採用這樣的表示方法。所以上文的`(2+2)==4`即`(== (+ 2 2) 4)`;`let baz = foo("bar")`,若是把foo("bar")這種函數套用(apply)寫成`(APPLY foo "bar")`,則其S-exp語法樹可寫為`(let baz(APPLY foo "bar"))`。
|
|
@ -1,148 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
<link rel="canonical" href="https://blog.kianting.info/pages/docs/anotherTypeSetter/index2/">
|
||||
<link rel="shortcut icon" href="../img/favicon.ico">
|
||||
<title>Index2 - Another Typesetter 另一個排版器</title>
|
||||
<link rel="stylesheet" href="../css/theme.css" />
|
||||
<link rel="stylesheet" href="../css/theme_extra.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
|
||||
|
||||
<script>
|
||||
// Current page data
|
||||
var mkdocs_page_name = "Index2";
|
||||
var mkdocs_page_input_path = "index2.md";
|
||||
var mkdocs_page_url = "/pages/docs/anotherTypeSetter/index2/";
|
||||
</script>
|
||||
|
||||
<script src="../js/jquery-2.1.1.min.js" defer></script>
|
||||
<script src="../js/modernizr-2.8.3.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search">
|
||||
<a href=".." class="icon icon-home"> Another Typesetter 另一個排版器</a>
|
||||
<div role="search">
|
||||
<form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" title="Type search term here" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="..">Home</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../defineASTandGrammar/">Ch 1</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="" href="../2DManipulating.md">Ch 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="..">Another Typesetter 另一個排版器</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="..">Docs</a> »</li>
|
||||
|
||||
|
||||
|
||||
<li>Index2</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main">
|
||||
<div class="section">
|
||||
|
||||
<p>[ Clo: another typesetter]{align="center"} [[
|
||||
一個排版器的實作心得]{.box}]{align="center"} []{.box} [[
|
||||
陳建町]{.box}]{align="center"}</p>
|
||||
<p>版權聲明</p>
|
||||
<p>(c) 2023 陳建町 (Tan, Kian-ting)</p>
|
||||
<p>本書內容非經許可,禁止複製、分發、商業使用等違反著作權法之行為。</p>
|
||||
<p>然書中之程式碼,採用
|
||||
<a href="https://opensource.org/license/mit/">MIT許可證</a>授權。</p>
|
||||
<p>序言</p>
|
||||
<p>以前從國中時候試用Linux以及架站以後,就開始想用LaTeX排版些自己所寫的東西,其中包含覺得LaTeX的語法不好想要重造輪子。就算後來大學沒有走上資訊工程這條路,還是希望有天至少能夠完成個能用的雛形。</p>
|
||||
<p>但是這是涉及字體檔案的處理、PDF的處理、語法分析,後來自己因為不知道如何開發,所以一直停擺。不是遇到很多蟲,就是效能問題有缺失。因為時間繁忙很少更不消說了。甚至買了Knuth教授的
|
||||
<em>Digital
|
||||
Typography</em>,想要瞭解斷行演算法,結果粗估五、六十頁,所以幾乎沒有讀。</p>
|
||||
<p>另外筆者一個分支興趣是編譯器的相關知識,所以開始讀和王垠的編譯器思想系出同門的Jeremy
|
||||
G. Siek所著作之_Essential of Complication: An Incremental Approach in
|
||||
Racket</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<!-- Copyright etc -->
|
||||
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
|
||||
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<script>var base_url = '..';</script>
|
||||
<script src="../js/theme.js" defer></script>
|
||||
<script src="../search/main.js" defer></script>
|
||||
<script defer>
|
||||
window.onload = function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
2
legacies/site/js/jquery-2.1.1.min.js
vendored
2
legacies/site/js/jquery-2.1.1.min.js
vendored
File diff suppressed because one or more lines are too long
1
legacies/site/js/modernizr-2.8.3.min.js
vendored
1
legacies/site/js/modernizr-2.8.3.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,265 +0,0 @@
|
|||
var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
|
||||
|
||||
// Sphinx theme nav state
|
||||
function ThemeNav () {
|
||||
|
||||
var nav = {
|
||||
navBar: null,
|
||||
win: null,
|
||||
winScroll: false,
|
||||
winResize: false,
|
||||
linkScroll: false,
|
||||
winPosition: 0,
|
||||
winHeight: null,
|
||||
docHeight: null,
|
||||
isRunning: false
|
||||
};
|
||||
|
||||
nav.enable = function (withStickyNav) {
|
||||
var self = this;
|
||||
|
||||
// TODO this can likely be removed once the theme javascript is broken
|
||||
// out from the RTD assets. This just ensures old projects that are
|
||||
// calling `enable()` get the sticky menu on by default. All other cals
|
||||
// to `enable` should include an argument for enabling the sticky menu.
|
||||
if (typeof(withStickyNav) == 'undefined') {
|
||||
withStickyNav = true;
|
||||
}
|
||||
|
||||
if (self.isRunning) {
|
||||
// Only allow enabling nav logic once
|
||||
return;
|
||||
}
|
||||
|
||||
self.isRunning = true;
|
||||
jQuery(function ($) {
|
||||
self.init($);
|
||||
|
||||
self.reset();
|
||||
self.win.on('hashchange', self.reset);
|
||||
|
||||
if (withStickyNav) {
|
||||
// Set scroll monitor
|
||||
self.win.on('scroll', function () {
|
||||
if (!self.linkScroll) {
|
||||
if (!self.winScroll) {
|
||||
self.winScroll = true;
|
||||
requestAnimationFrame(function() { self.onScroll(); });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set resize monitor
|
||||
self.win.on('resize', function () {
|
||||
if (!self.winResize) {
|
||||
self.winResize = true;
|
||||
requestAnimationFrame(function() { self.onResize(); });
|
||||
}
|
||||
});
|
||||
|
||||
self.onResize();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// TODO remove this with a split in theme and Read the Docs JS logic as
|
||||
// well, it's only here to support 0.3.0 installs of our theme.
|
||||
nav.enableSticky = function() {
|
||||
this.enable(true);
|
||||
};
|
||||
|
||||
nav.init = function ($) {
|
||||
var doc = $(document),
|
||||
self = this;
|
||||
|
||||
this.navBar = $('div.wy-side-scroll:first');
|
||||
this.win = $(window);
|
||||
|
||||
// Set up javascript UX bits
|
||||
$(document)
|
||||
// Shift nav in mobile when clicking the menu.
|
||||
.on('click', "[data-toggle='wy-nav-top']", function() {
|
||||
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift");
|
||||
})
|
||||
|
||||
// Nav menu link click operations
|
||||
.on('click', ".wy-menu-vertical .current ul li a", function() {
|
||||
var target = $(this);
|
||||
// Close menu when you click a link.
|
||||
$("[data-toggle='wy-nav-shift']").removeClass("shift");
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift");
|
||||
// Handle dynamic display of l3 and l4 nav lists
|
||||
self.toggleCurrent(target);
|
||||
self.hashChange();
|
||||
})
|
||||
.on('click', "[data-toggle='rst-current-version']", function() {
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift-up");
|
||||
})
|
||||
|
||||
// Make tables responsive
|
||||
$("table.docutils:not(.field-list,.footnote,.citation)")
|
||||
.wrap("<div class='wy-table-responsive'></div>");
|
||||
|
||||
// Add extra class to responsive tables that contain
|
||||
// footnotes or citations so that we can target them for styling
|
||||
$("table.docutils.footnote")
|
||||
.wrap("<div class='wy-table-responsive footnote'></div>");
|
||||
$("table.docutils.citation")
|
||||
.wrap("<div class='wy-table-responsive citation'></div>");
|
||||
|
||||
// Add expand links to all parents of nested ul
|
||||
$('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
|
||||
var link = $(this);
|
||||
expand =
|
||||
$('<button class="toctree-expand" title="Open/close menu"></button>');
|
||||
expand.on('click', function (ev) {
|
||||
self.toggleCurrent(link);
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
link.prepend(expand);
|
||||
});
|
||||
};
|
||||
|
||||
nav.reset = function () {
|
||||
// Get anchor from URL and open up nested nav
|
||||
var anchor = encodeURI(window.location.hash) || '#';
|
||||
|
||||
try {
|
||||
var vmenu = $('.wy-menu-vertical');
|
||||
var link = vmenu.find('[href="' + anchor + '"]');
|
||||
if (link.length === 0) {
|
||||
// this link was not found in the sidebar.
|
||||
// Find associated id element, then its closest section
|
||||
// in the document and try with that one.
|
||||
var id_elt = $('.document [id="' + anchor.substring(1) + '"]');
|
||||
var closest_section = id_elt.closest('div.section');
|
||||
link = vmenu.find('[href="#' + closest_section.attr("id") + '"]');
|
||||
if (link.length === 0) {
|
||||
// still not found in the sidebar. fall back to main section
|
||||
link = vmenu.find('[href="#"]');
|
||||
}
|
||||
}
|
||||
// If we found a matching link then reset current and re-apply
|
||||
// otherwise retain the existing match
|
||||
if (link.length > 0) {
|
||||
$('.wy-menu-vertical .current')
|
||||
.removeClass('current')
|
||||
.attr('aria-expanded','false');
|
||||
link.addClass('current')
|
||||
.attr('aria-expanded','true');
|
||||
link.closest('li.toctree-l1')
|
||||
.parent()
|
||||
.addClass('current')
|
||||
.attr('aria-expanded','true');
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
link.closest('li.toctree-l' + i)
|
||||
.addClass('current')
|
||||
.attr('aria-expanded','true');
|
||||
}
|
||||
link[0].scrollIntoView();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log("Error expanding nav for anchor", err);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
nav.onScroll = function () {
|
||||
this.winScroll = false;
|
||||
var newWinPosition = this.win.scrollTop(),
|
||||
winBottom = newWinPosition + this.winHeight,
|
||||
navPosition = this.navBar.scrollTop(),
|
||||
newNavPosition = navPosition + (newWinPosition - this.winPosition);
|
||||
if (newWinPosition < 0 || winBottom > this.docHeight) {
|
||||
return;
|
||||
}
|
||||
this.navBar.scrollTop(newNavPosition);
|
||||
this.winPosition = newWinPosition;
|
||||
};
|
||||
|
||||
nav.onResize = function () {
|
||||
this.winResize = false;
|
||||
this.winHeight = this.win.height();
|
||||
this.docHeight = $(document).height();
|
||||
};
|
||||
|
||||
nav.hashChange = function () {
|
||||
this.linkScroll = true;
|
||||
this.win.one('hashchange', function () {
|
||||
this.linkScroll = false;
|
||||
});
|
||||
};
|
||||
|
||||
nav.toggleCurrent = function (elem) {
|
||||
var parent_li = elem.closest('li');
|
||||
parent_li
|
||||
.siblings('li.current')
|
||||
.removeClass('current')
|
||||
.attr('aria-expanded','false');
|
||||
parent_li
|
||||
.siblings()
|
||||
.find('li.current')
|
||||
.removeClass('current')
|
||||
.attr('aria-expanded','false');
|
||||
var children = parent_li.find('> ul li');
|
||||
// Don't toggle terminal elements.
|
||||
if (children.length) {
|
||||
children
|
||||
.removeClass('current')
|
||||
.attr('aria-expanded','false');
|
||||
parent_li
|
||||
.toggleClass('current')
|
||||
.attr('aria-expanded', function(i, old) {
|
||||
return old == 'true' ? 'false' : 'true';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return nav;
|
||||
};
|
||||
|
||||
_ThemeNav = ThemeNav();
|
||||
|
||||
if (typeof(window) != 'undefined') {
|
||||
window.SphinxRtdTheme = {
|
||||
Navigation: _ThemeNav,
|
||||
// TODO remove this once static assets are split up between the theme
|
||||
// and Read the Docs. For now, this patches 0.3.0 to be backwards
|
||||
// compatible with a pre-0.3.0 layout.html
|
||||
StickyNav: _ThemeNav,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
|
||||
// https://gist.github.com/paulirish/1579671
|
||||
// MIT license
|
||||
|
||||
(function() {
|
||||
var lastTime = 0;
|
||||
var vendors = ['ms', 'moz', 'webkit', 'o'];
|
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|
||||
|| window[vendors[x]+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame)
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
|
||||
if (!window.cancelAnimationFrame)
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}());
|
|
@ -1,135 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
|
||||
<link rel="shortcut icon" href="./img/favicon.ico">
|
||||
<title>Another Typesetter 另一個排版器</title>
|
||||
<link rel="stylesheet" href="./css/theme.css" />
|
||||
<link rel="stylesheet" href="./css/theme_extra.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
|
||||
|
||||
<script src="./js/jquery-2.1.1.min.js" defer></script>
|
||||
<script src="./js/modernizr-2.8.3.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search">
|
||||
<a href="./." class="icon icon-home"> Another Typesetter 另一個排版器</a>
|
||||
<div role="search">
|
||||
<form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" title="Type search term here" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="./.">Home</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="./defineASTandGrammar/">Ch 1</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="" href="./2DManipulating.md">Ch 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="./.">Another Typesetter 另一個排版器</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="./.">Docs</a> »</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main">
|
||||
<div class="section">
|
||||
|
||||
|
||||
<h1 id="search">Search Results</h1>
|
||||
|
||||
<form id="content_search" action="search.html">
|
||||
<span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span>
|
||||
<input name="q" id="mkdocs-search-query" type="text" class="search_input search-query ui-autocomplete-input" placeholder="Search the Docs" autocomplete="off" autofocus title="Type search term here">
|
||||
</form>
|
||||
|
||||
<div id="mkdocs-search-results" class="search-results">
|
||||
Searching...
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<!-- Copyright etc -->
|
||||
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
|
||||
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<script>var base_url = '.';</script>
|
||||
<script src="./js/theme.js" defer></script>
|
||||
<script src="./search/main.js" defer></script>
|
||||
<script defer>
|
||||
window.onload = function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load diff
|
@ -1,98 +0,0 @@
|
|||
function getSearchTermFromLocation() {
|
||||
var sPageURL = window.location.search.substring(1);
|
||||
var sURLVariables = sPageURL.split('&');
|
||||
for (var i = 0; i < sURLVariables.length; i++) {
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] == 'q') {
|
||||
return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function joinUrl (base, path) {
|
||||
if (path.substring(0, 1) === "/") {
|
||||
// path starts with `/`. Thus it is absolute.
|
||||
return path;
|
||||
}
|
||||
if (base.substring(base.length-1) === "/") {
|
||||
// base ends with `/`
|
||||
return base + path;
|
||||
}
|
||||
return base + "/" + path;
|
||||
}
|
||||
|
||||
function formatResult (location, title, summary) {
|
||||
return '<article><h3><a href="' + joinUrl(base_url, location) + '">'+ title + '</a></h3><p>' + summary +'</p></article>';
|
||||
}
|
||||
|
||||
function displayResults (results) {
|
||||
var search_results = document.getElementById("mkdocs-search-results");
|
||||
while (search_results.firstChild) {
|
||||
search_results.removeChild(search_results.firstChild);
|
||||
}
|
||||
if (results.length > 0){
|
||||
for (var i=0; i < results.length; i++){
|
||||
var result = results[i];
|
||||
var html = formatResult(result.location, result.title, result.summary);
|
||||
search_results.insertAdjacentHTML('beforeend', html);
|
||||
}
|
||||
} else {
|
||||
search_results.insertAdjacentHTML('beforeend', "<p>No results found</p>");
|
||||
}
|
||||
}
|
||||
|
||||
function doSearch () {
|
||||
var query = document.getElementById('mkdocs-search-query').value;
|
||||
if (query.length > min_search_length) {
|
||||
if (!window.Worker) {
|
||||
displayResults(search(query));
|
||||
} else {
|
||||
searchWorker.postMessage({query: query});
|
||||
}
|
||||
} else {
|
||||
// Clear results for short queries
|
||||
displayResults([]);
|
||||
}
|
||||
}
|
||||
|
||||
function initSearch () {
|
||||
var search_input = document.getElementById('mkdocs-search-query');
|
||||
if (search_input) {
|
||||
search_input.addEventListener("keyup", doSearch);
|
||||
}
|
||||
var term = getSearchTermFromLocation();
|
||||
if (term) {
|
||||
search_input.value = term;
|
||||
doSearch();
|
||||
}
|
||||
}
|
||||
|
||||
function onWorkerMessage (e) {
|
||||
if (e.data.allowSearch) {
|
||||
initSearch();
|
||||
} else if (e.data.results) {
|
||||
var results = e.data.results;
|
||||
displayResults(results);
|
||||
} else if (e.data.config) {
|
||||
min_search_length = e.data.config.min_search_length-1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!window.Worker) {
|
||||
console.log('Web Worker API not supported');
|
||||
// load index in main thread
|
||||
$.getScript(joinUrl(base_url, "search/worker.js")).done(function () {
|
||||
console.log('Loaded worker');
|
||||
init();
|
||||
window.postMessage = function (msg) {
|
||||
onWorkerMessage({data: msg});
|
||||
};
|
||||
}).fail(function (jqxhr, settings, exception) {
|
||||
console.error('Could not load worker.js');
|
||||
});
|
||||
} else {
|
||||
// Wrap search in a web worker
|
||||
var searchWorker = new Worker(joinUrl(base_url, "search/worker.js"));
|
||||
searchWorker.postMessage({init: true});
|
||||
searchWorker.onmessage = onWorkerMessage;
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1,130 +0,0 @@
|
|||
var base_path = 'function' === typeof importScripts ? '.' : '/search/';
|
||||
var allowSearch = false;
|
||||
var index;
|
||||
var documents = {};
|
||||
var lang = ['en'];
|
||||
var data;
|
||||
|
||||
function getScript(script, callback) {
|
||||
console.log('Loading script: ' + script);
|
||||
$.getScript(base_path + script).done(function () {
|
||||
callback();
|
||||
}).fail(function (jqxhr, settings, exception) {
|
||||
console.log('Error: ' + exception);
|
||||
});
|
||||
}
|
||||
|
||||
function getScriptsInOrder(scripts, callback) {
|
||||
if (scripts.length === 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
getScript(scripts[0], function() {
|
||||
getScriptsInOrder(scripts.slice(1), callback);
|
||||
});
|
||||
}
|
||||
|
||||
function loadScripts(urls, callback) {
|
||||
if( 'function' === typeof importScripts ) {
|
||||
importScripts.apply(null, urls);
|
||||
callback();
|
||||
} else {
|
||||
getScriptsInOrder(urls, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function onJSONLoaded () {
|
||||
data = JSON.parse(this.responseText);
|
||||
var scriptsToLoad = ['lunr.js'];
|
||||
if (data.config && data.config.lang && data.config.lang.length) {
|
||||
lang = data.config.lang;
|
||||
}
|
||||
if (lang.length > 1 || lang[0] !== "en") {
|
||||
scriptsToLoad.push('lunr.stemmer.support.js');
|
||||
if (lang.length > 1) {
|
||||
scriptsToLoad.push('lunr.multi.js');
|
||||
}
|
||||
for (var i=0; i < lang.length; i++) {
|
||||
if (lang[i] != 'en') {
|
||||
scriptsToLoad.push(['lunr', lang[i], 'js'].join('.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
loadScripts(scriptsToLoad, onScriptsLoaded);
|
||||
}
|
||||
|
||||
function onScriptsLoaded () {
|
||||
console.log('All search scripts loaded, building Lunr index...');
|
||||
if (data.config && data.config.separator && data.config.separator.length) {
|
||||
lunr.tokenizer.separator = new RegExp(data.config.separator);
|
||||
}
|
||||
|
||||
if (data.index) {
|
||||
index = lunr.Index.load(data.index);
|
||||
data.docs.forEach(function (doc) {
|
||||
documents[doc.location] = doc;
|
||||
});
|
||||
console.log('Lunr pre-built index loaded, search ready');
|
||||
} else {
|
||||
index = lunr(function () {
|
||||
if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
|
||||
this.use(lunr[lang[0]]);
|
||||
} else if (lang.length > 1) {
|
||||
this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility
|
||||
}
|
||||
this.field('title');
|
||||
this.field('text');
|
||||
this.ref('location');
|
||||
|
||||
for (var i=0; i < data.docs.length; i++) {
|
||||
var doc = data.docs[i];
|
||||
this.add(doc);
|
||||
documents[doc.location] = doc;
|
||||
}
|
||||
});
|
||||
console.log('Lunr index built, search ready');
|
||||
}
|
||||
allowSearch = true;
|
||||
postMessage({config: data.config});
|
||||
postMessage({allowSearch: allowSearch});
|
||||
}
|
||||
|
||||
function init () {
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.addEventListener("load", onJSONLoaded);
|
||||
var index_path = base_path + '/search_index.json';
|
||||
if( 'function' === typeof importScripts ){
|
||||
index_path = 'search_index.json';
|
||||
}
|
||||
oReq.open("GET", index_path);
|
||||
oReq.send();
|
||||
}
|
||||
|
||||
function search (query) {
|
||||
if (!allowSearch) {
|
||||
console.error('Assets for search still loading');
|
||||
return;
|
||||
}
|
||||
|
||||
var resultDocuments = [];
|
||||
var results = index.search(query);
|
||||
for (var i=0; i < results.length; i++){
|
||||
var result = results[i];
|
||||
doc = documents[result.ref];
|
||||
doc.summary = doc.text.substring(0, 200);
|
||||
resultDocuments.push(doc);
|
||||
}
|
||||
return resultDocuments;
|
||||
}
|
||||
|
||||
if( 'function' === typeof importScripts ) {
|
||||
onmessage = function (e) {
|
||||
if (e.data.init) {
|
||||
init();
|
||||
} else if (e.data.query) {
|
||||
postMessage({ results: search(e.data.query) });
|
||||
} else {
|
||||
console.error("Worker - Unrecognized message: " + e);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url>
|
||||
<loc>https://blog.kianting.info/pages/docs/anotherTypeSetter/</loc>
|
||||
<lastmod>2023-12-01</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url><url>
|
||||
<loc>https://blog.kianting.info/pages/docs/anotherTypeSetter/defineASTandGrammar/</loc>
|
||||
<lastmod>2023-12-01</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
</urlset>
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
<svg baseProfile="full" height="248px" preserveAspectRatio="xMidYMid meet" style="font-family: times, serif; font-weight: normal; font-style: normal; font-size: 16px;" version="1.1" viewBox="0,0,144.0,248.0" width="144px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">句子</text></svg><svg width="27.7778%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">主詞</text></svg><svg width="100%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">代詞 </text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">我</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="72px" /></svg><line stroke="black" x1="50%" x2="50%" y1="19.2px" y2="56px" /></svg><line stroke="black" x1="50%" x2="13.8889%" y1="19.2px" y2="48px" /><svg width="72.2222%" x="27.7778%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">謂語</text></svg><svg width="69.2308%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">動詞</text><text text-anchor="middle" x="50%" y="32px">片語 </text></svg><svg width="44.4444%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">副詞</text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">曾</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="22.2222%" y1="35.2px" y2="72px" /><svg width="55.5556%" x="44.4444%" y="64px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">動詞 </text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">旅居</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="72.2222%" y1="35.2px" y2="72px" /></svg><line stroke="black" x1="50%" x2="34.6154%" y1="19.2px" y2="48px" /><svg width="30.7692%" x="69.2308%" y="48px"><defs /><svg width="100%" x="0" y="8px"><defs /><text text-anchor="middle" x="50%" y="16px">受詞</text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">專有</text><text text-anchor="middle" x="50%" y="32px">名詞</text></svg><svg width="100%" x="0%" y="64px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">新竹</text></svg></svg><line stroke="black" x1="50%" x2="50%" y1="35.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="50%" y1="27.2px" y2="64px" /></svg><line stroke="black" x1="50%" x2="84.6154%" y1="19.2px" y2="56px" /></svg><line stroke="black" x1="50%" x2="63.8889%" y1="19.2px" y2="48px" /></svg>
|
Before Width: | Height: | Size: 3.1 KiB |
|
@ -1 +0,0 @@
|
|||
<svg baseProfile="full" height="120px" preserveAspectRatio="xMidYMid meet" style="font-family: times, serif; font-weight: normal; font-style: normal; font-size: 16px;" version="1.1" viewBox="0,0,72.0,120.0" width="72px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">==</text></svg><svg width="66.6667%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">+</text></svg><svg width="50%" x="0%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">1</text></svg></svg><line stroke="black" x1="50%" x2="25%" y1="19.2px" y2="48px" /><svg width="50%" x="50%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">1</text></svg></svg><line stroke="black" x1="50%" x2="75%" y1="19.2px" y2="48px" /></svg><line stroke="black" x1="50%" x2="33.3333%" y1="19.2px" y2="48px" /><svg width="33.3333%" x="66.6667%" y="48px"><defs /><svg width="100%" x="0" y="0px"><defs /><text text-anchor="middle" x="50%" y="16px">2</text></svg></svg><line stroke="black" x1="50%" x2="83.3333%" y1="19.2px" y2="48px" /></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
1
legacies/src/ch1/node_modules/.bin/esparse
generated
vendored
1
legacies/src/ch1/node_modules/.bin/esparse
generated
vendored
|
@ -1 +0,0 @@
|
|||
../esprima/bin/esparse.js
|
1
legacies/src/ch1/node_modules/.bin/esvalidate
generated
vendored
1
legacies/src/ch1/node_modules/.bin/esvalidate
generated
vendored
|
@ -1 +0,0 @@
|
|||
../esprima/bin/esvalidate.js
|
1
legacies/src/ch1/node_modules/.bin/js-yaml
generated
vendored
1
legacies/src/ch1/node_modules/.bin/js-yaml
generated
vendored
|
@ -1 +0,0 @@
|
|||
../js-yaml/bin/js-yaml.js
|
1
legacies/src/ch1/node_modules/.bin/mkdirp
generated
vendored
1
legacies/src/ch1/node_modules/.bin/mkdirp
generated
vendored
|
@ -1 +0,0 @@
|
|||
../mkdirp/bin/cmd.js
|
1
legacies/src/ch1/node_modules/.bin/resolve
generated
vendored
1
legacies/src/ch1/node_modules/.bin/resolve
generated
vendored
|
@ -1 +0,0 @@
|
|||
../resolve/bin/resolve
|
1
legacies/src/ch1/node_modules/.bin/semver
generated
vendored
1
legacies/src/ch1/node_modules/.bin/semver
generated
vendored
|
@ -1 +0,0 @@
|
|||
../semver/bin/semver.js
|
1
legacies/src/ch1/node_modules/.bin/tslint
generated
vendored
1
legacies/src/ch1/node_modules/.bin/tslint
generated
vendored
|
@ -1 +0,0 @@
|
|||
../tslint/bin/tslint
|
116
legacies/src/ch1/node_modules/.yarn-integrity
generated
vendored
116
legacies/src/ch1/node_modules/.yarn-integrity
generated
vendored
|
@ -1,116 +0,0 @@
|
|||
{
|
||||
"systemParams": "linux-x64-93",
|
||||
"modulesFolders": [
|
||||
"node_modules"
|
||||
],
|
||||
"flags": [],
|
||||
"linkedModules": [],
|
||||
"topLevelPatterns": [
|
||||
"@types/node@^20.10.4",
|
||||
"@typescript-eslint/eslint-plugin@^6.13.2",
|
||||
"@typescript-eslint/parser@^6.13.2",
|
||||
"tslint@^6.1.3",
|
||||
"typescript-parsec@^0.3.4"
|
||||
],
|
||||
"lockfileEntries": {
|
||||
"@babel/code-frame@^7.0.0": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
|
||||
"@babel/helper-validator-identifier@^7.22.20": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"@babel/highlight@^7.23.4": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
|
||||
"@eslint-community/eslint-utils@^4.4.0": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
"@eslint-community/regexpp@^4.5.1": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
||||
"@nodelib/fs.scandir@2.1.5": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"@nodelib/fs.stat@2.0.5": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"@nodelib/fs.stat@^2.0.2": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"@nodelib/fs.walk@^1.2.3": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"@types/json-schema@^7.0.12": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
"@types/node@^20.10.4": "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198",
|
||||
"@types/semver@^7.5.0": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
|
||||
"@typescript-eslint/eslint-plugin@^6.13.2": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz",
|
||||
"@typescript-eslint/parser@^6.13.2": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz",
|
||||
"@typescript-eslint/scope-manager@6.13.2": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz",
|
||||
"@typescript-eslint/type-utils@6.13.2": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz",
|
||||
"@typescript-eslint/types@6.13.2": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz",
|
||||
"@typescript-eslint/typescript-estree@6.13.2": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz",
|
||||
"@typescript-eslint/utils@6.13.2": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz",
|
||||
"@typescript-eslint/visitor-keys@6.13.2": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz",
|
||||
"ansi-styles@^3.2.1": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"argparse@^1.0.7": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"array-union@^2.1.0": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"balanced-match@^1.0.0": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"brace-expansion@^1.1.7": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"braces@^3.0.2": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"builtin-modules@^1.1.1": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||
"chalk@^2.3.0": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"chalk@^2.4.2": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"color-convert@^1.9.0": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"color-name@1.1.3": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"commander@^2.12.1": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"concat-map@0.0.1": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"debug@^4.3.4": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"diff@^4.0.1": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"dir-glob@^3.0.1": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
"escape-string-regexp@^1.0.5": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"eslint-visitor-keys@^3.3.0": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||
"eslint-visitor-keys@^3.4.1": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||
"esprima@^4.0.0": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"fast-glob@^3.2.9": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||
"fastq@^1.6.0": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
|
||||
"fill-range@^7.0.1": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"fs.realpath@^1.0.0": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"function-bind@^1.1.2": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"glob-parent@^5.1.2": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"glob@^7.1.1": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"globby@^11.1.0": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||
"graphemer@^1.4.0": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
||||
"has-flag@^3.0.0": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"hasown@^2.0.0": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
|
||||
"ignore@^5.2.0": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
|
||||
"ignore@^5.2.4": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
|
||||
"inflight@^1.0.4": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"inherits@2": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"is-core-module@^2.13.0": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
|
||||
"is-extglob@^2.1.1": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"is-glob@^4.0.1": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"is-glob@^4.0.3": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"is-number@^7.0.0": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"js-tokens@^4.0.0": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"js-yaml@^3.13.1": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"lru-cache@^6.0.0": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"merge2@^1.3.0": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"merge2@^1.4.1": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"micromatch@^4.0.4": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"minimatch@^3.0.4": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"minimatch@^3.1.1": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"minimist@^1.2.6": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"mkdirp@^0.5.3": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
"ms@2.1.2": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"natural-compare@^1.4.0": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
"once@^1.3.0": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"path-is-absolute@^1.0.0": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"path-parse@^1.0.7": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"path-type@^4.0.0": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"picomatch@^2.3.1": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"queue-microtask@^1.2.2": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"resolve@^1.3.2": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||
"reusify@^1.0.4": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"run-parallel@^1.1.9": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"semver@^5.3.0": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"semver@^7.5.4": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"slash@^3.0.0": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"sprintf-js@~1.0.2": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"supports-color@^5.3.0": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"supports-preserve-symlinks-flag@^1.0.0": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"to-regex-range@^5.0.1": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"ts-api-utils@^1.0.1": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
|
||||
"tslib@^1.13.0": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"tslib@^1.8.1": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"tslint@^6.1.3": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
|
||||
"tsutils@^2.29.0": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
|
||||
"typescript-parsec@^0.3.4": "https://registry.npmjs.org/typescript-parsec/-/typescript-parsec-0.3.4.tgz",
|
||||
"undici-types@~5.26.4": "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617",
|
||||
"wrappy@1": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"yallist@^4.0.0": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
|
||||
},
|
||||
"files": [],
|
||||
"artifacts": {}
|
||||
}
|
22
legacies/src/ch1/node_modules/@babel/code-frame/LICENSE
generated
vendored
22
legacies/src/ch1/node_modules/@babel/code-frame/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
legacies/src/ch1/node_modules/@babel/code-frame/README.md
generated
vendored
19
legacies/src/ch1/node_modules/@babel/code-frame/README.md
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
# @babel/code-frame
|
||||
|
||||
> Generate errors that contain a code frame that point to source locations.
|
||||
|
||||
See our website [@babel/code-frame](https://babeljs.io/docs/babel-code-frame) for more information.
|
||||
|
||||
## Install
|
||||
|
||||
Using npm:
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/code-frame
|
||||
```
|
||||
|
||||
or using yarn:
|
||||
|
||||
```sh
|
||||
yarn add @babel/code-frame --dev
|
||||
```
|
157
legacies/src/ch1/node_modules/@babel/code-frame/lib/index.js
generated
vendored
157
legacies/src/ch1/node_modules/@babel/code-frame/lib/index.js
generated
vendored
|
@ -1,157 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.codeFrameColumns = codeFrameColumns;
|
||||
exports.default = _default;
|
||||
var _highlight = require("@babel/highlight");
|
||||
var _chalk = _interopRequireWildcard(require("chalk"), true);
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
let chalkWithForcedColor = undefined;
|
||||
function getChalk(forceColor) {
|
||||
if (forceColor) {
|
||||
var _chalkWithForcedColor;
|
||||
(_chalkWithForcedColor = chalkWithForcedColor) != null ? _chalkWithForcedColor : chalkWithForcedColor = new _chalk.default.constructor({
|
||||
enabled: true,
|
||||
level: 1
|
||||
});
|
||||
return chalkWithForcedColor;
|
||||
}
|
||||
return _chalk.default;
|
||||
}
|
||||
let deprecationWarningShown = false;
|
||||
function getDefs(chalk) {
|
||||
return {
|
||||
gutter: chalk.grey,
|
||||
marker: chalk.red.bold,
|
||||
message: chalk.red.bold
|
||||
};
|
||||
}
|
||||
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
||||
function getMarkerLines(loc, source, opts) {
|
||||
const startLoc = Object.assign({
|
||||
column: 0,
|
||||
line: -1
|
||||
}, loc.start);
|
||||
const endLoc = Object.assign({}, startLoc, loc.end);
|
||||
const {
|
||||
linesAbove = 2,
|
||||
linesBelow = 3
|
||||
} = opts || {};
|
||||
const startLine = startLoc.line;
|
||||
const startColumn = startLoc.column;
|
||||
const endLine = endLoc.line;
|
||||
const endColumn = endLoc.column;
|
||||
let start = Math.max(startLine - (linesAbove + 1), 0);
|
||||
let end = Math.min(source.length, endLine + linesBelow);
|
||||
if (startLine === -1) {
|
||||
start = 0;
|
||||
}
|
||||
if (endLine === -1) {
|
||||
end = source.length;
|
||||
}
|
||||
const lineDiff = endLine - startLine;
|
||||
const markerLines = {};
|
||||
if (lineDiff) {
|
||||
for (let i = 0; i <= lineDiff; i++) {
|
||||
const lineNumber = i + startLine;
|
||||
if (!startColumn) {
|
||||
markerLines[lineNumber] = true;
|
||||
} else if (i === 0) {
|
||||
const sourceLength = source[lineNumber - 1].length;
|
||||
markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
|
||||
} else if (i === lineDiff) {
|
||||
markerLines[lineNumber] = [0, endColumn];
|
||||
} else {
|
||||
const sourceLength = source[lineNumber - i].length;
|
||||
markerLines[lineNumber] = [0, sourceLength];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (startColumn === endColumn) {
|
||||
if (startColumn) {
|
||||
markerLines[startLine] = [startColumn, 0];
|
||||
} else {
|
||||
markerLines[startLine] = true;
|
||||
}
|
||||
} else {
|
||||
markerLines[startLine] = [startColumn, endColumn - startColumn];
|
||||
}
|
||||
}
|
||||
return {
|
||||
start,
|
||||
end,
|
||||
markerLines
|
||||
};
|
||||
}
|
||||
function codeFrameColumns(rawLines, loc, opts = {}) {
|
||||
const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts);
|
||||
const chalk = getChalk(opts.forceColor);
|
||||
const defs = getDefs(chalk);
|
||||
const maybeHighlight = (chalkFn, string) => {
|
||||
return highlighted ? chalkFn(string) : string;
|
||||
};
|
||||
const lines = rawLines.split(NEWLINE);
|
||||
const {
|
||||
start,
|
||||
end,
|
||||
markerLines
|
||||
} = getMarkerLines(loc, lines, opts);
|
||||
const hasColumns = loc.start && typeof loc.start.column === "number";
|
||||
const numberMaxWidth = String(end).length;
|
||||
const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines;
|
||||
let frame = highlightedLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
|
||||
const number = start + 1 + index;
|
||||
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
|
||||
const gutter = ` ${paddedNumber} |`;
|
||||
const hasMarker = markerLines[number];
|
||||
const lastMarkerLine = !markerLines[number + 1];
|
||||
if (hasMarker) {
|
||||
let markerLine = "";
|
||||
if (Array.isArray(hasMarker)) {
|
||||
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
|
||||
const numberOfMarkers = hasMarker[1] || 1;
|
||||
markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), " ", markerSpacing, maybeHighlight(defs.marker, "^").repeat(numberOfMarkers)].join("");
|
||||
if (lastMarkerLine && opts.message) {
|
||||
markerLine += " " + maybeHighlight(defs.message, opts.message);
|
||||
}
|
||||
}
|
||||
return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
||||
} else {
|
||||
return ` ${maybeHighlight(defs.gutter, gutter)}${line.length > 0 ? ` ${line}` : ""}`;
|
||||
}
|
||||
}).join("\n");
|
||||
if (opts.message && !hasColumns) {
|
||||
frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`;
|
||||
}
|
||||
if (highlighted) {
|
||||
return chalk.reset(frame);
|
||||
} else {
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
function _default(rawLines, lineNumber, colNumber, opts = {}) {
|
||||
if (!deprecationWarningShown) {
|
||||
deprecationWarningShown = true;
|
||||
const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`.";
|
||||
if (process.emitWarning) {
|
||||
process.emitWarning(message, "DeprecationWarning");
|
||||
} else {
|
||||
const deprecationError = new Error(message);
|
||||
deprecationError.name = "DeprecationWarning";
|
||||
console.warn(new Error(message));
|
||||
}
|
||||
}
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
const location = {
|
||||
start: {
|
||||
column: colNumber,
|
||||
line: lineNumber
|
||||
}
|
||||
};
|
||||
return codeFrameColumns(rawLines, location, opts);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=index.js.map
|
1
legacies/src/ch1/node_modules/@babel/code-frame/lib/index.js.map
generated
vendored
1
legacies/src/ch1/node_modules/@babel/code-frame/lib/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
30
legacies/src/ch1/node_modules/@babel/code-frame/package.json
generated
vendored
30
legacies/src/ch1/node_modules/@babel/code-frame/package.json
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"name": "@babel/code-frame",
|
||||
"version": "7.23.5",
|
||||
"description": "Generate errors that contain a code frame that point to source locations.",
|
||||
"author": "The Babel Team (https://babel.dev/team)",
|
||||
"homepage": "https://babel.dev/docs/en/next/babel-code-frame",
|
||||
"bugs": "https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "packages/babel-code-frame"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.23.4",
|
||||
"chalk": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"import-meta-resolve": "^4.0.0",
|
||||
"strip-ansi": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"type": "commonjs"
|
||||
}
|
22
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/LICENSE
generated
vendored
22
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/README.md
generated
vendored
19
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/README.md
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
# @babel/helper-validator-identifier
|
||||
|
||||
> Validate identifier/keywords name
|
||||
|
||||
See our website [@babel/helper-validator-identifier](https://babeljs.io/docs/babel-helper-validator-identifier) for more information.
|
||||
|
||||
## Install
|
||||
|
||||
Using npm:
|
||||
|
||||
```sh
|
||||
npm install --save @babel/helper-validator-identifier
|
||||
```
|
||||
|
||||
or using yarn:
|
||||
|
||||
```sh
|
||||
yarn add @babel/helper-validator-identifier
|
||||
```
|
70
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/identifier.js
generated
vendored
70
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/identifier.js
generated
vendored
|
@ -1,70 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.isIdentifierChar = isIdentifierChar;
|
||||
exports.isIdentifierName = isIdentifierName;
|
||||
exports.isIdentifierStart = isIdentifierStart;
|
||||
let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
|
||||
let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65";
|
||||
const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
|
||||
const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
|
||||
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
|
||||
const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191];
|
||||
const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
|
||||
function isInAstralSet(code, set) {
|
||||
let pos = 0x10000;
|
||||
for (let i = 0, length = set.length; i < length; i += 2) {
|
||||
pos += set[i];
|
||||
if (pos > code) return false;
|
||||
pos += set[i + 1];
|
||||
if (pos >= code) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isIdentifierStart(code) {
|
||||
if (code < 65) return code === 36;
|
||||
if (code <= 90) return true;
|
||||
if (code < 97) return code === 95;
|
||||
if (code <= 122) return true;
|
||||
if (code <= 0xffff) {
|
||||
return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
|
||||
}
|
||||
return isInAstralSet(code, astralIdentifierStartCodes);
|
||||
}
|
||||
function isIdentifierChar(code) {
|
||||
if (code < 48) return code === 36;
|
||||
if (code < 58) return true;
|
||||
if (code < 65) return false;
|
||||
if (code <= 90) return true;
|
||||
if (code < 97) return code === 95;
|
||||
if (code <= 122) return true;
|
||||
if (code <= 0xffff) {
|
||||
return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
|
||||
}
|
||||
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
|
||||
}
|
||||
function isIdentifierName(name) {
|
||||
let isFirst = true;
|
||||
for (let i = 0; i < name.length; i++) {
|
||||
let cp = name.charCodeAt(i);
|
||||
if ((cp & 0xfc00) === 0xd800 && i + 1 < name.length) {
|
||||
const trail = name.charCodeAt(++i);
|
||||
if ((trail & 0xfc00) === 0xdc00) {
|
||||
cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff);
|
||||
}
|
||||
}
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
if (!isIdentifierStart(cp)) {
|
||||
return false;
|
||||
}
|
||||
} else if (!isIdentifierChar(cp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !isFirst;
|
||||
}
|
||||
|
||||
//# sourceMappingURL=identifier.js.map
|
File diff suppressed because one or more lines are too long
57
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/index.js
generated
vendored
57
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/index.js
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "isIdentifierChar", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _identifier.isIdentifierChar;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isIdentifierName", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _identifier.isIdentifierName;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isIdentifierStart", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _identifier.isIdentifierStart;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isKeyword", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _keyword.isKeyword;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isReservedWord", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _keyword.isReservedWord;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isStrictBindOnlyReservedWord", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _keyword.isStrictBindOnlyReservedWord;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isStrictBindReservedWord", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _keyword.isStrictBindReservedWord;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, "isStrictReservedWord", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _keyword.isStrictReservedWord;
|
||||
}
|
||||
});
|
||||
var _identifier = require("./identifier.js");
|
||||
var _keyword = require("./keyword.js");
|
||||
|
||||
//# sourceMappingURL=index.js.map
|
1
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/index.js.map
generated
vendored
1
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/index.js.map
generated
vendored
|
@ -1 +0,0 @@
|
|||
{"version":3,"names":["_identifier","require","_keyword"],"sources":["../src/index.ts"],"sourcesContent":["export {\n isIdentifierName,\n isIdentifierChar,\n isIdentifierStart,\n} from \"./identifier.ts\";\nexport {\n isReservedWord,\n isStrictBindOnlyReservedWord,\n isStrictBindReservedWord,\n isStrictReservedWord,\n isKeyword,\n} from \"./keyword.ts\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAKA,IAAAC,QAAA,GAAAD,OAAA"}
|
35
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/keyword.js
generated
vendored
35
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/keyword.js
generated
vendored
|
@ -1,35 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.isKeyword = isKeyword;
|
||||
exports.isReservedWord = isReservedWord;
|
||||
exports.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord;
|
||||
exports.isStrictBindReservedWord = isStrictBindReservedWord;
|
||||
exports.isStrictReservedWord = isStrictReservedWord;
|
||||
const reservedWords = {
|
||||
keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"],
|
||||
strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"],
|
||||
strictBind: ["eval", "arguments"]
|
||||
};
|
||||
const keywords = new Set(reservedWords.keyword);
|
||||
const reservedWordsStrictSet = new Set(reservedWords.strict);
|
||||
const reservedWordsStrictBindSet = new Set(reservedWords.strictBind);
|
||||
function isReservedWord(word, inModule) {
|
||||
return inModule && word === "await" || word === "enum";
|
||||
}
|
||||
function isStrictReservedWord(word, inModule) {
|
||||
return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
|
||||
}
|
||||
function isStrictBindOnlyReservedWord(word) {
|
||||
return reservedWordsStrictBindSet.has(word);
|
||||
}
|
||||
function isStrictBindReservedWord(word, inModule) {
|
||||
return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word);
|
||||
}
|
||||
function isKeyword(word) {
|
||||
return keywords.has(word);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=keyword.js.map
|
1
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/keyword.js.map
generated
vendored
1
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/lib/keyword.js.map
generated
vendored
|
@ -1 +0,0 @@
|
|||
{"version":3,"names":["reservedWords","keyword","strict","strictBind","keywords","Set","reservedWordsStrictSet","reservedWordsStrictBindSet","isReservedWord","word","inModule","isStrictReservedWord","has","isStrictBindOnlyReservedWord","isStrictBindReservedWord","isKeyword"],"sources":["../src/keyword.ts"],"sourcesContent":["const reservedWords = {\n keyword: [\n \"break\",\n \"case\",\n \"catch\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"do\",\n \"else\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"return\",\n \"switch\",\n \"throw\",\n \"try\",\n \"var\",\n \"const\",\n \"while\",\n \"with\",\n \"new\",\n \"this\",\n \"super\",\n \"class\",\n \"extends\",\n \"export\",\n \"import\",\n \"null\",\n \"true\",\n \"false\",\n \"in\",\n \"instanceof\",\n \"typeof\",\n \"void\",\n \"delete\",\n ],\n strict: [\n \"implements\",\n \"interface\",\n \"let\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"static\",\n \"yield\",\n ],\n strictBind: [\"eval\", \"arguments\"],\n};\nconst keywords = new Set(reservedWords.keyword);\nconst reservedWordsStrictSet = new Set(reservedWords.strict);\nconst reservedWordsStrictBindSet = new Set(reservedWords.strictBind);\n\n/**\n * Checks if word is a reserved word in non-strict mode\n */\nexport function isReservedWord(word: string, inModule: boolean): boolean {\n return (inModule && word === \"await\") || word === \"enum\";\n}\n\n/**\n * Checks if word is a reserved word in non-binding strict mode\n *\n * Includes non-strict reserved words\n */\nexport function isStrictReservedWord(word: string, inModule: boolean): boolean {\n return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);\n}\n\n/**\n * Checks if word is a reserved word in binding strict mode, but it is allowed as\n * a normal identifier.\n */\nexport function isStrictBindOnlyReservedWord(word: string): boolean {\n return reservedWordsStrictBindSet.has(word);\n}\n\n/**\n * Checks if word is a reserved word in binding strict mode\n *\n * Includes non-strict reserved words and non-binding strict reserved words\n */\nexport function isStrictBindReservedWord(\n word: string,\n inModule: boolean,\n): boolean {\n return (\n isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word)\n );\n}\n\nexport function isKeyword(word: string): boolean {\n return keywords.has(word);\n}\n"],"mappings":";;;;;;;;;;AAAA,MAAMA,aAAa,GAAG;EACpBC,OAAO,EAAE,CACP,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,UAAU,EACV,SAAS,EACT,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,QAAQ,CACT;EACDC,MAAM,EAAE,CACN,YAAY,EACZ,WAAW,EACX,KAAK,EACL,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,CACR;EACDC,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW;AAClC,CAAC;AACD,MAAMC,QAAQ,GAAG,IAAIC,GAAG,CAACL,aAAa,CAACC,OAAO,CAAC;AAC/C,MAAMK,sBAAsB,GAAG,IAAID,GAAG,CAACL,aAAa,CAACE,MAAM,CAAC;AAC5D,MAAMK,0BAA0B,GAAG,IAAIF,GAAG,CAACL,aAAa,CAACG,UAAU,CAAC;AAK7D,SAASK,cAAcA,CAACC,IAAY,EAAEC,QAAiB,EAAW;EACvE,OAAQA,QAAQ,IAAID,IAAI,KAAK,OAAO,IAAKA,IAAI,KAAK,MAAM;AAC1D;AAOO,SAASE,oBAAoBA,CAACF,IAAY,EAAEC,QAAiB,EAAW;EAC7E,OAAOF,cAAc,CAACC,IAAI,EAAEC,QAAQ,CAAC,IAAIJ,sBAAsB,CAACM,GAAG,CAACH,IAAI,CAAC;AAC3E;AAMO,SAASI,4BAA4BA,CAACJ,IAAY,EAAW;EAClE,OAAOF,0BAA0B,CAACK,GAAG,CAACH,IAAI,CAAC;AAC7C;AAOO,SAASK,wBAAwBA,CACtCL,IAAY,EACZC,QAAiB,EACR;EACT,OACEC,oBAAoB,CAACF,IAAI,EAAEC,QAAQ,CAAC,IAAIG,4BAA4B,CAACJ,IAAI,CAAC;AAE9E;AAEO,SAASM,SAASA,CAACN,IAAY,EAAW;EAC/C,OAAOL,QAAQ,CAACQ,GAAG,CAACH,IAAI,CAAC;AAC3B"}
|
28
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/package.json
generated
vendored
28
legacies/src/ch1/node_modules/@babel/helper-validator-identifier/package.json
generated
vendored
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name": "@babel/helper-validator-identifier",
|
||||
"version": "7.22.20",
|
||||
"description": "Validate identifier/keywords name",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "packages/babel-helper-validator-identifier"
|
||||
},
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"exports": {
|
||||
".": "./lib/index.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@unicode/unicode-15.1.0": "^1.5.2",
|
||||
"charcodes": "^0.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"author": "The Babel Team (https://babel.dev/team)",
|
||||
"type": "commonjs"
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// Always use the latest available version of Unicode!
|
||||
// https://tc39.github.io/ecma262/#sec-conformance
|
||||
const version = "15.1.0";
|
||||
|
||||
const start = require(
|
||||
"@unicode/unicode-" + version + "/Binary_Property/ID_Start/code-points.js"
|
||||
).filter(function (ch) {
|
||||
return ch > 0x7f;
|
||||
});
|
||||
let last = -1;
|
||||
const cont = require(
|
||||
"@unicode/unicode-" + version + "/Binary_Property/ID_Continue/code-points.js"
|
||||
).filter(function (ch) {
|
||||
return ch > 0x7f && search(start, ch, last + 1) == -1;
|
||||
});
|
||||
|
||||
function search(arr, ch, starting) {
|
||||
for (let i = starting; arr[i] <= ch && i < arr.length; last = i++) {
|
||||
if (arr[i] === ch) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function pad(str, width) {
|
||||
while (str.length < width) str = "0" + str;
|
||||
return str;
|
||||
}
|
||||
|
||||
function esc(code) {
|
||||
const hex = code.toString(16);
|
||||
if (hex.length <= 2) return "\\x" + pad(hex, 2);
|
||||
else return "\\u" + pad(hex, 4);
|
||||
}
|
||||
|
||||
function generate(chars) {
|
||||
const astral = [];
|
||||
let re = "";
|
||||
for (let i = 0, at = 0x10000; i < chars.length; i++) {
|
||||
const from = chars[i];
|
||||
let to = from;
|
||||
while (i < chars.length - 1 && chars[i + 1] == to + 1) {
|
||||
i++;
|
||||
to++;
|
||||
}
|
||||
if (to <= 0xffff) {
|
||||
if (from == to) re += esc(from);
|
||||
else if (from + 1 == to) re += esc(from) + esc(to);
|
||||
else re += esc(from) + "-" + esc(to);
|
||||
} else {
|
||||
astral.push(from - at, to - from);
|
||||
at = to;
|
||||
}
|
||||
}
|
||||
return { nonASCII: re, astral: astral };
|
||||
}
|
||||
|
||||
const startData = generate(start);
|
||||
const contData = generate(cont);
|
||||
|
||||
console.log("/* prettier-ignore */");
|
||||
console.log('let nonASCIIidentifierStartChars = "' + startData.nonASCII + '";');
|
||||
console.log("/* prettier-ignore */");
|
||||
console.log('let nonASCIIidentifierChars = "' + contData.nonASCII + '";');
|
||||
console.log("/* prettier-ignore */");
|
||||
console.log(
|
||||
"const astralIdentifierStartCodes = " + JSON.stringify(startData.astral) + ";"
|
||||
);
|
||||
console.log("/* prettier-ignore */");
|
||||
console.log(
|
||||
"const astralIdentifierCodes = " + JSON.stringify(contData.astral) + ";"
|
||||
);
|
22
legacies/src/ch1/node_modules/@babel/highlight/LICENSE
generated
vendored
22
legacies/src/ch1/node_modules/@babel/highlight/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
legacies/src/ch1/node_modules/@babel/highlight/README.md
generated
vendored
19
legacies/src/ch1/node_modules/@babel/highlight/README.md
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
# @babel/highlight
|
||||
|
||||
> Syntax highlight JavaScript strings for output in terminals.
|
||||
|
||||
See our website [@babel/highlight](https://babeljs.io/docs/babel-highlight) for more information.
|
||||
|
||||
## Install
|
||||
|
||||
Using npm:
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/highlight
|
||||
```
|
||||
|
||||
or using yarn:
|
||||
|
||||
```sh
|
||||
yarn add @babel/highlight --dev
|
||||
```
|
105
legacies/src/ch1/node_modules/@babel/highlight/lib/index.js
generated
vendored
105
legacies/src/ch1/node_modules/@babel/highlight/lib/index.js
generated
vendored
|
@ -1,105 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = highlight;
|
||||
exports.shouldHighlight = shouldHighlight;
|
||||
var _jsTokens = require("js-tokens");
|
||||
var _helperValidatorIdentifier = require("@babel/helper-validator-identifier");
|
||||
var _chalk = _interopRequireWildcard(require("chalk"), true);
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const sometimesKeywords = new Set(["as", "async", "from", "get", "of", "set"]);
|
||||
function getDefs(chalk) {
|
||||
return {
|
||||
keyword: chalk.cyan,
|
||||
capitalized: chalk.yellow,
|
||||
jsxIdentifier: chalk.yellow,
|
||||
punctuator: chalk.yellow,
|
||||
number: chalk.magenta,
|
||||
string: chalk.green,
|
||||
regex: chalk.magenta,
|
||||
comment: chalk.grey,
|
||||
invalid: chalk.white.bgRed.bold
|
||||
};
|
||||
}
|
||||
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
||||
const BRACKET = /^[()[\]{}]$/;
|
||||
let tokenize;
|
||||
{
|
||||
const JSX_TAG = /^[a-z][\w-]*$/i;
|
||||
const getTokenType = function (token, offset, text) {
|
||||
if (token.type === "name") {
|
||||
if ((0, _helperValidatorIdentifier.isKeyword)(token.value) || (0, _helperValidatorIdentifier.isStrictReservedWord)(token.value, true) || sometimesKeywords.has(token.value)) {
|
||||
return "keyword";
|
||||
}
|
||||
if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.slice(offset - 2, offset) == "</")) {
|
||||
return "jsxIdentifier";
|
||||
}
|
||||
if (token.value[0] !== token.value[0].toLowerCase()) {
|
||||
return "capitalized";
|
||||
}
|
||||
}
|
||||
if (token.type === "punctuator" && BRACKET.test(token.value)) {
|
||||
return "bracket";
|
||||
}
|
||||
if (token.type === "invalid" && (token.value === "@" || token.value === "#")) {
|
||||
return "punctuator";
|
||||
}
|
||||
return token.type;
|
||||
};
|
||||
tokenize = function* (text) {
|
||||
let match;
|
||||
while (match = _jsTokens.default.exec(text)) {
|
||||
const token = _jsTokens.matchToToken(match);
|
||||
yield {
|
||||
type: getTokenType(token, match.index, text),
|
||||
value: token.value
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
function highlightTokens(defs, text) {
|
||||
let highlighted = "";
|
||||
for (const {
|
||||
type,
|
||||
value
|
||||
} of tokenize(text)) {
|
||||
const colorize = defs[type];
|
||||
if (colorize) {
|
||||
highlighted += value.split(NEWLINE).map(str => colorize(str)).join("\n");
|
||||
} else {
|
||||
highlighted += value;
|
||||
}
|
||||
}
|
||||
return highlighted;
|
||||
}
|
||||
function shouldHighlight(options) {
|
||||
return _chalk.default.level > 0 || options.forceColor;
|
||||
}
|
||||
let chalkWithForcedColor = undefined;
|
||||
function getChalk(forceColor) {
|
||||
if (forceColor) {
|
||||
var _chalkWithForcedColor;
|
||||
(_chalkWithForcedColor = chalkWithForcedColor) != null ? _chalkWithForcedColor : chalkWithForcedColor = new _chalk.default.constructor({
|
||||
enabled: true,
|
||||
level: 1
|
||||
});
|
||||
return chalkWithForcedColor;
|
||||
}
|
||||
return _chalk.default;
|
||||
}
|
||||
{
|
||||
exports.getChalk = options => getChalk(options.forceColor);
|
||||
}
|
||||
function highlight(code, options = {}) {
|
||||
if (code !== "" && shouldHighlight(options)) {
|
||||
const defs = getDefs(getChalk(options.forceColor));
|
||||
return highlightTokens(defs, code);
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceMappingURL=index.js.map
|
1
legacies/src/ch1/node_modules/@babel/highlight/lib/index.js.map
generated
vendored
1
legacies/src/ch1/node_modules/@babel/highlight/lib/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
29
legacies/src/ch1/node_modules/@babel/highlight/package.json
generated
vendored
29
legacies/src/ch1/node_modules/@babel/highlight/package.json
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"name": "@babel/highlight",
|
||||
"version": "7.23.4",
|
||||
"description": "Syntax highlight JavaScript strings for output in terminals.",
|
||||
"author": "The Babel Team (https://babel.dev/team)",
|
||||
"homepage": "https://babel.dev/docs/en/next/babel-highlight",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "packages/babel-highlight"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"strip-ansi": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"type": "commonjs"
|
||||
}
|
21
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/LICENSE
generated
vendored
21
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Toru Nagashima
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
37
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/README.md
generated
vendored
37
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/README.md
generated
vendored
|
@ -1,37 +0,0 @@
|
|||
# @eslint-community/eslint-utils
|
||||
|
||||
[![npm version](https://img.shields.io/npm/v/@eslint-community/eslint-utils.svg)](https://www.npmjs.com/package/@eslint-community/eslint-utils)
|
||||
[![Downloads/month](https://img.shields.io/npm/dm/@eslint-community/eslint-utils.svg)](http://www.npmtrends.com/@eslint-community/eslint-utils)
|
||||
[![Build Status](https://github.com/eslint-community/eslint-utils/workflows/CI/badge.svg)](https://github.com/eslint-community/eslint-utils/actions)
|
||||
[![Coverage Status](https://codecov.io/gh/eslint-community/eslint-utils/branch/main/graph/badge.svg)](https://codecov.io/gh/eslint-community/eslint-utils)
|
||||
|
||||
## 🏁 Goal
|
||||
|
||||
This package provides utility functions and classes for make ESLint custom rules.
|
||||
|
||||
For examples:
|
||||
|
||||
- [`getStaticValue`](https://eslint-community.github.io/eslint-utils/api/ast-utils.html#getstaticvalue) evaluates static value on AST.
|
||||
- [`ReferenceTracker`](https://eslint-community.github.io/eslint-utils/api/scope-utils.html#referencetracker-class) checks the members of modules/globals as handling assignments and destructuring.
|
||||
|
||||
## 📖 Usage
|
||||
|
||||
See [documentation](https://eslint-community.github.io/eslint-utils).
|
||||
|
||||
## 📰 Changelog
|
||||
|
||||
See [releases](https://github.com/eslint-community/eslint-utils/releases).
|
||||
|
||||
## ❤️ Contributing
|
||||
|
||||
Welcome contributing!
|
||||
|
||||
Please use GitHub's Issues/PRs.
|
||||
|
||||
### Development Tools
|
||||
|
||||
- `npm test` runs tests and measures coverage.
|
||||
- `npm run clean` removes the coverage result of `npm test` command.
|
||||
- `npm run coverage` shows the coverage result of the last `npm test` command.
|
||||
- `npm run lint` runs ESLint.
|
||||
- `npm run watch` runs tests on each file change.
|
2068
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.js
generated
vendored
2068
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.js
generated
vendored
File diff suppressed because it is too large
Load diff
1
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.js.map
generated
vendored
1
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2027
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.mjs
generated
vendored
2027
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.mjs
generated
vendored
File diff suppressed because it is too large
Load diff
1
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.mjs.map
generated
vendored
1
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/index.mjs.map
generated
vendored
File diff suppressed because one or more lines are too long
73
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/package.json
generated
vendored
73
legacies/src/ch1/node_modules/@eslint-community/eslint-utils/package.json
generated
vendored
|
@ -1,73 +0,0 @@
|
|||
{
|
||||
"name": "@eslint-community/eslint-utils",
|
||||
"version": "4.4.0",
|
||||
"description": "Utilities for ESLint plugins.",
|
||||
"keywords": [
|
||||
"eslint"
|
||||
],
|
||||
"homepage": "https://github.com/eslint-community/eslint-utils#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/eslint-community/eslint-utils/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint-community/eslint-utils"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Toru Nagashima",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./index.mjs",
|
||||
"require": "./index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "index",
|
||||
"module": "index.mjs",
|
||||
"files": [
|
||||
"index.*"
|
||||
],
|
||||
"scripts": {
|
||||
"prebuild": "npm run -s clean",
|
||||
"build": "rollup -c",
|
||||
"clean": "rimraf .nyc_output coverage index.*",
|
||||
"coverage": "opener ./coverage/lcov-report/index.html",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:watch": "vitepress dev docs",
|
||||
"format": "npm run -s format:prettier -- --write",
|
||||
"format:prettier": "prettier .",
|
||||
"format:check": "npm run -s format:prettier -- --check",
|
||||
"lint": "eslint .",
|
||||
"test": "c8 mocha --reporter dot \"test/*.mjs\"",
|
||||
"preversion": "npm test && npm run -s build",
|
||||
"postversion": "git push && git push --tags",
|
||||
"prewatch": "npm run -s clean",
|
||||
"watch": "warun \"{src,test}/**/*.mjs\" -- npm run -s test:mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-mysticatea": "^15.2.0",
|
||||
"c8": "^7.12.0",
|
||||
"dot-prop": "^6.0.1",
|
||||
"eslint": "^8.28.0",
|
||||
"mocha": "^9.2.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"opener": "^1.5.2",
|
||||
"prettier": "2.8.4",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"semver": "^7.3.8",
|
||||
"vitepress": "^1.0.0-alpha.40",
|
||||
"warun": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
}
|
21
legacies/src/ch1/node_modules/@eslint-community/regexpp/LICENSE
generated
vendored
21
legacies/src/ch1/node_modules/@eslint-community/regexpp/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Toru Nagashima
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
177
legacies/src/ch1/node_modules/@eslint-community/regexpp/README.md
generated
vendored
177
legacies/src/ch1/node_modules/@eslint-community/regexpp/README.md
generated
vendored
|
@ -1,177 +0,0 @@
|
|||
# @eslint-community/regexpp
|
||||
|
||||
[![npm version](https://img.shields.io/npm/v/@eslint-community/regexpp.svg)](https://www.npmjs.com/package/@eslint-community/regexpp)
|
||||
[![Downloads/month](https://img.shields.io/npm/dm/@eslint-community/regexpp.svg)](http://www.npmtrends.com/@eslint-community/regexpp)
|
||||
[![Build Status](https://github.com/eslint-community/regexpp/workflows/CI/badge.svg)](https://github.com/eslint-community/regexpp/actions)
|
||||
[![codecov](https://codecov.io/gh/eslint-community/regexpp/branch/main/graph/badge.svg)](https://codecov.io/gh/eslint-community/regexpp)
|
||||
|
||||
A regular expression parser for ECMAScript.
|
||||
|
||||
## 💿 Installation
|
||||
|
||||
```bash
|
||||
$ npm install @eslint-community/regexpp
|
||||
```
|
||||
|
||||
- require Node@^12.0.0 || ^14.0.0 || >=16.0.0.
|
||||
|
||||
## 📖 Usage
|
||||
|
||||
```ts
|
||||
import {
|
||||
AST,
|
||||
RegExpParser,
|
||||
RegExpValidator,
|
||||
RegExpVisitor,
|
||||
parseRegExpLiteral,
|
||||
validateRegExpLiteral,
|
||||
visitRegExpAST
|
||||
} from "@eslint-community/regexpp"
|
||||
```
|
||||
|
||||
### parseRegExpLiteral(source, options?)
|
||||
|
||||
Parse a given regular expression literal then make AST object.
|
||||
|
||||
This is equivalent to `new RegExpParser(options).parseLiteral(source)`.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string | RegExp`) The source code to parse.
|
||||
- `options?` ([`RegExpParser.Options`]) The options to parse.
|
||||
- **Return:**
|
||||
- The AST of the regular expression.
|
||||
|
||||
### validateRegExpLiteral(source, options?)
|
||||
|
||||
Validate a given regular expression literal.
|
||||
|
||||
This is equivalent to `new RegExpValidator(options).validateLiteral(source)`.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `options?` ([`RegExpValidator.Options`]) The options to validate.
|
||||
|
||||
### visitRegExpAST(ast, handlers)
|
||||
|
||||
Visit each node of a given AST.
|
||||
|
||||
This is equivalent to `new RegExpVisitor(handlers).visit(ast)`.
|
||||
|
||||
- **Parameters:**
|
||||
- `ast` ([`AST.Node`]) The AST to visit.
|
||||
- `handlers` ([`RegExpVisitor.Handlers`]) The callbacks.
|
||||
|
||||
### RegExpParser
|
||||
|
||||
#### new RegExpParser(options?)
|
||||
|
||||
- **Parameters:**
|
||||
- `options?` ([`RegExpParser.Options`]) The options to parse.
|
||||
|
||||
#### parser.parseLiteral(source, start?, end?)
|
||||
|
||||
Parse a regular expression literal.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to parse. E.g. `"/abc/g"`.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- **Return:**
|
||||
- The AST of the regular expression.
|
||||
|
||||
#### parser.parsePattern(source, start?, end?, flags?)
|
||||
|
||||
Parse a regular expression pattern.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to parse. E.g. `"abc"`.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- `flags?` (`{ unicode?: boolean, unicodeSets?: boolean }`) The flags to enable Unicode mode, and Unicode Set mode.
|
||||
- **Return:**
|
||||
- The AST of the regular expression pattern.
|
||||
|
||||
#### parser.parseFlags(source, start?, end?)
|
||||
|
||||
Parse a regular expression flags.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to parse. E.g. `"gim"`.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- **Return:**
|
||||
- The AST of the regular expression flags.
|
||||
|
||||
### RegExpValidator
|
||||
|
||||
#### new RegExpValidator(options)
|
||||
|
||||
- **Parameters:**
|
||||
- `options` ([`RegExpValidator.Options`]) The options to validate.
|
||||
|
||||
#### validator.validateLiteral(source, start, end)
|
||||
|
||||
Validate a regular expression literal.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
|
||||
#### validator.validatePattern(source, start, end, flags)
|
||||
|
||||
Validate a regular expression pattern.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- `flags?` (`{ unicode?: boolean, unicodeSets?: boolean }`) The flags to enable Unicode mode, and Unicode Set mode.
|
||||
|
||||
#### validator.validateFlags(source, start, end)
|
||||
|
||||
Validate a regular expression flags.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
|
||||
### RegExpVisitor
|
||||
|
||||
#### new RegExpVisitor(handlers)
|
||||
|
||||
- **Parameters:**
|
||||
- `handlers` ([`RegExpVisitor.Handlers`]) The callbacks.
|
||||
|
||||
#### visitor.visit(ast)
|
||||
|
||||
Validate a regular expression literal.
|
||||
|
||||
- **Parameters:**
|
||||
- `ast` ([`AST.Node`]) The AST to visit.
|
||||
|
||||
## 📰 Changelog
|
||||
|
||||
- [GitHub Releases](https://github.com/eslint-community/regexpp/releases)
|
||||
|
||||
## 🍻 Contributing
|
||||
|
||||
Welcome contributing!
|
||||
|
||||
Please use GitHub's Issues/PRs.
|
||||
|
||||
### Development Tools
|
||||
|
||||
- `npm test` runs tests and measures coverage.
|
||||
- `npm run build` compiles TypeScript source code to `index.js`, `index.js.map`, and `index.d.ts`.
|
||||
- `npm run clean` removes the temporary files which are created by `npm test` and `npm run build`.
|
||||
- `npm run lint` runs ESLint.
|
||||
- `npm run update:test` updates test fixtures.
|
||||
- `npm run update:ids` updates `src/unicode/ids.ts`.
|
||||
- `npm run watch` runs tests with `--watch` option.
|
||||
|
||||
[`AST.Node`]: src/ast.ts#L4
|
||||
[`RegExpParser.Options`]: src/parser.ts#L743
|
||||
[`RegExpValidator.Options`]: src/validator.ts#L220
|
||||
[`RegExpVisitor.Handlers`]: src/visitor.ts#L291
|
1065
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.d.ts
generated
vendored
1065
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.d.ts
generated
vendored
File diff suppressed because it is too large
Load diff
2747
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.js
generated
vendored
2747
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.js
generated
vendored
File diff suppressed because it is too large
Load diff
1
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.js.map
generated
vendored
1
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2737
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.mjs
generated
vendored
2737
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.mjs
generated
vendored
File diff suppressed because it is too large
Load diff
1
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.mjs.map
generated
vendored
1
legacies/src/ch1/node_modules/@eslint-community/regexpp/index.mjs.map
generated
vendored
File diff suppressed because one or more lines are too long
93
legacies/src/ch1/node_modules/@eslint-community/regexpp/package.json
generated
vendored
93
legacies/src/ch1/node_modules/@eslint-community/regexpp/package.json
generated
vendored
|
@ -1,93 +0,0 @@
|
|||
{
|
||||
"name": "@eslint-community/regexpp",
|
||||
"version": "4.10.0",
|
||||
"description": "Regular expression parser for ECMAScript.",
|
||||
"keywords": [
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"parser",
|
||||
"validator",
|
||||
"ast",
|
||||
"abstract",
|
||||
"syntax",
|
||||
"tree",
|
||||
"ecmascript",
|
||||
"es2015",
|
||||
"es2016",
|
||||
"es2017",
|
||||
"es2018",
|
||||
"es2019",
|
||||
"es2020",
|
||||
"es2021",
|
||||
"annexB"
|
||||
],
|
||||
"homepage": "https://github.com/eslint-community/regexpp#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/eslint-community/regexpp/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint-community/regexpp"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Toru Nagashima",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.mjs",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "index",
|
||||
"files": [
|
||||
"index.*"
|
||||
],
|
||||
"scripts": {
|
||||
"prebuild": "npm run -s clean",
|
||||
"build": "run-s build:*",
|
||||
"build:tsc": "tsc --module es2015",
|
||||
"build:rollup": "rollup -c",
|
||||
"build:dts": "npm run -s build:tsc -- --removeComments false && dts-bundle --name @eslint-community/regexpp --main .temp/index.d.ts --out ../index.d.ts && prettier --write index.d.ts",
|
||||
"clean": "rimraf .temp index.*",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"test": "nyc _mocha \"test/*.ts\" --reporter dot --timeout 10000",
|
||||
"debug": "mocha --require ts-node/register/transpile-only \"test/*.ts\" --reporter dot --timeout 10000",
|
||||
"update:test": "ts-node scripts/update-fixtures.ts",
|
||||
"update:unicode": "run-s update:unicode:*",
|
||||
"update:unicode:ids": "ts-node scripts/update-unicode-ids.ts",
|
||||
"update:unicode:props": "ts-node scripts/update-unicode-properties.ts",
|
||||
"update:test262:extract": "ts-node -T scripts/extract-test262.ts",
|
||||
"preversion": "npm test && npm run -s build",
|
||||
"postversion": "git push && git push --tags",
|
||||
"prewatch": "npm run -s clean",
|
||||
"watch": "_mocha \"test/*.ts\" --require ts-node/register --reporter dot --timeout 10000 --watch-extensions ts --watch --growl"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-mysticatea": "^15.5.1",
|
||||
"@rollup/plugin-node-resolve": "^14.1.0",
|
||||
"@types/eslint": "^8.44.3",
|
||||
"@types/jsdom": "^16.2.15",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^12.20.55",
|
||||
"dts-bundle": "^0.7.3",
|
||||
"eslint": "^8.50.0",
|
||||
"js-tokens": "^8.0.2",
|
||||
"jsdom": "^19.0.0",
|
||||
"mocha": "^9.2.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nyc": "^14.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"test262": "git+https://github.com/tc39/test262.git",
|
||||
"test262-stream": "^1.4.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "~5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
}
|
21
legacies/src/ch1/node_modules/@nodelib/fs.scandir/LICENSE
generated
vendored
21
legacies/src/ch1/node_modules/@nodelib/fs.scandir/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Denis Malinochkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
171
legacies/src/ch1/node_modules/@nodelib/fs.scandir/README.md
generated
vendored
171
legacies/src/ch1/node_modules/@nodelib/fs.scandir/README.md
generated
vendored
|
@ -1,171 +0,0 @@
|
|||
# @nodelib/fs.scandir
|
||||
|
||||
> List files and directories inside the specified directory.
|
||||
|
||||
## :bulb: Highlights
|
||||
|
||||
The package is aimed at obtaining information about entries in the directory.
|
||||
|
||||
* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional).
|
||||
* :gear: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type. See [`old` and `modern` mode](#old-and-modern-mode).
|
||||
* :link: Can safely work with broken symbolic links.
|
||||
|
||||
## Install
|
||||
|
||||
```console
|
||||
npm install @nodelib/fs.scandir
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import * as fsScandir from '@nodelib/fs.scandir';
|
||||
|
||||
fsScandir.scandir('path', (error, stats) => { /* … */ });
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### .scandir(path, [optionsOrSettings], callback)
|
||||
|
||||
Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path with standard callback-style.
|
||||
|
||||
```ts
|
||||
fsScandir.scandir('path', (error, entries) => { /* … */ });
|
||||
fsScandir.scandir('path', {}, (error, entries) => { /* … */ });
|
||||
fsScandir.scandir('path', new fsScandir.Settings(), (error, entries) => { /* … */ });
|
||||
```
|
||||
|
||||
### .scandirSync(path, [optionsOrSettings])
|
||||
|
||||
Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path.
|
||||
|
||||
```ts
|
||||
const entries = fsScandir.scandirSync('path');
|
||||
const entries = fsScandir.scandirSync('path', {});
|
||||
const entries = fsScandir.scandirSync(('path', new fsScandir.Settings());
|
||||
```
|
||||
|
||||
#### path
|
||||
|
||||
* Required: `true`
|
||||
* Type: `string | Buffer | URL`
|
||||
|
||||
A path to a file. If a URL is provided, it must use the `file:` protocol.
|
||||
|
||||
#### optionsOrSettings
|
||||
|
||||
* Required: `false`
|
||||
* Type: `Options | Settings`
|
||||
* Default: An instance of `Settings` class
|
||||
|
||||
An [`Options`](#options) object or an instance of [`Settings`](#settingsoptions) class.
|
||||
|
||||
> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.
|
||||
|
||||
### Settings([options])
|
||||
|
||||
A class of full settings of the package.
|
||||
|
||||
```ts
|
||||
const settings = new fsScandir.Settings({ followSymbolicLinks: false });
|
||||
|
||||
const entries = fsScandir.scandirSync('path', settings);
|
||||
```
|
||||
|
||||
## Entry
|
||||
|
||||
* `name` — The name of the entry (`unknown.txt`).
|
||||
* `path` — The path of the entry relative to call directory (`root/unknown.txt`).
|
||||
* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class. On Node.js below 10.10 will be emulated by [`DirentFromStats`](./src/utils/fs.ts) class.
|
||||
* `stats` (optional) — An instance of `fs.Stats` class.
|
||||
|
||||
For example, the `scandir` call for `tools` directory with one directory inside:
|
||||
|
||||
```ts
|
||||
{
|
||||
dirent: Dirent { name: 'typedoc', /* … */ },
|
||||
name: 'typedoc',
|
||||
path: 'tools/typedoc'
|
||||
}
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### stats
|
||||
|
||||
* Type: `boolean`
|
||||
* Default: `false`
|
||||
|
||||
Adds an instance of `fs.Stats` class to the [`Entry`](#entry).
|
||||
|
||||
> :book: Always use `fs.readdir` without the `withFileTypes` option. ??TODO??
|
||||
|
||||
### followSymbolicLinks
|
||||
|
||||
* Type: `boolean`
|
||||
* Default: `false`
|
||||
|
||||
Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`.
|
||||
|
||||
### `throwErrorOnBrokenSymbolicLink`
|
||||
|
||||
* Type: `boolean`
|
||||
* Default: `true`
|
||||
|
||||
Throw an error when symbolic link is broken if `true` or safely use `lstat` call if `false`.
|
||||
|
||||
### `pathSegmentSeparator`
|
||||
|
||||
* Type: `string`
|
||||
* Default: `path.sep`
|
||||
|
||||
By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead.
|
||||
|
||||
### `fs`
|
||||
|
||||
* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
|
||||
* Default: A default FS methods
|
||||
|
||||
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.
|
||||
|
||||
```ts
|
||||
interface FileSystemAdapter {
|
||||
lstat?: typeof fs.lstat;
|
||||
stat?: typeof fs.stat;
|
||||
lstatSync?: typeof fs.lstatSync;
|
||||
statSync?: typeof fs.statSync;
|
||||
readdir?: typeof fs.readdir;
|
||||
readdirSync?: typeof fs.readdirSync;
|
||||
}
|
||||
|
||||
const settings = new fsScandir.Settings({
|
||||
fs: { lstat: fakeLstat }
|
||||
});
|
||||
```
|
||||
|
||||
## `old` and `modern` mode
|
||||
|
||||
This package has two modes that are used depending on the environment and parameters of use.
|
||||
|
||||
### old
|
||||
|
||||
* Node.js below `10.10` or when the `stats` option is enabled
|
||||
|
||||
When working in the old mode, the directory is read first (`fs.readdir`), then the type of entries is determined (`fs.lstat` and/or `fs.stat` for symbolic links).
|
||||
|
||||
### modern
|
||||
|
||||
* Node.js 10.10+ and the `stats` option is disabled
|
||||
|
||||
In the modern mode, reading the directory (`fs.readdir` with the `withFileTypes` option) is combined with obtaining information about its entries. An additional call for symbolic links (`fs.stat`) is still present.
|
||||
|
||||
This mode makes fewer calls to the file system. It's faster.
|
||||
|
||||
## Changelog
|
||||
|
||||
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.
|
||||
|
||||
## License
|
||||
|
||||
This software is released under the terms of the MIT license.
|
20
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts
generated
vendored
20
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts
generated
vendored
|
@ -1,20 +0,0 @@
|
|||
import type * as fsStat from '@nodelib/fs.stat';
|
||||
import type { Dirent, ErrnoException } from '../types';
|
||||
export interface ReaddirAsynchronousMethod {
|
||||
(filepath: string, options: {
|
||||
withFileTypes: true;
|
||||
}, callback: (error: ErrnoException | null, files: Dirent[]) => void): void;
|
||||
(filepath: string, callback: (error: ErrnoException | null, files: string[]) => void): void;
|
||||
}
|
||||
export interface ReaddirSynchronousMethod {
|
||||
(filepath: string, options: {
|
||||
withFileTypes: true;
|
||||
}): Dirent[];
|
||||
(filepath: string): string[];
|
||||
}
|
||||
export declare type FileSystemAdapter = fsStat.FileSystemAdapter & {
|
||||
readdir: ReaddirAsynchronousMethod;
|
||||
readdirSync: ReaddirSynchronousMethod;
|
||||
};
|
||||
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
|
||||
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;
|
19
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/adapters/fs.js
generated
vendored
19
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/adapters/fs.js
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
|
||||
const fs = require("fs");
|
||||
exports.FILE_SYSTEM_ADAPTER = {
|
||||
lstat: fs.lstat,
|
||||
stat: fs.stat,
|
||||
lstatSync: fs.lstatSync,
|
||||
statSync: fs.statSync,
|
||||
readdir: fs.readdir,
|
||||
readdirSync: fs.readdirSync
|
||||
};
|
||||
function createFileSystemAdapter(fsMethods) {
|
||||
if (fsMethods === undefined) {
|
||||
return exports.FILE_SYSTEM_ADAPTER;
|
||||
}
|
||||
return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
|
||||
}
|
||||
exports.createFileSystemAdapter = createFileSystemAdapter;
|
4
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/constants.d.ts
generated
vendored
4
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/constants.d.ts
generated
vendored
|
@ -1,4 +0,0 @@
|
|||
/**
|
||||
* IS `true` for Node.js 10.10 and greater.
|
||||
*/
|
||||
export declare const IS_SUPPORT_READDIR_WITH_FILE_TYPES: boolean;
|
17
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/constants.js
generated
vendored
17
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/constants.js
generated
vendored
|
@ -1,17 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0;
|
||||
const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.');
|
||||
if (NODE_PROCESS_VERSION_PARTS[0] === undefined || NODE_PROCESS_VERSION_PARTS[1] === undefined) {
|
||||
throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);
|
||||
}
|
||||
const MAJOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[0], 10);
|
||||
const MINOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[1], 10);
|
||||
const SUPPORTED_MAJOR_VERSION = 10;
|
||||
const SUPPORTED_MINOR_VERSION = 10;
|
||||
const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION;
|
||||
const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION;
|
||||
/**
|
||||
* IS `true` for Node.js 10.10 and greater.
|
||||
*/
|
||||
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR;
|
12
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/index.d.ts
generated
vendored
12
legacies/src/ch1/node_modules/@nodelib/fs.scandir/out/index.d.ts
generated
vendored
|
@ -1,12 +0,0 @@
|
|||
import type { FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod } from './adapters/fs';
|
||||
import * as async from './providers/async';
|
||||
import Settings, { Options } from './settings';
|
||||
import type { Dirent, Entry } from './types';
|
||||
declare type AsyncCallback = async.AsyncCallback;
|
||||
declare function scandir(path: string, callback: AsyncCallback): void;
|
||||
declare function scandir(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
|
||||
declare namespace scandir {
|
||||
function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Entry[]>;
|
||||
}
|
||||
declare function scandirSync(path: string, optionsOrSettings?: Options | Settings): Entry[];
|
||||
export { scandir, scandirSync, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod, Options };
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue