•  


GitHub - davidbonnet/astring: ?? Tiny and fast JavaScript code generator from an ESTree-compliant AST.
Skip to content

davidbonnet/astring

Repository files navigation

Astring

NPM Version Coverage

?? Tiny and fast JavaScript code generator from an ESTree -compliant AST.

?? Checkout the live demo .

Key features

Installation

?? Astring relies on String.prototype.repeat(amount) and String.prototype.endsWith(string) . If the environment running Astring does not define these methods, use string.prototype.repeat , string.prototype.endsWith or babel-polyfill .

Install with the Node Package Manager :

npm install astring

Or install with JSR :

deno add @davidbonnet/astring

Alternatively, checkout this repository and install the development dependencies to build the module file:

git clone https://github.com/davidbonnet/astring.git
cd
 astring
npm install

Import

Import it from Deno's third party module repository :

const
 {
 generate 
}
 =
 await
 import
(
'https://deno.land/x/astring/src/astring.js'
)

With JavaScript 6 modules:

import
 {
 generate
 }
 from
 'astring'

With CommonJS:

const
 {
 generate 
}
 =
 require
(
'astring'
)

A browser-ready minified bundle containing Astring is available at dist/astring.min.js . The module exposes a global variable astring :

<
script
 src
="
astring.min.js
" 
type
="
text/javascript
"
>
</
script
>

<
script
 type
="
text/javascript
"
>

  var
 generate
 =
 astring
.
generate

</
script
>

API

The astring module exposes the following properties:

generate(node: object, options: object): string | object

Returns a string representing the rendered code of the provided AST node . However, if an output stream is provided in the options , it writes to that stream and returns it.

The options are:

  • indent : string to use for indentation (defaults to "??" )
  • lineEnd : string to use for line endings (defaults to "\n" )
  • startingIndentLevel : indent level to start from (defaults to 0 )
  • comments : generate comments if true (defaults to false )
  • output : output stream to write the rendered code to (defaults to null )
  • generator : custom code generator (defaults to GENERATOR )
  • sourceMap : source map generator (defaults to null )
  • expressionsPrecedence : custom map of node types and their precedence level (defaults to EXPRESSIONS_PRECEDENCE )

GENERATOR: object

Base generator that can be used to extend Astring .

EXPRESSIONS_PRECEDENCE: object

Mapping of node types and their precedence level to let the generator know when to use parentheses.

NEEDS_PARENTHESES: number

Default precedence level that always triggers the use of parentheses.

baseGenerator: object

?? Deprecated, use GENERATOR instead.

Benchmark

Generating code

Operations per second for generating each sample code from a pre-parsed AST:

code sample (length) escodegen astring uglify babel prettier
tiny code (11) 1,257,527 7,185,642 129,467 156,184 333
everything (8532) 1,366 8,008 0 346 64

Parsing and generating code

Operations per second for parsing and generating each sample code:

code sample (length) acorn + astring meriyah + astring buble sucrase
tiny code (11) 92,578 864,665 25,911 575,370
everything (8532) 706 1,425 132 1,403

Examples

The following examples are written in JavaScript 5 with Astring imported a la CommonJS .

Generating code

This example uses Acorn , a blazingly fast JavaScript AST producer and therefore the perfect companion of Astring.

// Make sure acorn and astring modules are imported


// Set example code

var
 code
 =
 'let answer = 4 + 7 * 5 + 3;\n'

// Parse it into an AST

var
 ast
 =
 acorn
.
parse
(
code
,
 {
 ecmaVersion
: 
6
 }
)

// Format it into a code string

var
 formattedCode
 =
 astring
.
generate
(
ast
)

// Check it

console
.
log
(
code
 ===
 formattedCode
 ? 
'It works!'
 : 
'Something went wrong…'
)

Generating source maps

This example uses the source map generator from the Source Map module.

// Make sure acorn, sourceMap and astring modules are imported


var
 code
 =
 'function add(a, b) { return a + b; }\n'

var
 ast
 =
 acorn
.
parse
(
code
,
 {

  ecmaVersion
: 
6
,

  sourceType
: 
'module'
,

  // Locations are needed in order for the source map generator to work

  locations
: 
true
,

}
)

// Create empty source map generator

var
 map
 =
 new
 sourceMap
.
SourceMapGenerator
(
{

  // Source file name must be set and will be used for mappings

  file
: 
'script.js'
,

}
)

var
 formattedCode
 =
 generate
(
ast
,
 {

  // Enable source maps

  sourceMap
: 
map
,

}
)

// Display generated source map

console
.
log
(
map
.
toString
(
)
)

Using writable streams

This example for Node shows how to use writable streams to get the rendered code.

// Make sure acorn and astring modules are imported


// Set example code

var
 code
 =
 'let answer = 4 + 7 * 5 + 3;\n'

// Parse it into an AST

var
 ast
 =
 acorn
.
parse
(
code
,
 {
 ecmaVersion
: 
6
 }
)

// Format it and write the result to stdout

