title: Node.js/jade syntax error: unexpected token ;
body: <p>I'm trying to learn node.js. I'm working through an example in the OReilly book "Building node applications with mongodb and backbone". I'm running into an error, and I haven't been able to work it out.</p>
  
  <p>I hunted the error for a while (in my own version of the code). Most similar cases were related to jade parsing comments badly (which I'm not using here). Looks like another possibility is module versions not being compatible with this code or each other, but I'm not prepared to go digging into that. I copied the code exactly from the example instead of using my own version, and I'm getting the same result.</p>
  
  <p>The trace points to a line in the jade template, but I'm not sure where the problem really is.</p>
  
  <p>Here's the code from the example .js file:</p>
  
  <pre><code>var http = require('http');
  var express = require('express');
  var app = express();
  var server = http.createServer(app);
  var io = require('socket.io').listen(server);
  
  var catchPhrases = ['Why I oughta...', 'Nyuk Nyuk Nyuk', 'Poifect!', 'Spread out!', 'Say a few syllables!', 'Soitenly!'];
  
  app.set('view engine', 'jade');
  app.set('view options', { layout: true});
  app.set('views', __dirname + '/views');
  
  app.get('/stooges/chat', function(req, res, next) {
  res.render('chat');
  });
  
  io.sockets.on('connection', function(socket) {
  var sendChat = function(title, text) {
  socket.emit('chat', {
  title: title,
  contents: text
  });
  };
  
  setInterval(function() {
  var randomIndex = Math.floor(Math.random() * catchPhrases.length);
  sendChat('Stooge', catchPhrases[randomIndex]);
  }, 5000);
  
  sendChat('Welcome to Stooge Chat', 'The Stooges are on the line');
  
  socket.on('chat', function(data) {
  sendChat('You', data.text);
  });
  });
  
  app.get('/?', function(req, res) {
  res.render('index');
  });
  
  var port = 8080;
  server.listen(port);
  console.log('Listening on port ' + port);
  </code></pre>
  
  <p>And here's the corresponding jade template:</p>
  
  <pre><code>extends layout
  
  block scripts
  script(type='text/javascript', src='/socket.io/socket.io.js')
  script(type='text/javascript')
  var socket = io.connect('http://localhost:8080');
  socket.on('chat', function(data) {
  document.getElementById('chat').innerHTML = '&lt;p&gt;&lt;b&gt;' + data.title + '&lt;/b&gt;: ' + data.contents + '&lt;/p&gt;';
  });
  var submitChat = function(form) {
  socket.emit('chat', {text: form.chat.value});
  return false;
  };
  
  block content
  div#chat
  
  form(onsubmit='return submitChat(this);')
  input#chat(name='chat', type='text')
  input(type='submit', value='Send Chat')
  </code></pre>
  
  <p>And here's the output:</p>
  
  <pre><code>   info  - socket.io started
  Listening on port 8080
  SyntaxError: /home/rob/Documents/Node/views/chat.jade:9
      7| socket.on('chat', function(data) {
      8| document.getElementById('chat').innerHTML = '&lt;p&gt;&lt;b&gt;' + data.title + '&lt;/b&gt;: ' + data.contents + '&lt;/p&gt;';
    &gt; 9| });
      10| var submitChat = function(form) {
      11| socket.emit('chat', {text: form.chat.value});
      12| return false;
  
  Unexpected token ;
      at Function (&lt;anonymous&gt;)
      at assertExpression (/home/rob/Documents/Node/node_modules/jade/lib/lexer.js:31:3)
      at Object.Lexer.attrs (/home/rob/Documents/Node/node_modules/jade/lib/lexer.js:648:20)
      at Object.Lexer.next (/home/rob/Documents/Node/node_modules/jade/lib/lexer.js:868:15)
      at Object.Lexer.lookahead (/home/rob/Documents/Node/node_modules/jade/lib/lexer.js:114:46)
      at Parser.lookahead (/home/rob/Documents/Node/node_modules/jade/lib/parser.js:100:23)
      at Parser.peek (/home/rob/Documents/Node/node_modules/jade/lib/parser.js:77:17)
      at Parser.tag (/home/rob/Documents/Node/node_modules/jade/lib/parser.js:733:22)
      at Parser.parseTag (/home/rob/Documents/Node/node_modules/jade/lib/parser.js:719:17)
      at Parser.parseExpr (/home/rob/Documents/Node/node_modules/jade/lib/parser.js:188:21)
  </code></pre>