Skip to content

Commit

Permalink
new lexer: vue
Browse files Browse the repository at this point in the history
  • Loading branch information
http://jneen.net/ committed Nov 4, 2016
1 parent afe56c5 commit 6db0ac1
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
11 changes: 11 additions & 0 deletions lib/rouge/demos/vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<div id="app">
{{ message }}
</div>
</template>

<script lang=coffee>
app = new Vue
el: '#app'
data: { message: 'Hello Vue!' }
</script>
124 changes: 124 additions & 0 deletions lib/rouge/lexers/vue.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
module Rouge
module Lexers
load_lexer 'html.rb'

class Vue < HTML
desc 'Vue.js single-file components'
tag 'vue'
aliases 'vuejs'
filenames '*.vue'

mimetypes 'text/x-vue', 'application/x-vue'

def initialize(*)
super
@js = Javascript.new(options)
end

def self.analyze_text(text)
return 0
end

def lookup_lang(lang)
case lang
when 'html' then HTML
when 'css' then CSS
when 'javascript' then Javascript
when 'sass' then Sass
when 'scss' then Scss
when 'coffee' then CoffeeScript
# TODO: add more when the lexers are done
else
PlainText
end
end

start { @js.reset! }

prepend :root do
rule /(<)(\s*)(template)/ do
groups Name::Tag, Text, Keyword
@lang = HTML
push :template
push :lang_tag
end

rule /(<)(\s*)(style)/ do
groups Name::Tag, Text, Keyword
@lang = CSS
push :style
push :lang_tag
end

rule /(<)(\s*)(script)/ do
groups Name::Tag, Text, Keyword
@lang = Javascript
push :script
push :lang_tag
end
end

state :style do
rule /(<\s*\/\s*)(style)(\s*>)/ do
groups Name::Tag, Keyword, Name::Tag
pop!
end

mixin :style_content
mixin :embed
end

state :script do
rule /(<\s*\/\s*)(script)(\s*>)/ do
groups Name::Tag, Keyword, Name::Tag
pop!
end

mixin :script_content
mixin :embed
end

state :lang_tag do
rule /(lang\s*=)(\s*)("(?:\\.|[^\\])*?"|'(\\.|[^\\])*?'|[^\s>]+)/ do |m|
groups Name::Attribute, Text, Str
@lang = lookup_lang(m[2])
end

mixin :tag
end

state :template do
rule %r((<\s*/\s*)(template)(\s*>)) do
groups Name::Tag, Keyword, Name::Tag
pop!
end

rule /{{/ do
token Str::Interpol
push :template_interpol
@js.reset!
end

mixin :embed
end

state :template_interpol do
rule /}}/, Str::Interpol, :pop!
rule /}/, Error
mixin :template_interpol_inner
end

state :template_interpol_inner do
rule(/{/) { delegate @js; push }
rule(/}/) { delegate @js; pop! }
rule(/[^{}]+/) { delegate @js }
end

state :embed do
rule(/[^{<]+/) { delegate @lang }
rule(/[<{][^<{]*/) { delegate @lang }
end
end
end
end

12 changes: 12 additions & 0 deletions spec/lexers/vue_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
describe Rouge::Lexers::Vue do
let(:subject) { Rouge::Lexers::Vue.new }

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.vue'
end
end
end

62 changes: 62 additions & 0 deletions spec/visual/samples/vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template lang="jade">
div
p {{ greeting }} World!
other-component
</template>

<script>
import OtherComponent from './OtherComponent.vue'

export default {
data () {
return {
greeting: 'Hello'
}
},
components: {
OtherComponent
}
}
</script>

<style lang="stylus" scoped>
p
font-size 2em
text-align center
</style>



<template>
<p>{{ greeting }} World!</p>
{{ message | filterA('arg1', arg2) }}
</template>

<script>
module.exports = {
data: function () {
return {
greeting: 'Hello'
}
}
}
</script>

<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>

<script lang=coffee>
module.exports = { data: -> { greeting: 'Hello' } }
</script>

<script lang='coffee'>
module.exports = { data: -> { greeting: 'Hello' } }
</script>

<script lang="coffee">
module.exports = { data: -> { greeting: 'Hello' } }
</script>

0 comments on commit 6db0ac1

Please sign in to comment.