var
 stream
 =
 astring
.
generate
(
ast
,
 {

  output
: 
process
.
stdout
,

}
)

// The returned value is the output stream

console
.
log
(
'Does stream equal process.stdout?'
,
 stream
 ===
 process
.
stdout
)

Generating comments

Astring supports comment generation, provided they are stored on the AST nodes. To do so, this example uses Astravel , a fast AST traveller and modifier.

// Make sure acorn, astravel and astring modules are imported


// Set example code

var
 code
 =

  [

    '// Compute the answer to everything'
,

    'let answer = 4 + 7 * 5 + 3;'
,

    '// Display it'
,

    'console.log(answer);'
,

  ]
.
join
(
'\n'
)
 +
 '\n'

// Parse it into an AST and retrieve the list of comments

var
 comments
 =
 [
]

var
 ast
 =
 acorn
.
parse
(
code
,
 {

  ecmaVersion
: 
6
,

  locations
: 
true
,

  onComment
: 
comments
,

}
)

// Attach comments to AST nodes

astravel
.
attachComments
(
ast
,
 comments
)

// Format it into a code string

var
 formattedCode
 =
 astring
.
generate
(
ast
,
 {

  comments
: 
true
,

}
)

// Check it

console
.
log
(
code
 ===
 formattedCode
 ? 
'It works!'
 : 
'Something went wrong…'
)

Extending

Astring can easily be extended by updating or passing a custom code generator . A code generator consists of a mapping of node names and functions that take two arguments: node and state . The node points to the node from which to generate the code and the state exposes the write method that takes generated code strings.

This example shows how to support the await keyword which is part of the asynchronous functions proposal . The corresponding AwaitExpression node is based on this suggested definition .

// Make sure the astring module is imported and that `Object.assign` is defined


// Create a custom generator that inherits from Astring's base generator

var
 customGenerator
 =
 Object
.
assign
(
{
}
,
 astring
.
GENERATOR
,
 {

  AwaitExpression
: 
function
 (
node
,
 state
)
 {

    state
.
write
(
'await '
)

    var
 argument
 =
 node
.
argument

    if
 (
argument
 !=
 null
)
 {

      this
[
argument
.
type
]
(
argument
,
 state
)

    }

  }
,

}
)

// Obtain a custom AST somehow (note that this AST is not obtained from a valid code)

var
 ast
 =
 {

  type
: 
'AwaitExpression'
,

  argument
: 
{

    type
: 
'CallExpression'
,

    callee
: 
{

      type
: 
'Identifier'
,

      name
: 
'callable'
,

    }
,

    arguments
: 
[
]
,

  }
,

}

// Format it

var
 code
 =
 astring
.
generate
(
ast
,
 {

  generator
: 
customGenerator
,

}
)

// Check it

console
.
log
(

  code
 ===
 'await callable();\n'
 ? 
'It works!'
 : 
'Something went wrong…'
,

)

Command line interface

The bin/astring utility can be used to convert a JSON-formatted ESTree compliant AST of a JavaScript code. It accepts the following arguments:

  • -i , --indent : string to use as indentation (defaults to "??" )
  • -l , --line-end : string to use for line endings (defaults to "\n" )
  • -s , --starting-indent-level : indent level to start from (defaults to 0 )
  • -h , --help : print a usage message and exit
  • -v , --version : print package version and exit

The utility reads the AST from a provided list of files or from stdin if none is supplied and prints the generated code.

Example

As in the previous example, these examples use Acorn to get the JSON-formatted AST. This command pipes the AST output by Acorn from a script.js file to Astring and writes the formatted JavaScript code into a result.js file:

acorn --ecma6 script.js 
|
 astring 
>
 result.js

This command does the same, but reads the AST from an intermediary file:

acorn --ecma6 script.js 
>
 ast.json
astring ast.json 
>
 result.js

This command reads JavaScript 6 code from stdin and outputs a prettified version:

cat 
|
 acorn --ecma6 
|
 astring
- "漢字路" 한글한자자동변환 서비스는 교육부 고전문헌국역지원사업의 지원으로 구축되었습니다.
- "漢字路" 한글한자자동변환 서비스는 전통문화연구회 "울산대학교한국어처리연구실 옥철영(IT융합전공)교수팀"에서 개발한 한글한자자동변환기를 바탕하여 지속적으로 공동 연구 개발하고 있는 서비스입니다.
- 현재 고유명사(인명, 지명등)을 비롯한 여러 변환오류가 있으며 이를 해결하고자 많은 연구 개발을 진행하고자 하고 있습니다. 이를 인지하시고 다른 곳에서 인용시 한자 변환 결과를 한번 더 검토하시고 사용해 주시기 바랍니다.
- 변환오류 및 건의,문의사항은 juntong@juntong.or.kr로 메일로 보내주시면 감사하겠습니다. .
Copyright ⓒ 2020 By '전통문화연구회(傳統文化硏究會)' All Rights reserved.
 한국   대만   중국   일본