Merge with sub_roles

This commit is contained in:
chris2tof committed 2011-12-23 18:34:21 +08:00
1 parent fc591ee308
commit 62aaf79491
308 files changed
+2844 -17841

No files matched your search

-6
View File
@@ -1,6 +0,0 @@
.bundle/
log/*.log
pkg/
test/dummy/db/*.sqlite3
test/dummy/log/*.log
test/dummy/tmp/
-16
View File
@@ -1,16 +0,0 @@
source "http://rubygems.org"
# Declare your gem's dependencies in NewBlog.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gem "mongoid"
gemspec
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'
-101
View File
@@ -1,101 +0,0 @@
PATH
remote: .
specs:
NewBlog (0.0.1)
rails (~> 3.1.0.rc6)
GEM
remote: http://rubygems.org/
specs:
actionmailer (3.1.0)
actionpack (= 3.1.0)
mail (~> 2.3.0)
actionpack (3.1.0)
activemodel (= 3.1.0)
activesupport (= 3.1.0)
builder (~> 3.0.0)
erubis (~> 2.7.0)
i18n (~> 0.6)
rack (~> 1.3.2)
rack-cache (~> 1.0.3)
rack-mount (~> 0.8.2)
rack-test (~> 0.6.1)
sprockets (~> 2.0.0)
activemodel (3.1.0)
activesupport (= 3.1.0)
bcrypt-ruby (~> 3.0.0)
builder (~> 3.0.0)
i18n (~> 0.6)
activerecord (3.1.0)
activemodel (= 3.1.0)
activesupport (= 3.1.0)
arel (~> 2.2.1)
tzinfo (~> 0.3.29)
activeresource (3.1.0)
activemodel (= 3.1.0)
activesupport (= 3.1.0)
activesupport (3.1.0)
multi_json (~> 1.0)
arel (2.2.1)
bcrypt-ruby (3.0.0)
bson (1.3.1)
builder (3.0.0)
erubis (2.7.0)
hike (1.2.1)
i18n (0.6.0)
mail (2.3.0)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
mongo (1.3.1)
bson (>= 1.3.1)
mongoid (2.1.9)
activemodel (~> 3.0)
mongo (~> 1.3)
tzinfo (~> 0.3.22)
multi_json (1.0.3)
polyglot (0.3.2)
rack (1.3.2)
rack-cache (1.0.3)
rack (>= 0.4)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
rails (3.1.0)
actionmailer (= 3.1.0)
actionpack (= 3.1.0)
activerecord (= 3.1.0)
activeresource (= 3.1.0)
activesupport (= 3.1.0)
bundler (~> 1.0)
railties (= 3.1.0)
railties (3.1.0)
actionpack (= 3.1.0)
activesupport (= 3.1.0)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2)
rdoc (3.9.4)
sprockets (2.0.0)
hike (~> 1.2)
rack (~> 1.0)
tilt (!= 1.3.0, ~> 1.1)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.29)
PLATFORMS
ruby
DEPENDENCIES
NewBlog!
mongoid
-20
View File
@@ -1,20 +0,0 @@
Copyright 2011 YOURNAME
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-23
View File
@@ -1,23 +0,0 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "NewBlog/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "NewBlog"
s.version = NewBlog::VERSION
s.authors = ["TODO: Your name"]
s.email = ["TODO: Your email"]
s.homepage = "TODO"
s.summary = "TODO: Summary of NewBlog."
s.description = "TODO: Description of NewBlog."
s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
s.test_files = Dir["test/**/*"]
s.add_dependency "rails", "~> 3.1.0.rc6"
# s.add_dependency "jquery-rails"
#s.add_development_dependency "sqlite3"
end
-9
View File
@@ -1,9 +0,0 @@
{
"title": "NewBlog",
"version": "0.1",
"organization": "Rulingcom",
"author": "RD dep",
"intro": "A simple blog……",
"update_info": "Some info",
"create_date": "11-11-2011"
}
-3
View File
@@ -1,3 +0,0 @@
= NewBlog
This project rocks and uses MIT-LICENSE.
-39
View File
@@ -1,39 +0,0 @@
#!/usr/bin/env rake
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
begin
require 'rdoc/task'
rescue LoadError
require 'rdoc/rdoc'
require 'rake/rdoctask'
RDoc::Task = Rake::RDocTask
end
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'NewBlog'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
Bundler::GemHelper.install_tasks
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end
task :default => :test
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -1,7 +0,0 @@
/*
*This is a manifest file that'll automatically include all the stylesheets available in this directory
*and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
*the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require_tree .
*/
@@ -1,51 +0,0 @@
/* module */
#module{
float: left;
width: 170px;
margin-left: 20px;
}
.production {
padding: 10px;
font-size: 12px;
border: 1px solid #e1e1e1;
margin-bottom: 10px;
background: #DDDAD0;
color: #484339;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-moz-box-shadow: 0 0 5px #33322C;
-webkit-box-shadow: 0 0 5px #33322C;
box-shadow: 0 0 5px #33322C;
text-shadow: 0 1px 0 #fff;
line-height: 1.4;
font-family: Arial;
}
.production h2{
font-size: 18px;
margin-bottom: 10px;
text-shadow: 0 1px 0 #fff;
border-left: 4px solid #B6300C;
line-height: 20px;
padding-left: 5px;
}
.production table{
border: 1px solid #9b968c;
padding: 5px;
width: 145px;
}
.production th{
background: #d3cfc3;
font-weight: bold;
}
.production th, .production tr, .production td{
border: 1px solid #9b968c;
padding: 5px;
}
.production a{
color: #9a460e;
text-decoration: none;
}
.production a:hover{
text-decoration: underline;
}
View File
Whitespace-only changes.
@@ -1,23 +0,0 @@
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale
# Set I18n.locale
def set_locale
# update session if passed
session[:locale] = params[:locale] if params[:locale]
# set locale based on session or default
begin
# check if locale is valid for non site pages
if !VALID_LOCALES.include?(session[:locale])
I18n.locale = I18n.default_locale
else
I18n.locale = session[:locale]
end
rescue
I18n.locale = I18n.default_locale
end
end
end
@@ -1,7 +0,0 @@
class Panel::Blog::CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create!(params[:comment])
redirect_to panel_blog_post_url(@post)
end
end
@@ -1,111 +0,0 @@
class Panel::Blog::PostsController < ApplicationController
layout 'admin'
# GET /posts
# GET /posts.xml
def widget_index
@posts = Post.all
widget_default_layout
end
def widget_latest_post
@post = Post.all.last
widget_default_layout
end
def index
@posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
end
end
# GET /posts/1
# GET /posts/1.xml
def show
@post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
@post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @post }
end
end
# GET /posts/1/edit
def edit
@post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
@post = Post.new(params[:post])
respond_to do |format|
if @post.save
format.html { redirect_to(panel_blog_post_url(@post), :notice => t('blog.create_post_success')) }
format.xml { render :xml => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update_attributes(params[:post])
format.html { redirect_to(panel_blog_post_url(@post), :notice => t('blog.update_post_success')) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
@post = Post.find(params[:id])
@post.destroy
respond_to do |format|
format.html { redirect_to(panel_blog_posts_url) }
format.xml { head :ok }
end
end
end
def widget_default_layout
respond_to do |format|
format.html {
if params[:edit_view]
#in the case of editing,should be displayed in modal window and
#be restricted by the border developer sat.
render :layout => 'admin'
else
#in the case of fetching data for ajax display,should
render :layout => 'production'
end
}
format.xml { render :xml => @posts }
end
end
View File
Whitespace-only changes.
@@ -1,2 +0,0 @@
module ApplicationHelper
end
View File
Whitespace-only changes.
View File
Whitespace-only changes.
-7
View File
@@ -1,7 +0,0 @@
class Comment
include Mongoid::Document
include Mongoid::Timestamps
field :name, :type => String
field :body, :type => String
embedded_in :post, :inverse_of => :comments
end
-8
View File
@@ -1,8 +0,0 @@
class Post
include Mongoid::Document
include Mongoid::Timestamps
field :title, :type => String
field :body, :type => String
embeds_many :comments
validates_presence_of :title, :body
end
View File
Whitespace-only changes.
@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Blog</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Blog</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body class="edit preview">
<div class="wapper">
<%= yield %>
</div>
</body>
</html>
@@ -1,3 +0,0 @@
<div class="production">
<%= yield %>
</div>
@@ -1,14 +0,0 @@
<%= f.error_messages %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
@@ -1,8 +0,0 @@
<h1><%= t('blog.editing_post') %></h1>
<%= form_for @post, :url => panel_blog_post_path(@post) do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
<%= link_to t('blog.show'), panel_blog_post_path(@post) %> |
<%= link_back %>
@@ -1,32 +0,0 @@
<% content_for :secondary do %>
<ul class="list">
<li><%= link_to t('blog.new_post'), new_panel_blog_post_path, :class => 'seclink1' %></li>
</ul>
<% end -%>
<%= flash_messages %>
<h1><%= t('blog.list_post') %></h1>
<table>
<tr>
<th><%= t('blog.title') %></th>
<th><%= t('blog.body') %></th>
<th></th>
<th></th>
<th></th>
</tr>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= truncate(post.body,:length=>15) %></td>
<td><%= link_to t('blog.show'), panel_blog_post_path(post) %></td>
<td><%= link_to t('blog.edit'), edit_panel_blog_post_path(post) %></td>
<td><%= link_to t('blog.delete'), panel_blog_post_path(post), :confirm => t('blog.sure?'), :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
@@ -1,5 +0,0 @@
<%=stylesheet_link_tag "NewBlog/application"%>
<h2><%=@post.title%></h2>
<p>
<%= @post.body%>
</p>
@@ -1,13 +0,0 @@
<% content_for :secondary do %>
<ul class="list">
<li><%= link_to t('blog.index'), panel_blog_posts_path, :class => 'seclink2' %></li>
</ul>
<% end -%>
<%= flash_messages %>
<h1><%= t('blog.new_post') %></h1>
<%= form_for @post, :url => panel_blog_posts_path do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
<%= link_back %>
@@ -1,38 +0,0 @@
<p id="notice"><%= flash_messages %></p>
<p>
<b><%= t('blog.body') %></b>
<%=h @post.body %>
</p>
<h2><%= t('blog.comments') %></h2>
<% @post.comments.each do |c| %>
<p>
<b><%=h c.name %> said:</b><br />
<%= time_ago_in_words(c.created_at) %> ago
</p>
<p>
<%=h c.body %>
</p>
<% end %>
<%= form_for Comment.new, :url => panel_blog_comments_path do |f| %>
<p>
<%= f.label :name, "Author" %><br />
<%= f.text_field :name %><br />
<%= f.label :body, "Comment Description" %><br />
<%= f.text_area :body %>
<%= hidden_field_tag :post_id, @post.id %>
</p>
<p>
<%= f.submit "Add Comment" %>
</p>
<% end %>
<%= link_to t('blog.edit'), edit_panel_blog_post_path(@post) %> |
<%= link_back %>
@@ -1,16 +0,0 @@
<%=stylesheet_link_tag "NewBlog/application"%>
<div class="widget_index">
<table>
<tr>
<th><%= t('blog.title') %></th>
<th><%= t('blog.body') %></th>
</tr>
<% @posts.each do |post| %>
<tr>
<td><%= link_to post.title,panel_blog_post_path(post) %></td>
<td><%= post.body.truncate(14) %></td>
</tr>
<% end %>
</table>
</div>
@@ -1,7 +0,0 @@
<%=stylesheet_link_tag "NewBlog/application"%>
<div class="widget_latest_post">
<h2><%= @post.title %> </h2>
<p>
<%= @post.body %>
</p>
</div>
-129
View File
@@ -1,129 +0,0 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
_locale: English
add: Add
back: Back
create: Create
delete: Delete
disable: Disable
downloaded: Downloaded
download: Download
edit: Edit
enable: Enable
hide: Hide
homepage: Homepage
no_: "No"
nothing: Nothing
show: Show
sure?: Are you sure?
update: Update
yes_: "Yes"
blog:
sure?: Sure?
# admin:
# action: Action
# add_language: Add language
# admin: Admin
# action: Action
# announcement: Announcement
# asset: Asset
# attributes: Attributes
# cant_delete_self: You can not delete yourself.
# cant_revoke_self_admin: You can not revoke your admin role yourself.
# class: Class
# content: Content
# create_error_link: Error when creating link.
# create_error_page: Error when creating page.
# create_success_home: Homepage was successfully created.
# create_success_layout: Layout was successfully created.
# create_success_link: Link was successfully created.
# create_success_page: Page was successfully created.
# create_success_snippet: Snippet was successfully created.
# create_success_user: User was successfully created.
# data: Data
# delete_language: Delete language
# description: Description
# design: Design
# disable_language: Disable language
# editing_home: Editing homepage
# editing_layout: Editing layout
# editing_link: Editing link
# editing_page: Editing page
# editing_snippet: Editing snippet
# editing_user_info: Editing user information
# editing_user_role: Editing user role
# email: Email
# enable_language: Enable language
# file_name: Filename
# file_size: File size
# format: Format
# home: Home
# id: ID
# info: Information
# is_published: Is published
# item: Item
# key: Key
# language: Language
# layout: Layout
# layout_name: Layout name
# list_assets: Assets list
# list_designs: Designs list
# list_items: Items list
# list_puchases: Purchases list
# list_snippets: Snippets list
# list_users: Users list
# list_user_infos: User information list
# list_user_roles: User roles list
# member: Member
# move_down: Move down
# move_up: Move up
# multilingual: Multilingual
# my_avatar: My Avatar
# no_home_page: You don't have a homepage
# no_layout: You don't have a layout
# name: Name
# new_asset: New asset
# new_component: New component
# new_home: New homepage
# new_layout: New layout
# new_link: New link
# new_page: New page
# new_snippet: New snippet
# new_user: New user
# new_user_info: New user information
# new_user_role: New user role
# non_multilingual: Non multilingual
# options: Options
# orig_upload_file: Original filename
# position: Position
# published?: Published?
# purchase: Purchase
# registered: Registered
# role: Role
# roles: Roles
# title: Title
# translation: Translation
# type: Type
# up_to_date: Up-to-date
# update_error_link: Error when updating link.
# update_error_page: Error when updating page.
# update_success_content: Content was successfully updated.
# update_success_home: Homepage was successfully updated.
# update_success_layout: Layout was successfully updated.
# update_success_link: Link was successfully updated.
# update_success_page: Page was successfully updated.
# update_success_snippet: Snippet was successfully updated.
# update_success_user: User was successfully updated.
# url: URL
# user: User
# user_info: User information
# user_panel: User panel
# user_role: User role
panel:
-20
View File
@@ -1,20 +0,0 @@
zh_tw:
_locale: 中文
add: 新增
back: 回去
create: 創造
delete: 刪除
disable: 禁用
edit: 編輯
enable: 啟用
hide: 隱藏
homepage: 首頁
no_: "No"
nothing: 無
show: 顯示
sure?: 您肯定嗎?
update: 更新
yes_: "Yes"
-13
View File
@@ -1,13 +0,0 @@
Rails.application.routes.draw do
namespace :panel do
namespace :blog do
root :to => "posts#index"
resources :posts
resources :comments
match "widget_latest_post" => "posts#widget_latest_post"
match "widget_index" => "posts#widget_index"
end
end
end
-5
View File
@@ -1,5 +0,0 @@
require "NewBlog/engine"
module NewBlog
end
-6
View File
@@ -1,6 +0,0 @@
module NewBlog
class Engine < Rails::Engine
isolate_namespace NewBlog
PrototypeR4::Application::Orbit_Apps << "NewBlog"
end
end
-3
View File
@@ -1,3 +0,0 @@
module NewBlog
VERSION = "0.0.1"
end
-4
View File
@@ -1,4 +0,0 @@
# desc "Explaining what the task does"
# task :NewBlog do
# # Task goes here
# end
-6
View File
@@ -1,6 +0,0 @@
#!/usr/bin/env ruby
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
ENGINE_PATH = File.expand_path('../..', __FILE__)
load File.expand_path('../../test/dummy/script/rails', __FILE__)
-7
View File
@@ -1,7 +0,0 @@
require 'test_helper'
class NewBlogTest < ActiveSupport::TestCase
test "truth" do
assert_kind_of Module, NewBlog
end
end
-7
View File
@@ -1,7 +0,0 @@
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
Dummy::Application.load_tasks
@@ -1,9 +0,0 @@
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
@@ -1,7 +0,0 @@
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require_tree .
*/
@@ -1,3 +0,0 @@
class ApplicationController < ActionController::Base
protect_from_forgery
end
@@ -1,2 +0,0 @@
module ApplicationHelper
end
Whitespace-only changes.
Whitespace-only changes.
@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Dummy</title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
-4
View File
@@ -1,4 +0,0 @@
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run Dummy::Application
-46
View File
@@ -1,46 +0,0 @@
require File.expand_path('../boot', __FILE__)
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
require "sprockets/railtie" # Uncomment this line for Rails 3.1+
Bundler.require
require "NewBlog"
module Dummy
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Enable the asset pipeline
config.assets.enabled = true
end
end
-10
View File
@@ -1,10 +0,0 @@
require 'rubygems'
gemfile = File.expand_path('../../../../Gemfile', __FILE__)
if File.exist?(gemfile)
ENV['BUNDLE_GEMFILE'] = gemfile
require 'bundler'
Bundler.setup
end
$:.unshift File.expand_path('../../../../lib', __FILE__)
-25
View File
@@ -1,25 +0,0 @@
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
@@ -1,5 +0,0 @@
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
Dummy::Application.initialize!
@@ -1,27 +0,0 @@
Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Do not compress assets
config.assets.compress = false
end
@@ -1,51 +0,0 @@
Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# Code is not reloaded between requests
config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
end
@@ -1,39 +0,0 @@
Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
# Log error messages when you accidentally call methods on nil
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
end
@@ -1,7 +0,0 @@
# Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
@@ -1,10 +0,0 @@
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
@@ -1,5 +0,0 @@
# Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
@@ -1,7 +0,0 @@
# Be sure to restart your server when you modify this file.
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Dummy::Application.config.secret_token = 'd50c02c22eac460faa82296161da6222762a7baff08669429b7b14b1e80b33f14cf1e1f8daf99486dda3b4d281c73b835169269a121027552299286a818c7d03'
@@ -1,8 +0,0 @@
# Be sure to restart your server when you modify this file.
Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Dummy::Application.config.session_store :active_record_store
@@ -1,14 +0,0 @@
# Be sure to restart your server when you modify this file.
#
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
# Disable root element in JSON by default.
ActiveSupport.on_load(:active_record) do
self.include_root_in_json = false
end
@@ -1,5 +0,0 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Hello world"
-1
View File
@@ -1 +0,0 @@
../../../../../../../orbit/config/mongoid.yml
-58
View File
@@ -1,58 +0,0 @@
Dummy::Application.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
end
Whitespace-only changes.
View File
Whitespace-only changes.
-26
View File
@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>The page you were looking for doesn't exist (404)</title>
<style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
div.dialog {
width: 25em;
padding: 0 4em;
margin: 4em auto 0 auto;
border: 1px solid #ccc;
border-right-color: #999;
border-bottom-color: #999;
}
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
</style>
</head>
<body>
<!-- This file lives in public/404.html -->
<div class="dialog">
<h1>The page you were looking for doesn't exist.</h1>
<p>You may have mistyped the address or the page may have moved.</p>
</div>
</body>
</html>
-26
View File
@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>The change you wanted was rejected (422)</title>
<style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
div.dialog {
width: 25em;
padding: 0 4em;
margin: 4em auto 0 auto;
border: 1px solid #ccc;
border-right-color: #999;
border-bottom-color: #999;
}
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
</style>
</head>
<body>
<!-- This file lives in public/422.html -->
<div class="dialog">
<h1>The change you wanted was rejected.</h1>
<p>Maybe you tried to change something you didn't have access to.</p>
</div>
</body>
</html>
-26
View File
@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>We're sorry, but something went wrong (500)</title>
<style type="text/css">
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
div.dialog {
width: 25em;
padding: 0 4em;
margin: 4em auto 0 auto;
border: 1px solid #ccc;
border-right-color: #999;
border-bottom-color: #999;
}
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
</style>
</head>
<body>
<!-- This file lives in public/500.html -->
<div class="dialog">
<h1>We're sorry, but something went wrong.</h1>
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
</div>
</body>
</html>
Whitespace-only changes.
-6
View File
@@ -1,6 +0,0 @@
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
@@ -1,10 +0,0 @@
require 'test_helper'
class NavigationTest < ActionDispatch::IntegrationTest
fixtures :all
# test "the truth" do
# assert true
# end
end
-10
View File
@@ -1,10 +0,0 @@
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../dummy/config/environment.rb", __FILE__)
require "rails/test_help"
Rails.backtrace_cleaner.remove_silencers!
# Load support files
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
-4
View File
@@ -1,4 +0,0 @@
doc
*.dot
pkg
*.rbc
-42
View File
@@ -1,42 +0,0 @@
= Change Log
== edge
* Support for Rubinius [jlong]
* Support for Ruby 1.9 [aemadrid]
* More tests [aemadrid]
* Fixed issue #5 - problem with other namespace tags [jemmyw]
* Switched to Jeweler for better gem management [jlong]
* Allow operation in a threaded environment (parser per-thread, shared context)
* Allow switching scanners that tokenize templates.
* Include SquiggleScanner to parse tags that look like "{ hello /}"
== 0.6.1
* Fixed a problem with non-tags that have no prefix or tag name (see test_parse_chirpy_bird)
== 0.6.0 (private release)
* Split radius.rb into multiple files.
* Ported the really hairy regexes from Radius::Parser to a single Ragel machine.
* Added and refactored tests.
* Refactored Rakefile and other administrativia.
== 0.5.1
* Fixed a problem with parsing quotes where a single tag preceding a double tag would consume the start tag of the double tag if both contained attributes.
== 0.5.0
* Created a DSL for tag definitions (introducing a DSL makes this version of Radiant incompatible with the last). The DSL has the following features:
- full support for nested tags
- global and local tag variables
- Contexts can now be defined dynamically (instead of being subclassed)
- see the QUICKSTART for more info
* Many refactorings of the library and unit tests.
* Changed the license to the MIT-LICENSE.
* Updated documentation to reflect the changes.
* Updated the version number to reflect the maturity of the code base.
== 0.0.2
* Refactored Parser to use Context#render_tag instead of #send when rendering tags defined on a Context.
* UndefinedTagError is now thrown when Parser tries to render a tag which doesn't exist on a Context.
* Added Context#tag_missing which works like method_method missing on Object, but is tag specific.
== 0.0.1
* First release.
-19
View File
@@ -1,19 +0,0 @@
Copyright (c) 2006-2010, John W. Long
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-322
View File
@@ -1,322 +0,0 @@
= Radius Quick Start
== Defining Tags
Before you can parse a template with Radius you need to create a Context object which defines
the tags that will be used in the template. This is actually quite simple:
require 'radius'
context = Radius::Context.new
context.define_tag "hello" do |tag|
"Hello #{tag.attr['name'] || 'World'}!"
end
Once you have defined a context you can easily create a Parser:
parser = Radius::Parser.new(context)
puts parser.parse('<p><radius:hello /></p>')
puts parser.parse('<p><radius:hello name="John" /></p>')
This code will output:
<p>Hello World!</p>
<p>Hello John!</p>
Note how you can pass attributes from the template to the context using the attributes hash.
Above, the first tag that was parsed didn't have a name attribute so the code in the +hello+
tag definition uses "World" instead. The second time the tag is parsed the name attribute is
set to "John" which is used to create the string "Hello John!". Tags that do not follow this
rule will be treated as if they were undefined (like normal methods).
== Container Tags
Radius also allows you to define "container" tags. That is, tags that contain content and
that may optionally manipulate it in some way. For example, if you have RedCloth installed
you could define another tag to parse and create Textile output:
require 'redcloth'
context.define_tag "textile" do |tag|
contents = tag.expand
RedCloth.new(contents).to_html
end
(The code <tt>tag.expand</tt> above returns the contents of the template between the start and end
tags.)
With the code above your parser can easily handle Textile:
parser.parse('<radius:textile>h1. Hello **World**!</radius:textile>')
This code will output:
<h1>Hello <b>World</b>!</h1>
== Nested Tags
But wait!--it gets better. Because container tags can manipulate the content they contain
you can use them to iterate over collections:
context = Radius::Context.new
context.define_tag "stooge" do |tag|
content = ''
["Larry", "Moe", "Curly"].each do |name|
tag.locals.name = name
content << tag.expand
end
content
end
context.define_tag "stooge:name" do |tag|
tag.locals.name
end
parser = Radius::Parser.new(context)
template = <<-TEMPLATE
<ul>
<radius:stooge>
<li><radius:name /></li>
</radius:stooge>
</ul>
TEMPLATE
puts parser.parse(template)
This code will output:
<ul>
<li>Larry</li>
<li>Moe</li>
<li>Curly</li>
</ul>
Note how the definition for the +name+ tag is defined. Because "name" is prefixed
with "stooge:" the +name+ tag cannot appear outside the +stooge+ tag. Had it been defined
simply as "name" it would be valid anywhere, even outside the +stooge+ tag (which was
not what we wanted). Using the colon operator you can define tags with any amount of
nesting.
== Exposing Objects to Templates
During normal operation, you will often want to expose certain objects to your templates.
Writing the tags to do this all by hand would be cumbersome of Radius did not provide
several mechanisms to make this easier. The first is a way of exposing objects as tags
on the context object. To expose an object simply call the +define_tag+
method with the +for+ option:
context.define_tag "count", :for => 1
This would expose the object <tt>1</tt> to the template as the +count+ tag. It's basically the
equivalent of writing:
context.define_tag("count") { 1 }
So far this doesn't save you a whole lot of typing, but suppose you want to expose certain
methods that are on that object? You could do this:
context.define_tag "user", :for => user, :expose => [ :name, :age, :email ]
This will add a total of four tags to the context. One for the <tt>user</tt> variable, and
one for each of the three methods listed in the +expose+ clause. You could now get the user's
name inside your template like this:
<radius:user><radius:name /></radius:user>
If "John" was the value stored in <tt>user.name</tt> the template would render as "John".
== Tag Shorthand
In the example above we made reference to <tt>user.name</tt> in our template by using the
following code:
<radius:user><radius:name /></radius:user>
There is a much easer way to refer to the <tt>user.name</tt> variable. Use the colon operator
to "scope" the reference to <tt>name</tt>:
<radius:user:name />
Radius allows you to use this shortcut for all tags.
== Changing the Tag Prefix
By default, all Radius tags must begin with "radius". You can change this by altering the
tag_prefix attribute on a Parser. For example:
parser = Radius::Parser.new(context, :tag_prefix => 'r')
Now, when parsing templates with +parser+, Radius will require that every tag begin with "r"
instead of "radius".
== Custom Behavior for Undefined Tags
Context#tag_missing behaves much like Object#method_missing only it allows you to define
specific behavior for when a tag is not defined on a Context. For example:
class LazyContext < Radius::Context
def tag_missing(tag, attr, &block)
"<strong>ERROR: Undefined tag `#{tag}' with attributes #{attr.inspect}</strong>"
end
end
parser = Radius::Parser.new(LazyContext.new, :tag_prefix => 'lazy')
puts parser.parse('<lazy:weird value="true" />')
This will output:
<strong>ERROR: Undefined tag `weird' with attributes {"value"=>"true"}</strong>
Normally, when the Radius Parser encounters an undefined tag for a Context it raises an
UndefinedTagError, but since we have defined #tag_missing on LazyContext the Parser now
outputs a nicely formated error message when we parse a string that does not contain a
valid tag.
== Tag Bindings
Radius passes a TagBinding into the block of the Context#define_tag method. The tag
binding is useful for a number of tasks. A tag binding has an #expand instance method
which processes a tag's contents and returns the result. It also has a #attr method
which returns a hash of the attributes that were passed into the tag. TagBinding also
contains the TagBinding#single? and TagBinding#double? methods which return true or false
based on wether the tag is a container tag or not. More about the methods which are
available on tag bindings can be found on the Radius::TagBinding documentation page.
== Tag Binding Locals, Globals, and Context Sensitive Tags
A TagBinding also contains two OpenStruct-like objects which are useful when developing
tags. TagBinding#globals is useful for storing variables which you would like to be
accessible to all tags:
context.define_tag "inc" do |tag|
tag.globals.count ||= 0
tag.globals.count += 1
""
end
context.define_tag "count" do |tag|
tag.globals.count || 0
end
TagBinding#locals mirrors the variables that are in TagBinding#globals, but allows child
tags to redefine variables. This is valuable when defining context sensitive tags:
class Person
attr_accessor :name, :friend
def initialize(name)
@name = name
end
end
jack = Person.new('Jack')
jill = Person.new('Jill')
jack.friend = jill
jill.friend = jack
context = Radius::Context.new do |c|
c.define_tag "jack" do |tag|
tag.locals.person = jack
tag.expand
end
c.define_tag "jill" do |tag|
tag.locals.person = jill
tag.expand
end
c.define_tag "name" do |tag|
tag.locals.person.name rescue tag.missing!
end
c.define_tag "friend" do |tag|
tag.locals.person = tag.locals.person.friend rescue tag.missing!
tag.expand
end
end
parser = Radius::Parser.new(context, :tag_prefix => 'r')
parser.parse('<r:jack:name />') #=> "Jack"
parser.parse('<r:jill:name />') #=> "Jill"
parser.parse('<r:jill:friend:name />') #=> "Jack"
parser.parse('<r:jack:friend:friend:name />') #=> "Jack"
parser.parse('<r:jill><r:friend:name /> and <r:name /></r:jill>') #=> "Jack and Jill"
parser.parse('<r:name />') # raises a Radius::UndefinedTagError exception
Notice how TagBinding#locals enables intelligent nesting. "<r:jill:name />" evaluates to
"Jill", but "<r:jill:friend:name />" evaluates to "Jack". Locals lose scope as soon as
the tag they were defined in closes. Globals on the other hand, never lose scope.
The final line in the example above demonstrates that calling "<r:name />" raises a
TagMissing error. This is because of the way the name tag was defined:
tag.locals.person.name rescue tag.missing!
If person is not defined on locals it will return nil. Calling #name on nil would normally
raise a NoMethodError exception, but because of the 'rescue' clause the TagBinding#missing!
method is called which fires off Context#tag_missing. By default Context#tag_missing raises
a UndefinedTagError exception. The 'rescue tag.missing!' idiom is extremly useful for adding
simple error checking to context sensitive tags.
== Tag Specificity
When Radius is presented with two tags that have the same name, but different nesting
Radius uses an algorithm similar to the way winning rules are calculated in Cascading Style
Sheets (CSS) to determine which definition should be used. Each time a tag is encountered
in a template potential tags are assigned specificity values and the tag with the highest
specificity wins.
For example, given the following tag definitions:
nesting
extra:nesting
parent:child:nesting
And template:
<r:parent:extra:child:nesting />
Radius will calculate specificity values like this:
nesting => 1.0.0.0
extra:nesting => 1.0.1.0
parent:child:nesting => 1.1.0.1
Meaning that parent:child:nesting will win. If a template contained:
<r:parent:child:extra:nesting />
The following specificity values would be assigned to each of the tag definitions:
nesting => 1.0.0.0
extra:nesting => 1.1.0.0
parent:child:nesting => 1.0.1.1
Meaning that extra:nesting would win because it is more "specific".
Values are assigned by assigning points to each of the tags from right to left.
Given a tag found in a template with nesting four levels deep, the maximum
specificity a tag could be assigned would be:
1.1.1.1
One point for each of the levels.
In practice, you don't need to understand this topic to be effective with Radius.
For the most part you will find that Radius resolves tags precisely the way that
you would expect. If you find this section confusing forget about it and refer
back to it if you find that tags are resolving differently from the way that you
expected.
-100
View File
@@ -1,100 +0,0 @@
= Radius -- Powerful Tag-Based Templates
Radius is a powerful tag-based template language for Ruby inspired by the
template languages used in MovableType[http://www.movabletype.org] and
TextPattern[http://www.textpattern.com]. It uses tags similar to XML, but can
be used to generate any form of plain text (HTML, e-mail, etc...).
== Usage
With Radius, it is extremely easy to create custom tags and parse them. Here's a small
example:
require 'radius'
# Define tags on a context that will be available to a template:
context = Radius::Context.new do |c|
c.define_tag 'hello' do
'Hello world'
end
c.define_tag 'repeat' do |tag|
number = (tag.attr['times'] || '1').to_i
result = ''
number.times { result << tag.expand }
result
end
end
# Create a parser to parse tags that begin with 'r:'
parser = Radius::Parser.new(context, :tag_prefix => 'r')
# Parse tags and output the result
puts parser.parse(%{A small example:\n<r:repeat times="3">* <r:hello />!\n</r:repeat>})
Output:
A small example:
* Hello world!
* Hello world!
* Hello world!
== Quick Start
Read the QUICKSTART file to get up and running with Radius.
== Requirements
Radius does not have any external requirements for using the library in your
own programs.
Ragel is required to create the ruby parser from the Ragel specification,
and both Ragel and Graphviz are required to draw the state graph for the
parser.
== Installation
It is recommended that you install Radius using the RubyGems packaging system:
% gem install --remote radius
== License
Radius is released under the MIT license and is copyright (c) 2006-2010
John W. Long. A copy of the MIT license can be found in the LICENSE file.
== Roadmap
This is a prioritized roadmap for future releases:
1. Clean up the current code base. [Done]
2. Add support for multi-level contexts: tags should be able to be
defined to only be valid within other sets of tags. [Done]
3. Create a simple DSL for defining contexts. [Done]
4. Optimize for speed, modify scan.rl to emit C.
== Development
The latest version of Radius can be found on RubyForge:
http://rubyforge.org/projects/radius
Experimental and development versions of Radius can be found on Github:
http://github.com/jlong/radius
If you are interested in helping with the development of Radius, feel free to
fork the project on GitHub and send me a pull request.
John Long ::
http://wiseheartdesign.com
-8
View File
@@ -1,8 +0,0 @@
require 'rubygems'
require 'rake'
require File.dirname(__FILE__) + '/lib/radius/version'
Dir['tasks/**/*.rake'].each { |t| load t }
task :default => :test
-1
View File
@@ -1 +0,0 @@
0.7.0.prerelease␍
-11
View File
@@ -1,11 +0,0 @@
require 'radius/version'
require 'radius/error'
require 'radius/tag_definitions'
require 'radius/delegating_open_struct'
require 'radius/tag_binding'
require 'radius/context'
require 'radius/parse_tag'
require 'radius/ord_string'
require 'radius/parser/scanner'
require 'radius/parser'
require 'radius/utility'
-147
View File
@@ -1,147 +0,0 @@
module Radius
#
# A context contains the tag definitions which are available for use in a template.
# See the QUICKSTART for a detailed explaination its
# usage.
#
class Context
# A hash of tag definition blocks that define tags accessible on a Context.
attr_accessor :definitions # :nodoc:
attr_accessor :globals # :nodoc:
# Creates a new Context object.
def initialize(&block)
@definitions = {}
@tag_binding_stack = []
@globals = DelegatingOpenStruct.new
with(&block) if block_given?
end
# Yield an instance of self for tag definitions:
#
# context.with do |c|
# c.define_tag 'test' do
# 'test'
# end
# end
#
def with
yield self
self
end
# Creates a tag definition on a context. Several options are available to you
# when creating a tag:
#
# +for+:: Specifies an object that the tag is in reference to. This is
# applicable when a block is not passed to the tag, or when the
# +expose+ option is also used.
#
# +expose+:: Specifies that child tags should be set for each of the methods
# contained in this option. May be either a single symbol/string or
# an array of symbols/strings.
#
# +attributes+:: Specifies whether or not attributes should be exposed
# automatically. Useful for ActiveRecord objects. Boolean. Defaults
# to +true+.
#
def define_tag(name, options = {}, &block)
type = Utility.impartial_hash_delete(options, :type).to_s
klass = Utility.constantize('Radius::TagDefinitions::' + Utility.camelize(type) + 'TagFactory') rescue raise(ArgumentError.new("Undefined type `#{type}' in options hash"))
klass.new(self).define_tag(name, options, &block)
end
# Returns the value of a rendered tag. Used internally by Parser#parse.
def render_tag(name, attributes = {}, &block)
if name =~ /^(.+?):(.+)$/
render_tag($1) { render_tag($2, attributes, &block) }
else
tag_definition_block = @definitions[qualified_tag_name(name.to_s)]
if tag_definition_block
stack(name, attributes, block) do |tag|
tag_definition_block.call(tag).to_s
end
else
tag_missing(name, attributes, &block)
end
end
end
# Like method_missing for objects, but fired when a tag is undefined.
# Override in your own Context to change what happens when a tag is
# undefined. By default this method raises an UndefinedTagError.
def tag_missing(name, attributes, &block)
raise UndefinedTagError.new(name)
end
# Returns the state of the current render stack. Useful from inside
# a tag definition. Normally just use TagBinding#nesting.
def current_nesting
@tag_binding_stack.collect { |tag| tag.name }.join(':')
end
# make a usable copy of this context
def dup # :nodoc:
rv = self.class.new
rv.globals = globals.dup
rv.definitions = definitions.dup
rv
end
private
# A convienence method for managing the various parts of the
# tag binding stack.
def stack(name, attributes, block)
previous = @tag_binding_stack.last
previous_locals = previous.nil? ? globals : previous.locals
locals = DelegatingOpenStruct.new(previous_locals)
binding = TagBinding.new(self, locals, name, attributes, block)
@tag_binding_stack.push(binding)
result = yield(binding)
@tag_binding_stack.pop
result
end
# Returns a fully qualified tag name based on state of the
# tag binding stack.
def qualified_tag_name(name)
nesting_parts = @tag_binding_stack.collect { |tag| tag.name }
nesting_parts << name unless nesting_parts.last == name
specific_name = nesting_parts.join(':') # specific_name always has the highest specificity
unless @definitions.has_key? specific_name
possible_matches = @definitions.keys.grep(/(^|:)#{name}$/)
specificity = possible_matches.inject({}) { |hash, tag| hash[numeric_specificity(tag, nesting_parts)] = tag; hash }
max = specificity.keys.max
if max != 0
specificity[max]
else
name
end
else
specific_name
end
end
# Returns the specificity for +tag_name+ at nesting defined
# by +nesting_parts+ as a number.
def numeric_specificity(tag_name, nesting_parts)
nesting_parts = nesting_parts.dup
name_parts = tag_name.split(':')
specificity = 0
value = 1
if nesting_parts.last == name_parts.last
while nesting_parts.size > 0
if nesting_parts.last == name_parts.last
specificity += value
name_parts.pop
end
nesting_parts.pop
value *= 0.1
end
specificity = 0 if (name_parts.size > 0)
end
specificity
end
end
end
@@ -1,37 +0,0 @@
module Radius
class DelegatingOpenStruct # :nodoc:
attr_accessor :object
def initialize(object = nil)
@object = object
@hash = {}
end
def dup
rv = self.class.new
rv.instance_variable_set(:@hash, @hash.dup)
rv
end
def method_missing(method, *args, &block)
symbol = (method.to_s =~ /^(.*?)=$/) ? $1.intern : method
if (0..1).include?(args.size)
if args.size == 1
@hash[symbol] = args.first
else
if @hash.has_key?(symbol)
@hash[symbol]
else
unless object.nil?
@object.send(method, *args, &block)
else
nil
end
end
end
else
super
end
end
end
end
-43
View File
@@ -1,43 +0,0 @@
module Radius
# Abstract base class for all parsing errors.
class ParseError < StandardError
end
# Occurs when the Parser expects an end tag for one tag and finds the end tag for another.
class WrongEndTagError < ParseError
def initialize(expected_tag, got_tag, stack)
stack_message = " with stack #{stack.inspect}" if stack
super("wrong end tag `#{got_tag}' found for start tag `#{expected_tag}'#{stack_message}")
end
end
# Occurs when Parser cannot find an end tag for a given tag in a template or when
# tags are miss-matched in a template.
class MissingEndTagError < ParseError
# Create a new MissingEndTagError object for +tag_name+.
def initialize(tag_name, stack)
stack_message = " with stack #{stack.inspect}" if stack
super("end tag not found for start tag `#{tag_name}'#{stack_message}")
end
end
# Occurs when Context#render_tag cannot find the specified tag on a Context.
class UndefinedTagError < ParseError
# Create a new UndefinedTagError object for +tag_name+.
def initialize(tag_name)
super("undefined tag `#{tag_name}'")
end
end
class TastelessTagError < ParseError #:nodoc:
def initialize(tag, stack)
super("internal error with tasteless tag #{tag.inspect} and stack #{stack.inspect}")
end
end
class UndefinedFlavorError < ParseError #:nodoc:
def initialize(tag, stack)
super("internal error with unknown flavored tag #{tag.inspect} and stack #{stack.inspect}")
end
end
end
-13
View File
@@ -1,13 +0,0 @@
module Radius
class OrdString < String
if RUBY_VERSION[0,3] == '1.9'
def [](*args)
if args.size == 1 && args.first.is_a?(Integer)
slice(args.first).ord
else
super
end
end
end
end
end
-24
View File
@@ -1,24 +0,0 @@
module Radius
class ParseTag # :nodoc:
def initialize(&b)
@block = b
end
def on_parse(&b)
@block = b
end
def to_s
@block.call(self) if @block
end
end
class ParseContainerTag < ParseTag # :nodoc:
attr_accessor :name, :attributes, :contents
def initialize(name = "", attributes = {}, contents = [], &b)
@name, @attributes, @contents = name, attributes, contents
super(&b)
end
end
end
-79
View File
@@ -1,79 +0,0 @@
module Radius
#
# The Radius parser. Initialize a parser with a Context object that
# defines how tags should be expanded. See the QUICKSTART[link:files/QUICKSTART.html]
# for a detailed explaination of its usage.
#
class Parser
# The Context object used to expand template tags.
attr_accessor :context
# The string that prefixes all tags that are expanded by a parser
# (the part in the tag name before the first colon).
attr_accessor :tag_prefix
# The class that performs tokenization of the input string
attr_accessor :scanner
# Creates a new parser object initialized with a Context.
def initialize(context = Context.new, options = {})
if context.kind_of?(Hash) and options.empty?
options, context = context, (context[:context] || context['context'])
end
options = Utility.symbolize_keys(options)
self.context = context ? context.dup : Context.new
self.tag_prefix = options[:tag_prefix] || 'radius'
self.scanner = options[:scanner] || default_scanner
end
# Parses string for tags, expands them, and returns the result.
def parse(string)
@stack = [ ParseContainerTag.new { |t| Utility.array_to_s(t.contents) } ]
tokenize(string)
stack_up
@stack.last.to_s
end
protected
# Convert the string into a list of text blocks and scanners (tokens)
def tokenize(string)
@tokens = scanner.operate(tag_prefix, string)
end
def stack_up
@tokens.each do |t|
if t.is_a? String
@stack.last.contents << t
next
end
case t[:flavor]
when :open
@stack.push(ParseContainerTag.new(t[:name], t[:attrs]))
when :self
@stack.last.contents << ParseTag.new {@context.render_tag(t[:name], t[:attrs])}
when :close
popped = @stack.pop
raise WrongEndTagError.new(popped.name, t[:name], @stack) if popped.name != t[:name]
popped.on_parse { |b| @context.render_tag(popped.name, popped.attributes) { Utility.array_to_s(b.contents) } }
@stack.last.contents << popped
when :tasteless
raise TastelessTagError.new(t, @stack)
else
raise UndefinedFlavorError.new(t, @stack)
end
end
raise MissingEndTagError.new(@stack.last.name, @stack) if @stack.length != 1
end
def default_scanner
if RUBY_PLATFORM == 'java'
require 'java'
require 'radius/parser/java_scanner.jar'
::Radius.send(:include_package, 'radius.parser')
Radius::JavaScanner.new(JRuby.runtime)
else
Radius::Scanner.new
end
end
end
end
Binary file not shown.
Binary file not shown.
Binary file not shown.
-634
View File
@@ -1,634 +0,0 @@
// line 1 "JavaScanner.rl"
// line 84 "JavaScanner.rl"
package radius.parser;
import java.util.HashMap;
import java.util.LinkedList;
import org.jruby.Ruby; // runtime
import org.jruby.RubyObject;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.RubyArray;
import org.jruby.RubyString;
import org.jruby.RubyHash;
import org.jruby.RubySymbol;
public class JavaScanner {
Ruby runtime = null;
RubyArray rv = null;
void pass_through(String str) {
RubyObject last = ((RubyObject)rv.last());
if ( rv.size() > 0 && last != null && (last instanceof RubyString) ){
// XXX concat changes for ruby 1.9
((RubyString) last).concat(RubyString.newString(runtime, str));
} else {
rv.append(RubyString.newString(runtime, str));
}
}
void tag(String prefix, String name, RubyHash attr, RubySymbol flavor) {
RubyHash tag = RubyHash.newHash(runtime);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "prefix"),
RubyString.newString(runtime, prefix)
);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "name"),
RubyString.newString(runtime, name)
);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "attrs"),
attr
);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "flavor"),
flavor
);
rv.append(tag);
}
public JavaScanner(Ruby runtime) {
this.runtime = runtime;
}
// line 65 "JavaScanner.java"
private static byte[] init__parser_actions_0()
{
return new byte [] {
0, 1, 0, 1, 3, 1, 4, 1, 5, 1, 6, 1,
7, 1, 8, 1, 9, 1, 10, 1, 14, 1, 15, 1,
19, 1, 21, 1, 22, 1, 23, 2, 1, 2, 2, 5,
6, 2, 6, 7, 2, 9, 5, 2, 9, 10, 2, 10,
9, 2, 11, 20, 2, 12, 20, 2, 13, 20, 2, 16,
17, 2, 16, 18, 3, 5, 6, 7, 3, 9, 5, 6,
3, 16, 6, 17, 4, 9, 5, 6, 7, 4, 16, 5,
6, 17, 5, 16, 9, 5, 6, 17
};
}
private static final byte _parser_actions[] = init__parser_actions_0();
private static short[] init__parser_key_offsets_0()
{
return new short [] {
0, 0, 11, 21, 34, 47, 61, 65, 70, 72, 74, 87,
100, 101, 103, 118, 133, 149, 155, 161, 176, 179, 182, 185,
200, 202, 204, 219, 235, 241, 247, 250, 253, 269, 285, 302,
309, 315, 331, 335, 351, 366, 369, 371, 381, 392, 402, 416,
420, 420, 421, 430, 430, 430, 432, 434, 437, 440, 442, 444
};
}
private static final short _parser_key_offsets[] = init__parser_key_offsets_0();
private static char[] init__parser_trans_keys_0()
{
return new char [] {
58, 63, 95, 45, 46, 48, 57, 65, 90, 97, 122, 63,
95, 45, 46, 48, 58, 65, 90, 97, 122, 32, 47, 62,
63, 95, 9, 13, 45, 58, 65, 90, 97, 122, 32, 47,
62, 63, 95, 9, 13, 45, 58, 65, 90, 97, 122, 32,
61, 63, 95, 9, 13, 45, 46, 48, 58, 65, 90, 97,
122, 32, 61, 9, 13, 32, 34, 39, 9, 13, 34, 92,
34, 92, 32, 47, 62, 63, 95, 9, 13, 45, 58, 65,
90, 97, 122, 32, 47, 62, 63, 95, 9, 13, 45, 58,
65, 90, 97, 122, 62, 34, 92, 32, 34, 47, 62, 63,
92, 95, 9, 13, 45, 58, 65, 90, 97, 122, 32, 34,
47, 62, 63, 92, 95, 9, 13, 45, 58, 65, 90, 97,
122, 32, 34, 61, 63, 92, 95, 9, 13, 45, 46, 48,
58, 65, 90, 97, 122, 32, 34, 61, 92, 9, 13, 32,
34, 39, 92, 9, 13, 32, 34, 47, 62, 63, 92, 95,
9, 13, 45, 58, 65, 90, 97, 122, 34, 62, 92, 34,
39, 92, 34, 39, 92, 32, 39, 47, 62, 63, 92, 95,
9, 13, 45, 58, 65, 90, 97, 122, 39, 92, 39, 92,
32, 39, 47, 62, 63, 92, 95, 9, 13, 45, 58, 65,
90, 97, 122, 32, 39, 61, 63, 92, 95, 9, 13, 45,
46, 48, 58, 65, 90, 97, 122, 32, 39, 61, 92, 9,
13, 32, 34, 39, 92, 9, 13, 34, 39, 92, 34, 39,
92, 32, 34, 39, 47, 62, 63, 92, 95, 9, 13, 45,
58, 65, 90, 97, 122, 32, 34, 39, 47, 62, 63, 92,
95, 9, 13, 45, 58, 65, 90, 97, 122, 32, 34, 39,
61, 63, 92, 95, 9, 13, 45, 46, 48, 58, 65, 90,
97, 122, 32, 34, 39, 61, 92, 9, 13, 32, 34, 39,
92, 9, 13, 32, 34, 39, 47, 62, 63, 92, 95, 9,
13, 45, 58, 65, 90, 97, 122, 34, 39, 62, 92, 32,
34, 39, 47, 62, 63, 92, 95, 9, 13, 45, 58, 65,
90, 97, 122, 32, 39, 47, 62, 63, 92, 95, 9, 13,
45, 58, 65, 90, 97, 122, 39, 62, 92, 39, 92, 63,
95, 45, 46, 48, 57, 65, 90, 97, 122, 58, 63, 95,
45, 46, 48, 57, 65, 90, 97, 122, 63, 95, 45, 46,
48, 58, 65, 90, 97, 122, 32, 62, 63, 95, 9, 13,
45, 46, 48, 58, 65, 90, 97, 122, 32, 62, 9, 13,
60, 47, 63, 95, 45, 57, 65, 90, 97, 122, 34, 92,
34, 92, 34, 39, 92, 34, 39, 92, 39, 92, 39, 92,
0
};
}
private static final char _parser_trans_keys[] = init__parser_trans_keys_0();
private static byte[] init__parser_single_lengths_0()
{
return new byte [] {
0, 3, 2, 5, 5, 4, 2, 3, 2, 2, 5, 5,
1, 2, 7, 7, 6, 4, 4, 7, 3, 3, 3, 7,
2, 2, 7, 6, 4, 4, 3, 3, 8, 8, 7, 5,
4, 8, 4, 8, 7, 3, 2, 2, 3, 2, 4, 2,
0, 1, 3, 0, 0, 2, 2, 3, 3, 2, 2, 0
};
}
private static final byte _parser_single_lengths[] = init__parser_single_lengths_0();
private static byte[] init__parser_range_lengths_0()
{
return new byte [] {
0, 4, 4, 4, 4, 5, 1, 1, 0, 0, 4, 4,
0, 0, 4, 4, 5, 1, 1, 4, 0, 0, 0, 4,
0, 0, 4, 5, 1, 1, 0, 0, 4, 4, 5, 1,
1, 4, 0, 4, 4, 0, 0, 4, 4, 4, 5, 1,
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
}
private static final byte _parser_range_lengths[] = init__parser_range_lengths_0();
private static short[] init__parser_index_offsets_0()
{
return new short [] {
0, 0, 8, 15, 25, 35, 45, 49, 54, 57, 60, 70,
80, 82, 85, 97, 109, 121, 127, 133, 145, 149, 153, 157,
169, 172, 175, 187, 199, 205, 211, 215, 219, 232, 245, 258,
265, 271, 284, 289, 302, 314, 318, 321, 328, 336, 343, 353,
357, 358, 360, 367, 368, 369, 372, 375, 379, 383, 386, 389
};
}
private static final short _parser_index_offsets[] = init__parser_index_offsets_0();
private static byte[] init__parser_indicies_0()
{
return new byte [] {
2, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3,
3, 3, 0, 4, 6, 7, 5, 5, 4, 5, 5, 5,
0, 8, 10, 11, 9, 9, 8, 9, 9, 9, 0, 13,
15, 14, 14, 13, 14, 14, 14, 14, 12, 16, 17, 16,
12, 17, 18, 19, 17, 12, 21, 22, 20, 24, 25, 23,
26, 28, 29, 27, 27, 26, 27, 27, 27, 12, 30, 32,
33, 31, 31, 30, 31, 31, 31, 12, 34, 12, 35, 25,
23, 36, 24, 38, 39, 37, 25, 37, 36, 37, 37, 37,
23, 40, 24, 42, 43, 41, 25, 41, 40, 41, 41, 41,
23, 44, 24, 46, 45, 25, 45, 44, 45, 45, 45, 45,
23, 47, 24, 48, 25, 47, 23, 48, 49, 50, 25, 48,
23, 51, 21, 53, 54, 52, 22, 52, 51, 52, 52, 52,
20, 24, 55, 25, 23, 57, 58, 59, 56, 61, 35, 62,
60, 64, 24, 66, 67, 65, 68, 65, 64, 65, 65, 65,
63, 24, 68, 63, 61, 68, 63, 69, 24, 71, 72, 70,
68, 70, 69, 70, 70, 70, 63, 73, 24, 75, 74, 68,
74, 73, 74, 74, 74, 74, 63, 76, 24, 77, 68, 76,
63, 77, 78, 79, 68, 77, 63, 80, 58, 59, 56, 81,
81, 62, 60, 82, 61, 35, 84, 85, 83, 62, 83, 82,
83, 83, 83, 60, 86, 61, 35, 88, 89, 87, 62, 87,
86, 87, 87, 87, 60, 90, 61, 35, 92, 91, 62, 91,
90, 91, 91, 91, 91, 60, 93, 61, 35, 94, 62, 93,
60, 94, 95, 96, 62, 94, 60, 97, 80, 58, 99, 100,
98, 59, 98, 97, 98, 98, 98, 56, 61, 35, 101, 62,
60, 97, 57, 58, 99, 100, 98, 59, 98, 97, 98, 98,
98, 56, 103, 21, 105, 106, 104, 107, 104, 103, 104, 104,
104, 102, 24, 108, 68, 63, 21, 107, 102, 109, 109, 109,
109, 109, 109, 0, 111, 110, 110, 110, 110, 110, 110, 0,
112, 112, 112, 112, 112, 112, 0, 113, 115, 114, 114, 113,
114, 114, 114, 114, 0, 116, 117, 116, 0, 118, 120, 119,
123, 122, 122, 122, 122, 122, 121, 124, 125, 24, 25, 23,
24, 25, 23, 61, 35, 62, 60, 61, 35, 62, 60, 24,
68, 63, 24, 68, 63, 126, 0
};
}
private static final byte _parser_indicies[] = init__parser_indicies_0();
private static byte[] init__parser_trans_targs_0()
{
return new byte [] {
49, 1, 2, 3, 4, 3, 12, 52, 4, 5, 12, 52,
49, 6, 5, 7, 6, 7, 8, 42, 9, 10, 13, 9,
10, 13, 11, 5, 12, 52, 11, 5, 12, 52, 51, 14,
15, 16, 20, 54, 15, 16, 20, 54, 17, 16, 18, 17,
18, 19, 21, 15, 16, 20, 54, 53, 22, 23, 14, 31,
22, 23, 31, 24, 26, 27, 41, 58, 25, 26, 27, 41,
58, 28, 27, 29, 28, 29, 30, 40, 23, 32, 33, 34,
38, 56, 33, 34, 38, 56, 35, 34, 36, 35, 36, 37,
39, 33, 34, 38, 56, 55, 24, 26, 27, 41, 58, 25,
57, 44, 44, 45, 46, 47, 46, 59, 47, 59, 0, 49,
50, 49, 1, 43, 49, 49, 49
};
}
private static final byte _parser_trans_targs[] = init__parser_trans_targs_0();
private static byte[] init__parser_trans_actions_0()
{
return new byte [] {
27, 0, 31, 3, 5, 0, 5, 5, 0, 11, 0, 0,
29, 13, 0, 13, 0, 0, 0, 0, 15, 43, 15, 0,
17, 0, 7, 64, 34, 34, 0, 37, 9, 9, 0, 17,
7, 64, 34, 81, 0, 37, 9, 72, 13, 0, 13, 0,
0, 17, 0, 40, 76, 68, 86, 58, 15, 46, 43, 15,
0, 17, 0, 0, 7, 64, 34, 81, 0, 0, 37, 9,
72, 13, 0, 13, 0, 0, 0, 17, 43, 17, 7, 64,
34, 81, 0, 37, 9, 72, 13, 0, 13, 0, 0, 17,
17, 40, 76, 68, 86, 58, 15, 40, 76, 68, 86, 15,
58, 1, 0, 31, 3, 5, 0, 5, 0, 0, 0, 23,
61, 25, 1, 0, 52, 49, 55
};
}
private static final byte _parser_trans_actions[] = init__parser_trans_actions_0();
private static byte[] init__parser_to_state_actions_0()
{
return new byte [] {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
}
private static final byte _parser_to_state_actions[] = init__parser_to_state_actions_0();
private static byte[] init__parser_from_state_actions_0()
{
return new byte [] {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
}
private static final byte _parser_from_state_actions[] = init__parser_from_state_actions_0();
private static short[] init__parser_eof_trans_0()
{
return new short [] {
0, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1,
0, 0, 122, 125, 126, 125, 126, 125, 126, 125, 126, 127
};
}
private static final short _parser_eof_trans[] = init__parser_eof_trans_0();
static final int parser_start = 49;
static final int parser_first_final = 49;
static final int parser_error = 0;
static final int parser_en_Closeout = 48;
static final int parser_en_main = 49;
// line 143 "JavaScanner.rl"
public RubyArray operate(String tag_prefix, String input) {
char[] data = input.toCharArray();
String disposable_string;
String name = "";
String prefix = "";
RubySymbol flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
RubyHash attributes = RubyHash.newHash(runtime);
int tagstart = 0;
int mark_pfx = 0;
int mark_stg = 0;
int mark_attr = 0;
int mark_nat = 0;
int mark_vat = 0;
String nat = "";
String vat = "";
int cs;
int p = 0;
int pe = data.length;
int eof = pe;
int act;
int ts;
int te;
rv = RubyArray.newArray(runtime);
char[] remainder = data;
// line 351 "JavaScanner.java"
{
cs = parser_start;
ts = -1;
te = -1;
act = 0;
}
// line 175 "JavaScanner.rl"
// line 361 "JavaScanner.java"
{
int _klen;
int _trans = 0;
int _acts;
int _nacts;
int _keys;
int _goto_targ = 0;
_goto: while (true) {
switch ( _goto_targ ) {
case 0:
if ( p == pe ) {
_goto_targ = 4;
continue _goto;
}
if ( cs == 0 ) {
_goto_targ = 5;
continue _goto;
}
case 1:
_acts = _parser_from_state_actions[cs];
_nacts = (int) _parser_actions[_acts++];
while ( _nacts-- > 0 ) {
switch ( _parser_actions[_acts++] ) {
case 15:
// line 1 "NONE"
{ts = p;}
break;
// line 390 "JavaScanner.java"
}
}
_match: do {
_keys = _parser_key_offsets[cs];
_trans = _parser_index_offsets[cs];
_klen = _parser_single_lengths[cs];
if ( _klen > 0 ) {
int _lower = _keys;
int _mid;
int _upper = _keys + _klen - 1;
while (true) {
if ( _upper < _lower )
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( data[p] < _parser_trans_keys[_mid] )
_upper = _mid - 1;
else if ( data[p] > _parser_trans_keys[_mid] )
_lower = _mid + 1;
else {
_trans += (_mid - _keys);
break _match;
}
}
_keys += _klen;
_trans += _klen;
}
_klen = _parser_range_lengths[cs];
if ( _klen > 0 ) {
int _lower = _keys;
int _mid;
int _upper = _keys + (_klen<<1) - 2;
while (true) {
if ( _upper < _lower )
break;
_mid = _lower + (((_upper-_lower) >> 1) & ~1);
if ( data[p] < _parser_trans_keys[_mid] )
_upper = _mid - 2;
else if ( data[p] > _parser_trans_keys[_mid+1] )
_lower = _mid + 2;
else {
_trans += ((_mid - _keys)>>1);
break _match;
}
}
_trans += _klen;
}
} while (false);
_trans = _parser_indicies[_trans];
case 3:
cs = _parser_trans_targs[_trans];
if ( _parser_trans_actions[_trans] != 0 ) {
_acts = _parser_trans_actions[_trans];
_nacts = (int) _parser_actions[_acts++];
while ( _nacts-- > 0 )
{
switch ( _parser_actions[_acts++] )
{
case 0:
// line 4 "JavaScanner.rl"
{ mark_pfx = p; }
break;
case 1:
// line 5 "JavaScanner.rl"
{
prefix = input.substring(mark_pfx, p);
}
break;
case 2:
// line 8 "JavaScanner.rl"
{
if ( !prefix.equals(tag_prefix) ) {
// have to manually add ':' / Sep
// pass the text through & reset state
pass_through(input.substring(tagstart, p) + ":");
prefix = "";
{cs = 49; _goto_targ = 2; if (true) continue _goto;}
}
}
break;
case 3:
// line 18 "JavaScanner.rl"
{ mark_stg = p; }
break;
case 4:
// line 19 "JavaScanner.rl"
{ name = input.substring(mark_stg, p); }
break;
case 5:
// line 20 "JavaScanner.rl"
{ mark_attr = p; }
break;
case 6:
// line 21 "JavaScanner.rl"
{
attributes.op_aset(
runtime.getCurrentContext(),
RubyString.newString(runtime, nat),
RubyString.newString(runtime, vat)
);
}
break;
case 7:
// line 29 "JavaScanner.rl"
{ mark_nat = p; }
break;
case 8:
// line 30 "JavaScanner.rl"
{ nat = input.substring(mark_nat, p); }
break;
case 9:
// line 31 "JavaScanner.rl"
{ mark_vat = p; }
break;
case 10:
// line 32 "JavaScanner.rl"
{ vat = input.substring(mark_vat, p); }
break;
case 11:
// line 34 "JavaScanner.rl"
{ flavor = RubySymbol.newSymbol(runtime, "open".intern()); }
break;
case 12:
// line 35 "JavaScanner.rl"
{ flavor = RubySymbol.newSymbol(runtime, "self".intern()); }
break;
case 13:
// line 36 "JavaScanner.rl"
{ flavor = RubySymbol.newSymbol(runtime, "close".intern()); }
break;
case 16:
// line 1 "NONE"
{te = p+1;}
break;
case 17:
// line 72 "JavaScanner.rl"
{act = 1;}
break;
case 18:
// line 79 "JavaScanner.rl"
{act = 2;}
break;
case 19:
// line 79 "JavaScanner.rl"
{te = p+1;{
pass_through(input.substring(p, p + 1));
tagstart = p + 1;
}}
break;
case 20:
// line 72 "JavaScanner.rl"
{te = p;p--;{
tag(prefix, name, attributes, flavor);
prefix = "";
name = "";
attributes = RubyHash.newHash(runtime);
flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
}}
break;
case 21:
// line 79 "JavaScanner.rl"
{te = p;p--;{
pass_through(input.substring(p, p + 1));
tagstart = p + 1;
}}
break;
case 22:
// line 79 "JavaScanner.rl"
{{p = ((te))-1;}{
pass_through(input.substring(p, p + 1));
tagstart = p + 1;
}}
break;
case 23:
// line 1 "NONE"
{ switch( act ) {
case 1:
{{p = ((te))-1;}
tag(prefix, name, attributes, flavor);
prefix = "";
name = "";
attributes = RubyHash.newHash(runtime);
flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
}
break;
case 2:
{{p = ((te))-1;}
pass_through(input.substring(p, p + 1));
tagstart = p + 1;
}
break;
}
}
break;
// line 590 "JavaScanner.java"
}
}
}
case 2:
_acts = _parser_to_state_actions[cs];
_nacts = (int) _parser_actions[_acts++];
while ( _nacts-- > 0 ) {
switch ( _parser_actions[_acts++] ) {
case 14:
// line 1 "NONE"
{ts = -1;}
break;
// line 604 "JavaScanner.java"
}
}
if ( cs == 0 ) {
_goto_targ = 5;
continue _goto;
}
if ( ++p != pe ) {
_goto_targ = 1;
continue _goto;
}
case 4:
if ( p == eof )
{
if ( _parser_eof_trans[cs] > 0 ) {
_trans = _parser_eof_trans[cs] - 1;
_goto_targ = 3;
continue _goto;
}
}
case 5:
}
break; }
}
// line 176 "JavaScanner.rl"
return rv;
}
}
-179
View File
@@ -1,179 +0,0 @@
%%{
machine parser;
action _prefix { mark_pfx = p; }
action prefix {
prefix = input.substring(mark_pfx, p);
}
action _check_prefix {
if ( !prefix.equals(tag_prefix) ) {
// have to manually add ':' / Sep
// pass the text through & reset state
pass_through(input.substring(tagstart, p) + ":");
prefix = "";
fgoto main;
}
}
action _starttag { mark_stg = p; }
action starttag { name = input.substring(mark_stg, p); }
action _attr { mark_attr = p; }
action attr {
attributes.op_aset(
runtime.getCurrentContext(),
RubyString.newString(runtime, nat),
RubyString.newString(runtime, vat)
);
}
action _nameattr { mark_nat = p; }
action nameattr { nat = input.substring(mark_nat, p); }
action _valattr { mark_vat = p; }
action valattr { vat = input.substring(mark_vat, p); }
action opentag { flavor = RubySymbol.newSymbol(runtime, "open".intern()); }
action selftag { flavor = RubySymbol.newSymbol(runtime, "self".intern()); }
action closetag { flavor = RubySymbol.newSymbol(runtime, "close".intern()); }
Closeout := empty;
# words
PrefixChar = [\-A-Za-z0-9._?] ;
NameChar = [\-A-Za-z0-9._:?] ;
TagName = NameChar+ >_starttag %starttag;
Prefix = PrefixChar+ >_prefix %prefix;
Open = "<";
Sep = ":" >_check_prefix;
End = "/";
Close = ">";
Name = Prefix Sep TagName;
NameAttr = NameChar+ >_nameattr %nameattr;
Q1Char = ( "\\\'" | [^'] ) ;
Q1Attr = Q1Char* >_valattr %valattr;
Q2Char = ( "\\\"" | [^"] ) ;
Q2Attr = Q2Char* >_valattr %valattr;
Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr;
Attrs = (space+ Attr* | empty);
CloseTrailer = End Close %selftag;
OpenTrailer = Close %opentag;
Trailer = (OpenTrailer | CloseTrailer);
OpenOrSelfTag = Name Attrs? Trailer;
CloseTag = End Name space* Close %closetag;
SomeTag = Open (OpenOrSelfTag | CloseTag);
main := |*
SomeTag => {
tag(prefix, name, attributes, flavor);
prefix = "";
name = "";
attributes = RubyHash.newHash(runtime);
flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
};
any => {
pass_through(input.substring(p, p + 1));
tagstart = p + 1;
};
*|;
}%%
package radius.parser;
import java.util.HashMap;
import java.util.LinkedList;
import org.jruby.Ruby; // runtime
import org.jruby.RubyObject;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.RubyArray;
import org.jruby.RubyString;
import org.jruby.RubyHash;
import org.jruby.RubySymbol;
public class JavaScanner {
Ruby runtime = null;
RubyArray rv = null;
void pass_through(String str) {
RubyObject last = ((RubyObject)rv.last());
if ( rv.size() > 0 && last != null && (last instanceof RubyString) ){
// XXX concat changes for ruby 1.9
((RubyString) last).concat(RubyString.newString(runtime, str));
} else {
rv.append(RubyString.newString(runtime, str));
}
}
void tag(String prefix, String name, RubyHash attr, RubySymbol flavor) {
RubyHash tag = RubyHash.newHash(runtime);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "prefix"),
RubyString.newString(runtime, prefix)
);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "name"),
RubyString.newString(runtime, name)
);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "attrs"),
attr
);
tag.op_aset(
runtime.getCurrentContext(),
RubySymbol.newSymbol(runtime, "flavor"),
flavor
);
rv.append(tag);
}
public JavaScanner(Ruby runtime) {
this.runtime = runtime;
}
%% write data;
public RubyArray operate(String tag_prefix, String input) {
char[] data = input.toCharArray();
String disposable_string;
String name = "";
String prefix = "";
RubySymbol flavor = RubySymbol.newSymbol(runtime, "tasteless".intern());
RubyHash attributes = RubyHash.newHash(runtime);
int tagstart = 0;
int mark_pfx = 0;
int mark_stg = 0;
int mark_attr = 0;
int mark_nat = 0;
int mark_vat = 0;
String nat = "";
String vat = "";
int cs;
int p = 0;
int pe = data.length;
int eof = pe;
int act;
int ts;
int te;
rv = RubyArray.newArray(runtime);
char[] remainder = data;
%% write init;
%% write exec;
return rv;
}
}
Binary file not shown.
File diff suppressed because it is too large. Load diff
-125
View File
@@ -1,125 +0,0 @@
%%{
machine parser;
action _prefix { mark_pfx = p }
action prefix {
if data[mark_pfx..p-1] != @prefix
closing = data[mark_pfx-1,1] == '/'
@nodes.last << data[mark_pfx-(closing ? 2 : 1)..p]
fbreak;
end
}
action _starttag { mark_stg = p }
action starttag { @starttag = data[mark_stg..p-1] }
action _attr { mark_attr = p }
action attr {
@attrs[@nat] = @vat
}
action prematch {
@prematch_end = p
@prematch = data[0..p] if p > 0
}
action _nameattr { mark_nat = p }
action nameattr { @nat = data[mark_nat..p-1] }
action _valattr { mark_vat = p }
action valattr { @vat = data[mark_vat..p-1] }
action opentag { @flavor = :open }
action selftag { @flavor = :self }
action closetag { @flavor = :close }
action stopparse {
@cursor = p;
fbreak;
}
Closeout := empty;
# words
PrefixChar = [\-A-Za-z0-9._?] ;
NameChar = [\-A-Za-z0-9._:?] ;
TagName = NameChar+ >_starttag %starttag;
Prefix = PrefixChar+ >_prefix %prefix;
Name = Prefix ":" TagName;
NameAttr = NameChar+ >_nameattr %nameattr;
Q1Char = ( "\\\'" | [^'] ) ;
Q1Attr = Q1Char* >_valattr %valattr;
Q2Char = ( "\\\"" | [^"] ) ;
Q2Attr = Q2Char* >_valattr %valattr;
Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr;
Attrs = (space+ Attr* | empty);
CloseTrailer = "/>" %selftag;
OpenTrailer = ">" %opentag;
Trailer = (OpenTrailer | CloseTrailer);
OpenOrSelfTag = Name Attrs? Trailer;
CloseTag = "/" Name space* ">" %closetag;
SomeTag = '<' (OpenOrSelfTag | CloseTag);
main := |*
SomeTag => {
tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs}
@prefix = nil
@name = nil
@flavor = :tasteless
@attrs = {}
@nodes << tag << ''
fbreak;
};
any => {
@nodes.last << data[p]
@tagstart = p
};
*|;
}%%
module Radius
class Scanner
def operate(prefix, data)
data = Radius::OrdString.new data
buf = ""
csel = ""
@prematch = ''
@starttag = nil
@attrs = {}
@flavor = :tasteless
@cursor = 0
@tagstart = 0
@nodes = ['']
remainder = data.dup
until remainder.length == 0
p = perform_parse(prefix, remainder)
remainder = remainder[p..-1]
end
return @nodes
end
private
def perform_parse(prefix, data)
stack = []
p = 0
ts = 0
te = 0
act = 0
eof = data.length
@prefix = prefix
%% write data;
%% write init;
%% write exec;
return p
end
end
end
Loaded 100 of 308 files, more files were not shown because too many files have changed in this diff. Show more