Skip to content

Commit

Permalink
Feat: Javascript/Typescript extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
zealot128 committed Jul 4, 2024
1 parent 04b8c40 commit 5fb6302
Show file tree
Hide file tree
Showing 16 changed files with 631 additions and 10 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ This Gem **supports** the following source files:
- Caveats: because of limitations of the HTML/XML parser it will slightly transform the HTML, for example, self closing tags are expanded (e.g. ``<Component />`` will become ``<Component></Component>``). Also multi-line arrangements of attributes, tags etc. might produce unexpected results, so make sure to use Git and diff the result.
- Vue Pug views
- Pug is very similar to slim and thus relatively well extractable via Regexp.
- Javascript string Literals by vendoring a small **nodeJS** script in ``js/find_string_tokens.js`` (requires node16+).
- Vue: Literal strings in script block (via bundled nodejs file)
- JS/TS: Literal strings
- ERB views
- by vendoring/extending https://github.com/ProGM/i18n-html_extractor (MIT License)

CURRENTLY THERE IS **NO SUPPORT** FOR:

- haml ( integrating https://github.com/shaiguitar/haml-i18n-extractor)
- JS: Template-Literals

But I am open to integrating PRs for those!

Expand All @@ -49,6 +53,14 @@ extract-i18n --locale de --yaml config/locales/unsorted.de.yml app/views/user
If you prefer relative keys in slim views use ``--slim-relative``, e.g. ``t('.title')`` instead of ``t('users.index.title')``.
I prefer absolute keys, as it makes copy pasting/ moving files much safer.

To extract Vue/JS files, we usually put them in a namespace ``js.*`` and handle them with i18n-tasks as well, so to extract Vue-Components, or plain JS files:

```
extract-i18n --locale de --yaml config/locales/unsorted.de.yml -n js app/javascript/components/Foobar.vue
```

Will prefix the keys with ``js.components.foobar``. This system also switches the **interpolation format** from ``%{foo}`` to ``{foo}``, when handling Vue,JS,TS file.


## Contributing

Expand Down
9 changes: 6 additions & 3 deletions extract_i18n.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Gem::Specification.new do |spec|
spec.version = ExtractI18n::VERSION
spec.authors = ["Stefan Wienert"]
spec.email = ["[email protected]"]
spec.metadata = { "rubygems_mfa_required" => "true" }

spec.summary = %q{Extact i18n from Ruby files using Ruby parser and slim files using regex}
spec.description = %q{Extact i18n from Ruby files using Ruby parser and slim files using regex interactively}
Expand All @@ -20,10 +21,12 @@ Gem::Specification.new do |spec|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables << "extract-i18n"
end - ['js/build.js', 'js/package.json', 'js/yarn.lock', 'js/run.mjs']

spec.bindir = "exe"
spec.executables << "extract-i18n"
spec.require_paths = ["lib"]
spec.required_ruby_version = '>= 2.7.0'

spec.add_runtime_dependency 'nokogiri'
spec.add_runtime_dependency 'parser', '>= 2.6'
Expand Down
1 change: 1 addition & 0 deletions js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions js/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 18.12.1
9 changes: 9 additions & 0 deletions js/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { build } = require('esbuild');

build({
entryPoints: ['run.mjs'],
bundle: true,
platform: 'node',
outfile: 'find_string_tokens.js',
minify: true,
}).catch(() => process.exit(1));
106 changes: 106 additions & 0 deletions js/find_string_tokens.js

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "js",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.7",
"recast": "^0.23.9",
"typescript": "^5.5.3"
},
"devDependencies": {
"esbuild": "^0.23.0"
}
}
68 changes: 68 additions & 0 deletions js/run.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { parse, print, visit } from "recast";
import typescript from "recast/parsers/babel-ts"
import fs from "fs";

let code
if (process.argv.length == 3) {
code = fs.readFileSync(process.argv[2], "utf-8");
}

if (!code) {
code = fs.readFileSync(0, "utf-8");
}

if (!code) {
console.error("Usage: node find_string_tokens.js <filename> | STDIN");
process.exit(1);
}


const ast = parse(code, {
parser: typescript,
})

const replacements = []

