88// BMP coarse filter: a 64-byte bitmap (1 bit per 128-codepoint block) gates
99// the binary search. Clean blocks return width 1 without touching the table.
1010
11- const UNICODE_BASE = "https://www.unicode.org/Public/16.0.0/ucd" ;
11+ let UNICODE_BASE = "https://www.unicode.org/Public/16.0.0/ucd" ;
1212
1313interface Interval {
1414 start : number ;
@@ -20,9 +20,9 @@ interface TaggedInterval extends Interval {
2020}
2121
2222async function fetchText ( path : string ) : Promise < string > {
23- const url = `${ UNICODE_BASE } /${ path } ` ;
23+ let url = `${ UNICODE_BASE } /${ path } ` ;
2424 console . error ( `Fetching ${ url } …` ) ;
25- const response = await fetch ( url ) ;
25+ let response = await fetch ( url ) ;
2626 if ( ! response . ok ) {
2727 throw new Error ( `HTTP ${ response . status } fetching ${ url } ` ) ;
2828 }
@@ -31,10 +31,10 @@ async function fetchText(path: string): Promise<string> {
3131
3232function parseCodepointRange ( token : string ) : Interval {
3333 if ( token . includes ( ".." ) ) {
34- const [ lo , hi ] = token . split ( ".." ) . map ( ( s ) => parseInt ( s , 16 ) ) ;
34+ let [ lo , hi ] = token . split ( ".." ) . map ( ( s ) => parseInt ( s , 16 ) ) ;
3535 return { start : lo , end : hi } ;
3636 }
37- const cp = parseInt ( token , 16 ) ;
37+ let cp = parseInt ( token , 16 ) ;
3838 return { start : cp , end : cp } ;
3939}
4040
@@ -43,11 +43,11 @@ function parseCodepointRange(token: string): Interval {
4343 * `XXXX..YYYY ; Category # …` and returns intervals matching `category`.
4444 */
4545function parseGeneralCategory ( text : string , category : string ) : Interval [ ] {
46- const intervals : Interval [ ] = [ ] ;
47- for ( const line of text . split ( "\n" ) ) {
48- const content = line . split ( "#" ) [ 0 ] . trim ( ) ;
46+ let intervals : Interval [ ] = [ ] ;
47+ for ( let line of text . split ( "\n" ) ) {
48+ let content = line . split ( "#" ) [ 0 ] . trim ( ) ;
4949 if ( ! content ) continue ;
50- const [ range , cat ] = content . split ( ";" ) . map ( ( s ) => s . trim ( ) ) ;
50+ let [ range , cat ] = content . split ( ";" ) . map ( ( s ) => s . trim ( ) ) ;
5151 if ( cat !== category ) continue ;
5252 intervals . push ( parseCodepointRange ( range ) ) ;
5353 }
@@ -59,11 +59,11 @@ function parseGeneralCategory(text: string, category: string): Interval[] {
5959 * `XXXX ; Property_Name # …` and returns intervals matching `property`.
6060 */
6161function parseDerivedProperty ( text : string , property : string ) : Interval [ ] {
62- const intervals : Interval [ ] = [ ] ;
63- for ( const line of text . split ( "\n" ) ) {
64- const content = line . split ( "#" ) [ 0 ] . trim ( ) ;
62+ let intervals : Interval [ ] = [ ] ;
63+ for ( let line of text . split ( "\n" ) ) {
64+ let content = line . split ( "#" ) [ 0 ] . trim ( ) ;
6565 if ( ! content ) continue ;
66- const [ range , prop ] = content . split ( ";" ) . map ( ( s ) => s . trim ( ) ) ;
66+ let [ range , prop ] = content . split ( ";" ) . map ( ( s ) => s . trim ( ) ) ;
6767 if ( prop !== property ) continue ;
6868 intervals . push ( parseCodepointRange ( range ) ) ;
6969 }
@@ -75,11 +75,11 @@ function parseDerivedProperty(text: string, property: string): Interval[] {
7575 * and returns intervals for Wide (W) and Fullwidth (F) codepoints.
7676 */
7777function parseWideEastAsian ( text : string ) : Interval [ ] {
78- const intervals : Interval [ ] = [ ] ;
79- for ( const line of text . split ( "\n" ) ) {
80- const content = line . split ( "#" ) [ 0 ] . trim ( ) ;
78+ let intervals : Interval [ ] = [ ] ;
79+ for ( let line of text . split ( "\n" ) ) {
80+ let content = line . split ( "#" ) [ 0 ] . trim ( ) ;
8181 if ( ! content ) continue ;
82- const [ range , width ] = content . split ( ";" ) . map ( ( s ) => s . trim ( ) ) ;
82+ let [ range , width ] = content . split ( ";" ) . map ( ( s ) => s . trim ( ) ) ;
8383 if ( width !== "W" && width !== "F" ) continue ;
8484 intervals . push ( parseCodepointRange ( range ) ) ;
8585 }
@@ -89,10 +89,10 @@ function parseWideEastAsian(text: string): Interval[] {
8989function mergeIntervals ( intervals : Interval [ ] ) : Interval [ ] {
9090 if ( intervals . length === 0 ) return [ ] ;
9191 intervals . sort ( ( a , b ) => a . start - b . start ) ;
92- const merged : Interval [ ] = [ { ...intervals [ 0 ] } ] ;
92+ let merged : Interval [ ] = [ { ...intervals [ 0 ] } ] ;
9393 for ( let index = 1 ; index < intervals . length ; index ++ ) {
94- const current = merged [ merged . length - 1 ] ;
95- const next = intervals [ index ] ;
94+ let current = merged [ merged . length - 1 ] ;
95+ let next = intervals [ index ] ;
9696 if ( next . start <= current . end + 1 ) {
9797 current . end = Math . max ( current . end , next . end ) ;
9898 } else {
@@ -109,9 +109,9 @@ function mergeIntervals(intervals: Interval[]): Interval[] {
109109 */
110110function subtractIntervals ( base : Interval [ ] , mask : Interval [ ] ) : Interval [ ] {
111111 let result = [ ...base ] ;
112- for ( const m of mask ) {
113- const next : Interval [ ] = [ ] ;
114- for ( const b of result ) {
112+ for ( let m of mask ) {
113+ let next : Interval [ ] = [ ] ;
114+ for ( let b of result ) {
115115 if ( m . end < b . start || m . start > b . end ) {
116116 next . push ( b ) ;
117117 } else {
@@ -126,8 +126,8 @@ function subtractIntervals(base: Interval[], mask: Interval[]): Interval[] {
126126
127127function assertNoAdjacentRanges ( intervals : Interval [ ] , label : string ) : void {
128128 for ( let index = 1 ; index < intervals . length ; index ++ ) {
129- const previous = intervals [ index - 1 ] ;
130- const current = intervals [ index ] ;
129+ let previous = intervals [ index - 1 ] ;
130+ let current = intervals [ index ] ;
131131 if ( current . start <= previous . end + 1 ) {
132132 throw new Error (
133133 `${ label } : adjacent ranges at index ${ index } : ` +
@@ -155,40 +155,40 @@ function formatUint8Hex(value: number): string {
155155}
156156
157157function formatUint32Array ( values : number [ ] , indent = " " ) : string {
158- const lines : string [ ] = [ ] ;
158+ let lines : string [ ] = [ ] ;
159159 for ( let index = 0 ; index < values . length ; index += 8 ) {
160- const chunk = values . slice ( index , index + 8 ) ;
160+ let chunk = values . slice ( index , index + 8 ) ;
161161 lines . push ( indent + chunk . map ( formatUint32Hex ) . join ( ", " ) + "," ) ;
162162 }
163163 return lines . join ( "\n" ) ;
164164}
165165
166166function formatUint16Array ( values : number [ ] , indent = " " ) : string {
167- const lines : string [ ] = [ ] ;
167+ let lines : string [ ] = [ ] ;
168168 for ( let index = 0 ; index < values . length ; index += 8 ) {
169- const chunk = values . slice ( index , index + 8 ) ;
169+ let chunk = values . slice ( index , index + 8 ) ;
170170 lines . push ( indent + chunk . map ( formatUint16Hex ) . join ( ", " ) + "," ) ;
171171 }
172172 return lines . join ( "\n" ) ;
173173}
174174
175175function formatUint8Array ( values : number [ ] , indent = " " ) : string {
176- const lines : string [ ] = [ ] ;
176+ let lines : string [ ] = [ ] ;
177177 for ( let index = 0 ; index < values . length ; index += 8 ) {
178- const chunk = values . slice ( index , index + 8 ) ;
178+ let chunk = values . slice ( index , index + 8 ) ;
179179 lines . push ( indent + chunk . map ( formatUint8Hex ) . join ( ", " ) + "," ) ;
180180 }
181181 return lines . join ( "\n" ) ;
182182}
183183
184- const [ derivedCategoryText , derivedCorePropsText , eastAsianWidthText ] =
184+ let [ derivedCategoryText , derivedCorePropsText , eastAsianWidthText ] =
185185 await Promise . all ( [
186186 fetchText ( "extracted/DerivedGeneralCategory.txt" ) ,
187187 fetchText ( "DerivedCoreProperties.txt" ) ,
188188 fetchText ( "EastAsianWidth.txt" ) ,
189189 ] ) ;
190190
191- const nonspacingMarks = parseGeneralCategory ( derivedCategoryText , "Mn" ) ;
191+ let nonspacingMarks = parseGeneralCategory ( derivedCategoryText , "Mn" ) ;
192192const enclosingMarks = parseGeneralCategory ( derivedCategoryText , "Me" ) ;
193193const defaultIgnorables = parseDerivedProperty (
194194 derivedCorePropsText ,
@@ -211,7 +211,7 @@ const combiningIntervals = mergeIntervals(
211211) ;
212212assertNoAdjacentRanges ( combiningIntervals , "combining" ) ;
213213
214- const wideIntervals = mergeIntervals ( parseWideEastAsian ( eastAsianWidthText ) ) ;
214+ let wideIntervals = mergeIntervals ( parseWideEastAsian ( eastAsianWidthText ) ) ;
215215assertNoAdjacentRanges ( wideIntervals , "wide" ) ;
216216
217217// Strip any codepoints that are in both tables — combining takes priority.
@@ -225,8 +225,8 @@ const allSpecialIntervals: TaggedInterval[] = [
225225] . sort ( ( a , b ) => a . start - b . start ) ;
226226
227227for ( let index = 1 ; index < allSpecialIntervals . length ; index ++ ) {
228- const prev = allSpecialIntervals [ index - 1 ] ;
229- const curr = allSpecialIntervals [ index ] ;
228+ let prev = allSpecialIntervals [ index - 1 ] ;
229+ let curr = allSpecialIntervals [ index ] ;
230230 if ( curr . start <= prev . end ) {
231231 throw new Error (
232232 `combining/wide overlap at 0x${ curr . start . toString ( 16 ) } ` +
@@ -235,13 +235,13 @@ for (let index = 1; index < allSpecialIntervals.length; index++) {
235235 }
236236}
237237
238- const allRanges = allSpecialIntervals . map ( ( i ) => ( {
238+ let allRanges = allSpecialIntervals . map ( ( i ) => ( {
239239 start : i . start ,
240240 count : i . end - i . start ,
241241 width : i . width ,
242242} ) ) ;
243243
244- for ( const range of allRanges ) {
244+ for ( let range of allRanges ) {
245245 if ( range . start > 0x1fffff ) {
246246 throw new Error (
247247 `Range start 0x${
@@ -258,7 +258,7 @@ for (const range of allRanges) {
258258const smallRanges = allRanges . filter ( ( range ) => range . count <= 1023 ) ;
259259const largeRanges = allRanges . filter ( ( range ) => range . count > 1023 ) ;
260260
261- const smallPacked = smallRanges . map (
261+ let smallPacked = smallRanges . map (
262262 ( range ) =>
263263 ( range . start << 11 ) | ( range . count << 1 ) | ( range . width === 2 ? 1 : 0 ) ,
264264) ;
@@ -271,7 +271,7 @@ for (let index = 1; index < smallPacked.length; index++) {
271271 }
272272}
273273
274- const largeStarts = largeRanges . map ( ( range ) => range . start ) ;
274+ let largeStarts = largeRanges . map ( ( range ) => range . start ) ;
275275const largeCounts = largeRanges . map ( ( range ) => range . count ) ;
276276const largeWidths = largeRanges . map ( ( range ) => range . width ) ;
277277
@@ -280,9 +280,9 @@ const largeWidths = largeRanges.map((range) => range.width);
280280const bmpFilter = new Uint32Array ( 16 ) ;
281281for ( const range of allRanges ) {
282282 if ( range . start > 0xffff ) continue ;
283- const endCp = Math . min ( range . start + range . count , 0xffff ) ;
284- const startBlock = range . start >> 7 ;
285- const endBlock = endCp >> 7 ;
283+ let endCp = Math . min ( range . start + range . count , 0xffff ) ;
284+ let startBlock = range . start >> 7 ;
285+ let endBlock = endCp >> 7 ;
286286 for ( let block = startBlock ; block <= endBlock ; block ++ ) {
287287 bmpFilter [ block >> 5 ] |= 1 << ( block & 31 ) ;
288288 }
@@ -296,7 +296,7 @@ for (const w of bmpFilter) {
296296 }
297297}
298298
299- const tableBytes = 16 * 4 + // bmp_filter
299+ let tableBytes = 16 * 4 + // bmp_filter
300300 smallPacked . length * 4 +
301301 largeStarts . length * 4 +
302302 largeCounts . length * 2 +
@@ -307,9 +307,9 @@ console.error(`special_large_ranges: ${largeRanges.length} entries`);
307307console . error ( `BMP dirty blocks: ${ dirtyBlocks } / 512` ) ;
308308console . error ( `Table data: ${ tableBytes } bytes` ) ;
309309
310- const date = new Date ( ) . toISOString ( ) . slice ( 0 , 10 ) ;
310+ let date = new Date ( ) . toISOString ( ) . slice ( 0 , 10 ) ;
311311
312- const output = `\
312+ let output = `\
313313/* wcwidth.c - Unicode character width lookup
314314 * Unicode 16.0 - generated by tasks/gen-wcwidth.ts on ${ date }
315315 *
@@ -413,7 +413,7 @@ int iswprint(uint32_t codepoint) { return wcwidth(codepoint) >= 0; }
413413` ;
414414
415415if ( Deno . args . includes ( "--check" ) ) {
416- const existing = await Deno . readTextFile ( "src/wcwidth.c" ) ;
416+ let existing = await Deno . readTextFile ( "src/wcwidth.c" ) ;
417417 if ( existing !== output ) {
418418 console . error ( "src/wcwidth.c is out of date — run: deno task gen-wcwidth" ) ;
419419 Deno . exit ( 1 ) ;
0 commit comments