<commit_before>Eco: Embedded CoffeeScript templates
====================================

Eco lets you embed [CoffeeScript](http://coffeescript.org/) logic in
your markup. It's like EJS and ERB, but with CoffeeScript inside the
`<% ... %>`. Use it from [Node.js](http://nodejs.org/) to render your
application's views on the server side, or compile your templates
to JavaScript with the `eco` command-line utility and use them to
dynamically render views in the browser.

Here's how an Eco template looks:

    <% if @projects.length: %>
      <% for project in @projects: %>
        <a href="<%= project.url %>"><%= project.name %></a>
        <p><%= project.description %></p>
      <% end %>
    <% else: %>
      No projects
    <% end %>

# Usage

Use `eco.render()` to render your templates. The first argument is the
template source as a string. The second argument is the context object
which contains your view state and any helper methods you want to call.

    eco = require "eco"
    fs  = require "fs"

    template = fs.readFileSync __dirname + "/views/projects.html.eco", "utf-8"
    console.log eco.render template, projects: [
      { name: "Mobile app", url: "/projects/1", description: "Iteration 1" },
      { name: "Home page redesign", url: "/projects/2" }
    ]

Eco is fully synchronous. If your template needs to access data from
asynchronous operations, perform those first before calling `render`.

## Language reference

Eco's syntax is simple:

* `<% expression %>`: Evaluate a CoffeeScript expression without
  printing its return value.
* `<%= expression %>`: Evaluate a CoffeeScript expression, escape its
  return value, and print it.
* `<%- expression %>`: Evaluate a CoffeeScript expression and print
  its return value without escaping it.
* `<%= @property %>`: Print the escaped value of the property
  `property` from the context object passed to `render`.
* `<%= @helper() %>`: Call the helper method `helper` from the context
  object passed to `render`, then print its escaped return value.

## A note about whitespace

CoffeeScript is whitespace-sensitive, but your templates
aren't. Therefore, Eco code tags that begin an indented CoffeeScript
block must be suffixed with a colon. To indicate the end of an
indented block, use the special tag `<% end %>`. For example:

    <% if @project.isOnHold(): %>
      On Hold
    <% end %>

You don't need to write the `if` and `end` tags on separate lines:

    <% if @project.isOnHold(): %> On Hold <% end %>

And you can use the single-line postfix form of `if` as you'd expect:

    <%= "On Hold" if @project.isOnHold() %>

Certain forms in CoffeeScript, such as `else`, must be unindented
first. Eco handles that for you automatically:

    <% if @project.isOnHold(): %>
      On Hold
    <% else if @project.isArchived(): %>
      Archived
    <% end %>

## The context object
<commit_msg>Document tag escaping and blocks in the syntax synopsis<commit_after>Eco: Embedded CoffeeScript templates
====================================

Eco lets you embed [CoffeeScript](http://coffeescript.org/) logic in
your markup. It's like EJS and ERB, but with CoffeeScript inside the
`<% ... %>`. Use it from [Node.js](http://nodejs.org/) to render your
application's views on the server side, or compile your templates
to JavaScript with the `eco` command-line utility and use them to
dynamically render views in the browser.

Here's how an Eco template looks:

    <% if @projects.length: %>
      <% for project in @projects: %>
        <a href="<%= project.url %>"><%= project.name %></a>
        <p><%= project.description %></p>
      <% end %>
    <% else: %>
      No projects
    <% end %>

# Usage

Use `eco.render()` to render your templates. The first argument is the
template source as a string. The second argument is the context object
which contains your view state and any helper methods you want to call.

    eco = require "eco"
    fs  = require "fs"

    template = fs.readFileSync __dirname + "/views/projects.html.eco", "utf-8"
    console.log eco.render template, projects: [
      { name: "Mobile app", url: "/projects/1", description: "Iteration 1" },
      { name: "Home page redesign", url: "/projects/2" }
    ]

Eco is fully synchronous. If your template needs to access data from
asynchronous operations, perform those first before calling `render`.

## Language reference

Eco's syntax is simple:

* `<% expression %>`: Evaluate a CoffeeScript expression without
  printing its return value.
* `<%= expression %>`: Evaluate a CoffeeScript expression, escape its
  return value, and print it.
* `<%- expression %>`: Evaluate a CoffeeScript expression and print
  its return value without escaping it.
* `<%= @property %>`: Print the escaped value of the property
  `property` from the context object passed to `render`.
* `<%= @helper() %>`: Call the helper method `helper` from the context
  object passed to `render`, then print its escaped return value.
* `<% @helper -> %>...<% end %>`: Call the helper method `helper` with
  a function as its first argument. When invoked, the function will
  capture and return the content `...` inside the tag.
* `<%%` and `%%>` will result in a literal `<%` and `%>` in the
  rendered template, respectively.

## A note about whitespace

CoffeeScript is whitespace-sensitive, but your templates
aren't. Therefore, Eco code tags that begin an indented CoffeeScript
block must be suffixed with a colon. To indicate the end of an
indented block, use the special tag `<% end %>`. For example:

    <% if @project.isOnHold(): %>
      On Hold
    <% end %>

You don't need to write the `if` and `end` tags on separate lines:

    <% if @project.isOnHold(): %> On Hold <% end %>

And you can use the single-line postfix form of `if` as you'd expect:

    <%= "On Hold" if @project.isOnHold() %>

Certain forms in CoffeeScript, such as `else`, must be unindented
first. Eco handles that for you automatically:

    <% if @project.isOnHold(): %>
      On Hold
    <% else if @project.isArchived(): %>
      Archived
    <% end %>

## The context object

{'fraction_non_alphanumeric': 0.12813781788351108, 'fraction_numerical': 0.0013125512715340443, 'mean_word_length': 3.5662921348314605, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4749840', 'n_tokens_mistral': 1846, 'n_tokens_neox': 1676, 'n_words': 757}