visit(ast, {
visitLiteral(path) {
const { node } = path;
if (typeof node.value === "string") {
replacements.push({
type: 'literal',
value: node.value,
raw: node.raw || node.extra?.raw,
loc: {
start: node.loc.start,
end: node.loc.end,
index: node.loc.index,
}
})
}
this.traverse(path);
},
visitTemplateLiteral(path) {
const { node } = path;
replacements.push({
type: 'template',
quasis: node.quasis.map(quasi => ({
value: quasi.value,
raw: quasi.raw || quasi.extra?.raw,
loc: {
start: quasi.loc.start,
end: quasi.loc.end,
index: quasi.loc.index,
}
})),
expressions: node.expressions.map(expression => ({
loc: {
start: expression.loc.start,
end: expression.loc.end,
index: expression.loc.index,
}
})),
})
this.traverse(path);
}
// interpolation Strings?
});
process.stdout.write(JSON.stringify(replacements, null, " "))
201 changes: 201 additions & 0 deletions js/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@babel/parser@^7.24.7":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85"
integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz#145b74d5e4a5223489cabdc238d8dad902df5259"
integrity sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz#453bbe079fc8d364d4c5545069e8260228559832"
integrity sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.0.tgz#26c806853aa4a4f7e683e519cd9d68e201ebcf99"
integrity sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.0.tgz#1e51af9a6ac1f7143769f7ee58df5b274ed202e6"
integrity sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz#d996187a606c9534173ebd78c58098a44dd7ef9e"
integrity sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz#30c8f28a7ef4e32fe46501434ebe6b0912e9e86c"
integrity sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz#30f4fcec8167c08a6e8af9fc14b66152232e7fb4"
integrity sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz#1003a6668fe1f5d4439e6813e5b09a92981bc79d"
integrity sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz#3b9a56abfb1410bb6c9138790f062587df3e6e3a"
integrity sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz#237a8548e3da2c48cd79ae339a588f03d1889aad"
integrity sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz#4269cd19cb2de5de03a7ccfc8855dde3d284a238"
integrity sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz#82b568f5658a52580827cc891cb69d2cb4f86280"
integrity sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz#9a57386c926262ae9861c929a6023ed9d43f73e5"
integrity sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz#f3a79fd636ba0c82285d227eb20ed8e31b4444f6"
integrity sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz#f9d2ef8356ce6ce140f76029680558126b74c780"
integrity sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz#45390f12e802201f38a0229e216a6aed4351dfe8"
integrity sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz#c8409761996e3f6db29abcf9b05bee8d7d80e910"
integrity sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz#ba70db0114380d5f6cfb9003f1d378ce989cd65c"
integrity sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz#72fc55f0b189f7a882e3cf23f332370d69dfd5db"
integrity sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz#b6ae7a0911c18fe30da3db1d6d17a497a550e5d8"
integrity sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz#58f0d5e55b9b21a086bfafaa29f62a3eb3470ad8"
integrity sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz#b858b2432edfad62e945d5c7c9e5ddd0f528ca6d"
integrity sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz#167ef6ca22a476c6c0c014a58b4f43ae4b80dec7"
integrity sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==

"@esbuild/[email protected]":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz#db44a6a08520b5f25bbe409f34a59f2d4bcc7ced"
integrity sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==

ast-types@^0.16.1:
version "0.16.1"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2"
integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==
dependencies:
tslib "^2.0.1"

esbuild@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.0.tgz#de06002d48424d9fdb7eb52dbe8e95927f852599"
integrity sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==
optionalDependencies:
"@esbuild/aix-ppc64" "0.23.0"
"@esbuild/android-arm" "0.23.0"
"@esbuild/android-arm64" "0.23.0"
"@esbuild/android-x64" "0.23.0"
"@esbuild/darwin-arm64" "0.23.0"
"@esbuild/darwin-x64" "0.23.0"
"@esbuild/freebsd-arm64" "0.23.0"
"@esbuild/freebsd-x64" "0.23.0"
"@esbuild/linux-arm" "0.23.0"
"@esbuild/linux-arm64" "0.23.0"
"@esbuild/linux-ia32" "0.23.0"
"@esbuild/linux-loong64" "0.23.0"
"@esbuild/linux-mips64el" "0.23.0"
"@esbuild/linux-ppc64" "0.23.0"
"@esbuild/linux-riscv64" "0.23.0"
"@esbuild/linux-s390x" "0.23.0"
"@esbuild/linux-x64" "0.23.0"
"@esbuild/netbsd-x64" "0.23.0"
"@esbuild/openbsd-arm64" "0.23.0"
"@esbuild/openbsd-x64" "0.23.0"
"@esbuild/sunos-x64" "0.23.0"
"@esbuild/win32-arm64" "0.23.0"
"@esbuild/win32-ia32" "0.23.0"
"@esbuild/win32-x64" "0.23.0"

esprima@~4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==

recast@^0.23.9:
version "0.23.9"
resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b"
integrity sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==
dependencies:
ast-types "^0.16.1"
esprima "~4.0.0"
source-map "~0.6.1"
tiny-invariant "^1.3.3"
tslib "^2.0.1"

source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==

tiny-invariant@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==

tslib@^2.0.1:
version "2.6.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==

typescript@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.3.tgz#e1b0a3c394190838a0b168e771b0ad56a0af0faa"
integrity sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==
12 changes: 7 additions & 5 deletions lib/extract_i18n.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ class << self
'::',
'v-else',
'v-else-if',
%r{^\| },
'&nbsp;',
%r{^#[^ ]+$},
%r{^/}
%r{^/},
%r{^(mdi|fa|fas|far|icon)-},
]
self.html_fields_with_plaintext = %w[title placeholder alt label aria-label modal-title]

Expand All @@ -43,9 +44,10 @@ def self.key(string, length: 25)

def self.file_key(path)
path.gsub(strip_path, '').
gsub(%r{^/|/$}, '').
gsub(/\.(vue|rb|html\.slim|\.slim)$/, '').
gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').
gsub(%r{^/|/$}, ''). # remove leading and trailing slashes
gsub(/\.[a-z]+$/, ''). # remove file extension
gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'). # convert camelcase to underscore
gsub(/([a-z\d])([A-Z])/, '\1_\2').
gsub('/_', '.').
gsub('/', '.').
tr("-", "_").downcase
Expand Down
1 change: 1 addition & 0 deletions lib/extract_i18n/adapters/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def self.for(file_path)
when /\.rb$/ then RubyAdapter
when /\.erb$/ then ErbAdapter
when /\.slim$/ then SlimAdapter
when /\.ts$/, /\.js$/, /\.mjs/, /\.jsx$/ then JsAdapter
when /\.vue$/
if File.read(file_path)[/lang=.pug./]
VuePugAdapter
Expand Down
Loading

0 comments on commit 5fb6302

Please sign in to comment.