* added issue_relations branch
* issue_relation model added git-svn-id: http://redmine.rubyforge.org/svn/branches/work@162 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
== Version 1.1 (28 May 2006)
|
||||
|
||||
* The charset for each and/or all languages can now be easily configured.
|
||||
* Added a ActionController filter that auto-detects the client language.
|
||||
* The rake task "sort" now merges lines that match 100%, and warns if duplicate keys are found.
|
||||
* Rule support. Create flexible rules to handle issues such as pluralization.
|
||||
* Massive speed and stability improvements to development mode.
|
||||
* Added Russian strings. (Thanks to Evgeny Lineytsev)
|
||||
* Complete RDoc documentation.
|
||||
* Improved helpers.
|
||||
* GLoc now configurable via get_config and set_config
|
||||
* Added an option to tell GLoc to output various verbose information.
|
||||
* More useful functions such as set_language_if_valid, similar_language
|
||||
* GLoc's entire internal state can now be backed up and restored.
|
||||
|
||||
|
||||
== Version 1.0 (17 April 2006)
|
||||
|
||||
* Initial public release.
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2005-2006 David Barri
|
||||
|
||||
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.
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
= About
|
||||
|
||||
=== Preface
|
||||
I originally started designing this on weekends and after work in 2005. We started to become very interested in Rails at work and I wanted to get some experience with ruby with before we started using it full-time. I didn't have very many ideas for anything interesting to create so, because we write a lot of multilingual webapps at my company, I decided to write a localization library. That way if my little hobby project developed into something decent, I could at least put it to good use.
|
||||
And here we are in 2006, my little hobby project has come a long way and become quite a useful piece of software. Not only do I use it in production sites I write at work, but I also prefer it to other existing alternatives. Therefore I have decided to make it publicly available, and I hope that other developers will find it useful too.
|
||||
|
||||
=== About
|
||||
GLoc is a localization library. It doesn't aim to do everything l10n-related that you can imagine, but what it does, it does very well. It was originally designed as a Rails plugin, but can also be used for plain ruby projects. Here are a list of its main features:
|
||||
* Lightweight and efficient.
|
||||
* Uses file-based string bundles. Strings can also be set directly.
|
||||
* Intelligent, cascading language configuration.
|
||||
* Create flexible rules to handle issues such as pluralization.
|
||||
* Includes a ActionController filter that auto-detects the client language.
|
||||
* Works perfectly with Rails Engines and allows strings to be overridden just as easily as controllers, models, etc.
|
||||
* Automatically localizes Rails functions such as distance_in_minutes, select_month etc
|
||||
* Supports different charsets. You can even specify the encoding to use for each language seperately.
|
||||
* Special Rails mods/helpers.
|
||||
|
||||
=== What does GLoc mean?
|
||||
If you're wondering about the name "GLoc", I'm sure you're not alone.
|
||||
This project was originally just called "Localization" which was a bit too common, so when I decided to release it I decided to call it "Golly's Localization Library" instead (Golly is my nickname), and that was long and boring so I then abbreviated that to "GLoc". What a fun story!!
|
||||
|
||||
=== Localization helpers
|
||||
This also includes a few helpers for common situations such as displaying localized date, time, "yes" or "no", etc.
|
||||
|
||||
=== Rails Localization
|
||||
At the moment, unless you manually remove the <tt>require 'gloc-rails-text'</tt> line from init.rb, this plugin overrides certain Rails functions to provide multilingual versions. This automatically localizes functions such as select_date(), distance_of_time_in_words() and more...
|
||||
The strings can be found in lang/*.yml.
|
||||
NOTE: This is not complete. Timezones and countries are not currently localized.
|
||||
|
||||
|
||||
|
||||
|
||||
= Usage
|
||||
|
||||
=== Quickstart
|
||||
|
||||
Windows users will need to first install iconv. http://wiki.rubyonrails.com/rails/pages/iconv
|
||||
|
||||
* Create a dir "#{RAILS_ROOT}/lang"
|
||||
* Create a file "#{RAILS_ROOT}/lang/en.yml" and write your strings. The format is "key: string". Save it as UTF-8. If you save it in a different encoding, add a key called file_charset (eg. "file_charset: iso-2022-jp")
|
||||
* Put the following in config/environment.rb and change the values as you see fit. The following example is for an app that uses English and Japanese, with Japanese being the default.
|
||||
GLoc.set_config :default_language => :ja
|
||||
GLoc.clear_strings_except :en, :ja
|
||||
GLoc.set_kcode
|
||||
GLoc.load_localized_strings
|
||||
* Add 'include GLoc' to all classes that will use localization. This is added to most Rails classes automatically.
|
||||
* Optionally, you can set the language for models and controllers by simply inserting <tt>set_language :en</tt> in classes and/or methods.
|
||||
* To use localized strings, replace text such as <tt>"Welcome"</tt> with <tt>l(:welcome_string_key)</tt>, and <tt>"Hello #{name}."</tt> with <tt>l(:hello_string_key, name)</tt>. (Of course the strings will need to exist in your string bundle.)
|
||||
|
||||
There is more functionality provided by this plugin, that is not demonstrated above. Please read the API summary for details.
|
||||
|
||||
=== API summary
|
||||
|
||||
The following methods are added as both class methods and instance methods to modules/classes that include GLoc. They are also available as class methods of GLoc.
|
||||
current_language # Returns the current language
|
||||
l(symbol, *arguments) # Returns a localized string
|
||||
ll(lang, symbol, *arguments) # Returns a localized string in a specific language
|
||||
ltry(possible_key) # Returns a localized string if passed a Symbol, else returns the same argument passed
|
||||
lwr(symbol, *arguments) # Uses the default rule to return a localized string.
|
||||
lwr_(rule, symbol, *arguments) # Uses a specified rule to return a localized string.
|
||||
l_has_string?(symbol) # Checks if a localized string exists
|
||||
set_language(language) # Sets the language for the current class or class instance
|
||||
set_language_if_valid(lang) # Sets the current language if the language passed is a valid language
|
||||
|
||||
The GLoc module also defines the following class methods:
|
||||
add_localized_strings(lang, symbol_hash, override=true) # Adds a hash of localized strings
|
||||
backup_state(clear=false) # Creates a backup of GLoc's internal state and optionally clears everything too
|
||||
clear_strings(*languages) # Removes localized strings from memory
|
||||
clear_strings_except(*languages) # Removes localized strings from memory except for those of certain specified languages
|
||||
get_charset(lang) # Returns the charset used to store localized strings in memory
|
||||
get_config(key) # Returns a GLoc configuration value (see below)
|
||||
load_localized_strings(dir=nil, override=true) # Loads localized strings from all YML files in a given directory
|
||||
restore_state(state) # Restores a backup of GLoc's internal state
|
||||
set_charset(new_charset, *langs) # Sets the charset used to internally store localized strings
|
||||
set_config(hash) # Sets GLoc configuration values (see below)
|
||||
set_kcode(charset=nil) # Sets the $KCODE global variable
|
||||
similar_language(language) # Tries to find a valid language that is similar to the argument passed
|
||||
valid_languages # Returns an array of (currently) valid languages (ie. languages for which localized data exists)
|
||||
valid_language?(language) # Checks whether any localized strings are in memory for a given language
|
||||
|
||||
GLoc uses the following configuration items. They can be accessed via <tt>get_config</tt> and <tt>set_config</tt>.
|
||||
:default_cookie_name
|
||||
:default_language
|
||||
:default_param_name
|
||||
:raise_string_not_found_errors
|
||||
:verbose
|
||||
|
||||
The GLoc module is automatically included in the following classes:
|
||||
ActionController::Base
|
||||
ActionMailer::Base
|
||||
ActionView::Base
|
||||
ActionView::Helpers::InstanceTag
|
||||
ActiveRecord::Base
|
||||
ActiveRecord::Errors
|
||||
ApplicationHelper
|
||||
Test::Unit::TestCase
|
||||
|
||||
The GLoc module also defines the following controller filters:
|
||||
autodetect_language_filter
|
||||
|
||||
GLoc also makes the following change to Rails:
|
||||
* Views for ActionMailer are now #{view_name}_#{language}.rb rather than just #{view_name}.rb
|
||||
* All ActiveRecord validation class methods now accept a localized string key (symbol) as a :message value.
|
||||
* ActiveRecord::Errors.add now accepts symbols as valid message values. At runtime these symbols are converted to localized strings using the current_language of the base record.
|
||||
* ActiveRecord::Errors.add now accepts arrays as arguments so that printf-style strings can be generated at runtime. This also applies to the validates_* class methods.
|
||||
Eg. validates_xxxxxx_of :name, :message => ['Your name must be at least %d characters.', MIN_LEN]
|
||||
Eg. validates_xxxxxx_of :name, :message => [:user_error_validation_name_too_short, MIN_LEN]
|
||||
* Instances of ActiveView inherit their current_language from the controller (or mailer) creating them.
|
||||
|
||||
This plugin also adds the following rake tasks:
|
||||
* gloc:sort - Sorts the keys in the lang ymls (also accepts a DIR argument)
|
||||
|
||||
=== Cascading language configuration
|
||||
|
||||
The language can be set at three levels:
|
||||
1. The default # GLoc.get_config :default_language
|
||||
2. Class level # class A; set_language :de; end
|
||||
3. Instance level # b= B.new; b.set_language :zh
|
||||
|
||||
Instance level has the highest priority and the default has the lowest.
|
||||
|
||||
Because GLoc is included at class level too, it becomes easy to associate languages with contexts.
|
||||
For example:
|
||||
class Student
|
||||
set_language :en
|
||||
def say_hello
|
||||
puts "We say #{l :hello} but our teachers say #{Teacher.l :hello}"
|
||||
end
|
||||
end
|
||||
|
||||
=== Rules
|
||||
|
||||
There are often situations when depending on the value of one or more variables, the surrounding text
|
||||
changes. The most common case of this is pluralization. Rather than hardcode these rules, they are
|
||||
completely definable by the user so that the user can eaasily accomodate for more complicated grammatical
|
||||
rules such as those found in Russian and Polish (or so I hear). To define a rule, simply include a string
|
||||
in the string bundle whose key begins with "_gloc_rule_" and then write ruby code as the value. The ruby
|
||||
code will be converted to a Proc when the string bundle is first read, and should return a prefix that will
|
||||
be appended to the string key at runtime to point to a new string. Make sense? Probably not... Please look
|
||||
at the following example and I am sure it will all make sense.
|
||||
|
||||
Simple example (string bundle / en.yml)
|
||||
_gloc_rule_default: ' |n| n==1 ? "_single" : "_plural" '
|
||||
man_count_plural: There are %d men.
|
||||
man_count_single: There is 1 man.
|
||||
|
||||
Simple example (code)
|
||||
lwr(:man_count, 1) # => There is 1 man.
|
||||
lwr(:man_count, 8) # => There are 8 men.
|
||||
|
||||
To use rules other than the default simply call lwr_ instead of lwr, and specify the rule.
|
||||
|
||||
Example #2 (string bundle / en.yml)
|
||||
_gloc_rule_default: ' |n| n==1 ? "_single" : "_plural" '
|
||||
_gloc_rule_custom: ' |n| return "_none" if n==0; return "_heaps" if n>100; n==1 ? "_single" : "_plural" '
|
||||
man_count_none: There are no men.
|
||||
man_count_heaps: There are heaps of men!!
|
||||
man_count_plural: There are %d men.
|
||||
man_count_single: There is 1 man.
|
||||
|
||||
Example #2 (code)
|
||||
lwr_(:custom, :man_count, 0) # => There are no men.
|
||||
lwr_(:custom, :man_count, 1) # => There is 1 man.
|
||||
lwr_(:custom, :man_count, 8) # => There are 8 men.
|
||||
lwr_(:custom, :man_count, 150) # => There are heaps of men!!
|
||||
|
||||
|
||||
=== Helpers
|
||||
|
||||
GLoc includes the following helpers:
|
||||
l_age(age) # Returns a localized version of an age. eg "3 years old"
|
||||
l_date(date) # Returns a date in a localized format
|
||||
l_datetime(date) # Returns a date+time in a localized format
|
||||
l_datetime_short(date) # Returns a date+time in a localized short format.
|
||||
l_lang_name(l,dl=nil) # Returns the name of a language (you must supply your own strings)
|
||||
l_strftime(date,fmt) # Formats a date/time in a localized format.
|
||||
l_time(date) # Returns a time in a localized format
|
||||
l_YesNo(value) # Returns localized string of "Yes" or "No" depending on the arg
|
||||
l_yesno(value) # Returns localized string of "yes" or "no" depending on the arg
|
||||
|
||||
=== Rails localization
|
||||
|
||||
Not all of Rails is covered but the following functions are:
|
||||
distance_of_time_in_words
|
||||
select_day
|
||||
select_month
|
||||
select_year
|
||||
add_options
|
||||
|
||||
|
||||
|
||||
|
||||
= FAQ
|
||||
|
||||
==== How do I use it in engines?
|
||||
Simply put this in your init_engine.rb
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
That way your engines strings will be loaded when the engine is started. Just simply make sure that you load your application strings after you start your engines to safely override any engine strings.
|
||||
|
||||
==== Why am I getting an Iconv::IllegalSequence error when calling GLoc.set_charset?
|
||||
By default GLoc loads all of its default strings at startup. For example, calling <tt>set_charset 'iso-2022-jp'</tt> will cause this error because Russian strings are loaded by default, and the Russian strings use characters that cannot be expressed in the ISO-2022-JP charset.
|
||||
Before calling <tt>set_charset</tt> you should call <tt>clear_strings_except</tt> to remove strings from any languages that you will not be using.
|
||||
Alternatively, you can simply specify the language(s) as follows, <tt>set_charset 'iso-2022-jp', :ja</tt>.
|
||||
|
||||
==== How do I make GLoc ignore StringNotFoundErrors?
|
||||
Disable it as follows:
|
||||
GLoc.set_config :raise_string_not_found_errors => false
|
||||
@@ -0,0 +1,15 @@
|
||||
Dir.glob("#{File.dirname(__FILE__)}/tasks/*.rake").each {|f| load f}
|
||||
|
||||
task :default => 'gloc:sort'
|
||||
|
||||
# RDoc task
|
||||
require 'rake/rdoctask'
|
||||
Rake::RDocTask.new() { |rdoc|
|
||||
rdoc.rdoc_dir = 'doc'
|
||||
rdoc.title = "GLoc Localization Library Documentation"
|
||||
rdoc.options << '--line-numbers' << '--inline-source'
|
||||
rdoc.rdoc_files.include('README', 'CHANGELOG')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
rdoc.rdoc_files.exclude('lib/gloc-dev.rb')
|
||||
rdoc.rdoc_files.exclude('lib/gloc-config.rb')
|
||||
}
|
||||
Vendored
+230
@@ -0,0 +1,230 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: ActionController::Filters::ClassMethods</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">ActionController::Filters::ClassMethods</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../../files/lib/gloc-rails_rb.html">
|
||||
lib/gloc-rails.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000001">autodetect_language_filter</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000001" class="method-detail">
|
||||
<a name="M000001"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000001" class="method-signature">
|
||||
<span class="method-name">autodetect_language_filter</span><span class="method-args">(*args)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
This filter attempts to auto-detect the clients desired language. It first
|
||||
checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE request
|
||||
header. If a language is found to match or be similar to a currently valid
|
||||
language, then it sets the current_language of the controller.
|
||||
</p>
|
||||
<pre>
|
||||
class ExampleController < ApplicationController
|
||||
set_language :en
|
||||
autodetect_language_filter :except => 'monkey', :on_no_lang => :lang_not_autodetected_callback
|
||||
autodetect_language_filter :only => 'monkey', :check_cookie => 'monkey_lang', :check_accept_header => false
|
||||
...
|
||||
def lang_not_autodetected_callback
|
||||
redirect_to somewhere
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
The <tt>args</tt> for this filter are exactly the same the arguments of
|
||||
<tt>before_filter</tt> with the following exceptions:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>:check_params</tt> — If false, then params will not be checked
|
||||
for a language. If a String, then this will value will be used as the name
|
||||
of the param.
|
||||
|
||||
</li>
|
||||
<li><tt>:check_cookie</tt> — If false, then the cookie will not be
|
||||
checked for a language. If a String, then this will value will be used as
|
||||
the name of the cookie.
|
||||
|
||||
</li>
|
||||
<li><tt>:check_accept_header</tt> — If false, then HTTP_ACCEPT_LANGUAGE
|
||||
will not be checked for a language.
|
||||
|
||||
</li>
|
||||
<li><tt>:on_set_lang</tt> — You can specify the name of a callback
|
||||
function to be called when the language is successfully detected and set.
|
||||
The param must be a Symbol or a String which is the name of the function.
|
||||
The callback function must accept one argument (the language) and must be
|
||||
instance level.
|
||||
|
||||
</li>
|
||||
<li><tt>:on_no_lang</tt> — You can specify the name of a callback
|
||||
function to be called when the language couldn’t be detected
|
||||
automatically. The param must be a Symbol or a String which is the name of
|
||||
the function. The callback function must be instance level.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
You override the default names of the param or cookie by calling <tt><a
|
||||
href="../../GLoc.html#M000014">GLoc.set_config</a> :default_param_name
|
||||
=> ‘new_param_name‘</tt> and <tt><a
|
||||
href="../../GLoc.html#M000014">GLoc.set_config</a> :default_cookie_name
|
||||
=> ‘new_cookie_name‘</tt>.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000001-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000001-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 43</span>
|
||||
43: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">autodetect_language_filter</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
|
||||
44: <span class="ruby-identifier">options</span>= <span class="ruby-identifier">args</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">last</span> <span class="ruby-operator">:</span> {}
|
||||
45: <span class="ruby-identifier">x</span>= <span class="ruby-value str">'Proc.new { |c| l= nil;'</span>
|
||||
46: <span class="ruby-comment cmt"># :check_params</span>
|
||||
47: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">v</span>= <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:check_params</span>)) <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
|
||||
48: <span class="ruby-identifier">name</span>= <span class="ruby-identifier">v</span> <span class="ruby-value">? </span><span class="ruby-node">":#{v}"</span> <span class="ruby-operator">:</span> <span class="ruby-value str">'GLoc.get_config(:default_param_name)'</span>
|
||||
49: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-node">"l ||= GLoc.similar_language(c.params[#{name}]);"</span>
|
||||
50: <span class="ruby-keyword kw">end</span>
|
||||
51: <span class="ruby-comment cmt"># :check_cookie</span>
|
||||
52: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">v</span>= <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:check_cookie</span>)) <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
|
||||
53: <span class="ruby-identifier">name</span>= <span class="ruby-identifier">v</span> <span class="ruby-value">? </span><span class="ruby-node">":#{v}"</span> <span class="ruby-operator">:</span> <span class="ruby-value str">'GLoc.get_config(:default_cookie_name)'</span>
|
||||
54: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-node">"l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);"</span>
|
||||
55: <span class="ruby-keyword kw">end</span>
|
||||
56: <span class="ruby-comment cmt"># :check_accept_header</span>
|
||||
57: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:check_accept_header</span>) <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
|
||||
58: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-value str">%<
|
||||
59: unless l
|
||||
60: a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
|
||||
61: a.each {|x| l ||= GLoc.similar_language(x)} if a
|
||||
62: end; ></span>
|
||||
63: <span class="ruby-keyword kw">end</span>
|
||||
64: <span class="ruby-comment cmt"># Set language</span>
|
||||
65: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-value str">'ret= true;'</span>
|
||||
66: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-value str">'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '</span>
|
||||
67: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:on_set_lang</span>)
|
||||
68: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-node">"ret= c.#{options.delete(:on_set_lang)}(l);"</span>
|
||||
69: <span class="ruby-keyword kw">end</span>
|
||||
70: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:on_no_lang</span>)
|
||||
71: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-node">"else; ret= c.#{options.delete(:on_no_lang)};"</span>
|
||||
72: <span class="ruby-keyword kw">end</span>
|
||||
73: <span class="ruby-identifier">x</span> <span class="ruby-operator"><<</span> <span class="ruby-value str">'end; ret }'</span>
|
||||
74:
|
||||
75: <span class="ruby-comment cmt"># Create filter</span>
|
||||
76: <span class="ruby-identifier">block</span>= <span class="ruby-identifier">eval</span> <span class="ruby-identifier">x</span>
|
||||
77: <span class="ruby-identifier">before_filter</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">&</span><span class="ruby-identifier">block</span>)
|
||||
78: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Class: ActionMailer::Base</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Class</strong></td>
|
||||
<td class="class-name-in-header">ActionMailer::Base</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../files/lib/gloc-rails_rb.html">
|
||||
lib/gloc-rails.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Parent:</strong></td>
|
||||
<td>
|
||||
Object
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
In addition to including <a href="../GLoc.html">GLoc</a>,
|
||||
<tt>render_message</tt> is also overridden so that mail templates contain
|
||||
the current language at the end of the file. Eg. <tt>deliver_hello</tt>
|
||||
will render <tt>hello_en.rhtml</tt>.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="../GLoc.html">GLoc</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
<div id="aliases-list">
|
||||
<h3 class="section-bar">External Aliases</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<table summary="aliases">
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">render_message</td>
|
||||
<td>-></td>
|
||||
<td class="context-item-value">render_message_without_gloc</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Class: ActionView::Base</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Class</strong></td>
|
||||
<td class="class-name-in-header">ActionView::Base</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../files/lib/gloc-rails_rb.html">
|
||||
lib/gloc-rails.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Parent:</strong></td>
|
||||
<td>
|
||||
Object
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
<tt>initialize</tt> is overridden so that new instances of this class
|
||||
inherit the current language of the controller.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000046">new</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="../GLoc.html">GLoc</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
<div id="aliases-list">
|
||||
<h3 class="section-bar">External Aliases</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<table summary="aliases">
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">initialize</td>
|
||||
<td>-></td>
|
||||
<td class="context-item-value">initialize_without_gloc</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Class methods</h3>
|
||||
|
||||
<div id="method-M000046" class="method-detail">
|
||||
<a name="M000046"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000046" class="method-signature">
|
||||
<span class="method-name">new</span><span class="method-args">(base_path = nil, assigns_for_first_render = {}, controller = nil)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000046-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000046-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 109</span>
|
||||
109: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">base_path</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">assigns_for_first_render</span> = {}, <span class="ruby-identifier">controller</span> = <span class="ruby-keyword kw">nil</span>)
|
||||
110: <span class="ruby-identifier">initialize_without_gloc</span>(<span class="ruby-identifier">base_path</span>, <span class="ruby-identifier">assigns_for_first_render</span>, <span class="ruby-identifier">controller</span>)
|
||||
111: <span class="ruby-identifier">set_language</span> <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">current_language</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">nil?</span>
|
||||
112: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: ActionView::Helpers::DateHelper</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">ActionView::Helpers::DateHelper</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../../files/lib/gloc-rails-text_rb.html">
|
||||
lib/gloc-rails-text.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000041">distance_of_time_in_words</a>
|
||||
<a href="#M000042">select_day</a>
|
||||
<a href="#M000043">select_month</a>
|
||||
<a href="#M000044">select_year</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
<div id="constants-list">
|
||||
<h3 class="section-bar">Constants</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<table summary="Constants">
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">LOCALIZED_HELPERS</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">true</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">LOCALIZED_MONTHNAMES</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">{}</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">LOCALIZED_ABBR_MONTHNAMES</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">{}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000041" class="method-detail">
|
||||
<a name="M000041"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000041" class="method-signature">
|
||||
<span class="method-name">distance_of_time_in_words</span><span class="method-args">(from_time, to_time = 0, include_seconds = false)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
This method uses <tt>current_language</tt> to return a localized string.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000041-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000041-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 16</span>
|
||||
16: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">distance_of_time_in_words</span>(<span class="ruby-identifier">from_time</span>, <span class="ruby-identifier">to_time</span> = <span class="ruby-value">0</span>, <span class="ruby-identifier">include_seconds</span> = <span class="ruby-keyword kw">false</span>)
|
||||
17: <span class="ruby-identifier">from_time</span> = <span class="ruby-identifier">from_time</span>.<span class="ruby-identifier">to_time</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">from_time</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">:to_time</span>)
|
||||
18: <span class="ruby-identifier">to_time</span> = <span class="ruby-identifier">to_time</span>.<span class="ruby-identifier">to_time</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">to_time</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">:to_time</span>)
|
||||
19: <span class="ruby-identifier">distance_in_minutes</span> = (((<span class="ruby-identifier">to_time</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">from_time</span>).<span class="ruby-identifier">abs</span>)<span class="ruby-operator">/</span><span class="ruby-value">60</span>).<span class="ruby-identifier">round</span>
|
||||
20: <span class="ruby-identifier">distance_in_seconds</span> = ((<span class="ruby-identifier">to_time</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">from_time</span>).<span class="ruby-identifier">abs</span>).<span class="ruby-identifier">round</span>
|
||||
21:
|
||||
22: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">distance_in_minutes</span>
|
||||
23: <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>
|
||||
24: <span class="ruby-keyword kw">return</span> (<span class="ruby-identifier">distance_in_minutes</span><span class="ruby-operator">==</span><span class="ruby-value">0</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_less_than</span>) <span class="ruby-operator">:</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_single</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">include_seconds</span>
|
||||
25: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">distance_in_seconds</span>
|
||||
26: <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">5</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_second_less_than</span>, <span class="ruby-value">5</span>)
|
||||
27: <span class="ruby-keyword kw">when</span> <span class="ruby-value">6</span><span class="ruby-operator">..</span><span class="ruby-value">10</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_second_less_than</span>, <span class="ruby-value">10</span>)
|
||||
28: <span class="ruby-keyword kw">when</span> <span class="ruby-value">11</span><span class="ruby-operator">..</span><span class="ruby-value">20</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_second_less_than</span>, <span class="ruby-value">20</span>)
|
||||
29: <span class="ruby-keyword kw">when</span> <span class="ruby-value">21</span><span class="ruby-operator">..</span><span class="ruby-value">40</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_half</span>)
|
||||
30: <span class="ruby-keyword kw">when</span> <span class="ruby-value">41</span><span class="ruby-operator">..</span><span class="ruby-value">59</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_less_than</span>)
|
||||
31: <span class="ruby-keyword kw">else</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute</span>)
|
||||
32: <span class="ruby-keyword kw">end</span>
|
||||
33:
|
||||
34: <span class="ruby-keyword kw">when</span> <span class="ruby-value">2</span><span class="ruby-operator">..</span><span class="ruby-value">45</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute</span>, <span class="ruby-identifier">distance_in_minutes</span>)
|
||||
35: <span class="ruby-keyword kw">when</span> <span class="ruby-value">46</span><span class="ruby-operator">..</span><span class="ruby-value">90</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_hour_about_single</span>)
|
||||
36: <span class="ruby-keyword kw">when</span> <span class="ruby-value">90</span><span class="ruby-operator">..</span><span class="ruby-value">1440</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_hour_about</span>, (<span class="ruby-identifier">distance_in_minutes</span>.<span class="ruby-identifier">to_f</span> <span class="ruby-operator">/</span> <span class="ruby-value">60.0</span>).<span class="ruby-identifier">round</span>)
|
||||
37: <span class="ruby-keyword kw">when</span> <span class="ruby-value">1441</span><span class="ruby-operator">..</span><span class="ruby-value">2880</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_day</span>, <span class="ruby-value">1</span>)
|
||||
38: <span class="ruby-keyword kw">else</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_day</span>, (<span class="ruby-identifier">distance_in_minutes</span> <span class="ruby-operator">/</span> <span class="ruby-value">1440</span>).<span class="ruby-identifier">round</span>)
|
||||
39: <span class="ruby-keyword kw">end</span>
|
||||
40: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000042" class="method-detail">
|
||||
<a name="M000042"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000042" class="method-signature">
|
||||
<span class="method-name">select_day</span><span class="method-args">(date, options = {})</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
This method has been modified so that a localized string can be appended to
|
||||
the day numbers.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000042-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000042-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 43</span>
|
||||
43: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">select_day</span>(<span class="ruby-identifier">date</span>, <span class="ruby-identifier">options</span> = {})
|
||||
44: <span class="ruby-identifier">day_options</span> = []
|
||||
45: <span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">l</span> <span class="ruby-identifier">:actionview_datehelper_select_day_prefix</span>
|
||||
46:
|
||||
47: <span class="ruby-value">1</span>.<span class="ruby-identifier">upto</span>(<span class="ruby-value">31</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">day</span><span class="ruby-operator">|</span>
|
||||
48: <span class="ruby-identifier">day_options</span> <span class="ruby-operator"><<</span> ((<span class="ruby-identifier">date</span> <span class="ruby-operator">&&</span> (<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">date</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">day</span>) <span class="ruby-operator">==</span> <span class="ruby-identifier">day</span>) <span class="ruby-operator">?</span>
|
||||
49: <span class="ruby-node">%(<option value="#{day}" selected="selected">#{day}#{prefix}</option>\n)</span> <span class="ruby-operator">:</span>
|
||||
50: <span class="ruby-node">%(<option value="#{day}">#{day}#{prefix}</option>\n)</span>
|
||||
51: )
|
||||
52: <span class="ruby-keyword kw">end</span>
|
||||
53:
|
||||
54: <span class="ruby-identifier">select_html</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:field_name</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'day'</span>, <span class="ruby-identifier">day_options</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:prefix</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:include_blank</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:discard_type</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:disabled</span>])
|
||||
55: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000043" class="method-detail">
|
||||
<a name="M000043"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000043" class="method-signature">
|
||||
<span class="method-name">select_month</span><span class="method-args">(date, options = {})</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
This method has been modified so that
|
||||
</p>
|
||||
<ul>
|
||||
<li>the month names are localized.
|
||||
|
||||
</li>
|
||||
<li>it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>,
|
||||
<tt>:start_month</tt>, <tt>:end_month</tt>
|
||||
|
||||
</li>
|
||||
<li>a localized string can be appended to the month numbers when the
|
||||
<tt>:use_month_numbers</tt> option is specified.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000043-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000043-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 61</span>
|
||||
61: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">select_month</span>(<span class="ruby-identifier">date</span>, <span class="ruby-identifier">options</span> = {})
|
||||
62: <span class="ruby-keyword kw">unless</span> <span class="ruby-constant">LOCALIZED_MONTHNAMES</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">current_language</span>)
|
||||
63: <span class="ruby-constant">LOCALIZED_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>] = [<span class="ruby-value str">''</span>] <span class="ruby-operator">+</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_select_month_names</span>).<span class="ruby-identifier">split</span>(<span class="ruby-value str">','</span>)
|
||||
64: <span class="ruby-constant">LOCALIZED_ABBR_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>] = [<span class="ruby-value str">''</span>] <span class="ruby-operator">+</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_select_month_names_abbr</span>).<span class="ruby-identifier">split</span>(<span class="ruby-value str">','</span>)
|
||||
65: <span class="ruby-keyword kw">end</span>
|
||||
66:
|
||||
67: <span class="ruby-identifier">month_options</span> = []
|
||||
68: <span class="ruby-identifier">month_names</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:use_short_month</span>] <span class="ruby-operator">?</span> <span class="ruby-constant">LOCALIZED_ABBR_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>] <span class="ruby-operator">:</span> <span class="ruby-constant">LOCALIZED_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>]
|
||||
69:
|
||||
70: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:min_date</span>) <span class="ruby-operator">&&</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:max_date</span>)
|
||||
71: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:min_date</span>].<span class="ruby-identifier">year</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:max_date</span>].<span class="ruby-identifier">year</span>
|
||||
72: <span class="ruby-identifier">start_month</span>, <span class="ruby-identifier">end_month</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:min_date</span>].<span class="ruby-identifier">month</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:max_date</span>].<span class="ruby-identifier">month</span>
|
||||
73: <span class="ruby-keyword kw">end</span>
|
||||
74: <span class="ruby-keyword kw">end</span>
|
||||
75: <span class="ruby-identifier">start_month</span> = (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:start_month</span>] <span class="ruby-operator">||</span> <span class="ruby-value">1</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">start_month</span>
|
||||
76: <span class="ruby-identifier">end_month</span> = (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:end_month</span>] <span class="ruby-operator">||</span> <span class="ruby-value">12</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">end_month</span>
|
||||
77: <span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">l</span> <span class="ruby-identifier">:actionview_datehelper_select_month_prefix</span>
|
||||
78:
|
||||
79: <span class="ruby-identifier">start_month</span>.<span class="ruby-identifier">upto</span>(<span class="ruby-identifier">end_month</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">month_number</span><span class="ruby-operator">|</span>
|
||||
80: <span class="ruby-identifier">month_name</span> = <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:use_month_numbers</span>]
|
||||
81: <span class="ruby-node">"#{month_number}#{prefix}"</span>
|
||||
82: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:add_month_numbers</span>]
|
||||
83: <span class="ruby-identifier">month_number</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">' - '</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">month_names</span>[<span class="ruby-identifier">month_number</span>]
|
||||
84: <span class="ruby-keyword kw">else</span>
|
||||
85: <span class="ruby-identifier">month_names</span>[<span class="ruby-identifier">month_number</span>]
|
||||
86: <span class="ruby-keyword kw">end</span>
|
||||
87:
|
||||
88: <span class="ruby-identifier">month_options</span> <span class="ruby-operator"><<</span> ((<span class="ruby-identifier">date</span> <span class="ruby-operator">&&</span> (<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">date</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">month</span>) <span class="ruby-operator">==</span> <span class="ruby-identifier">month_number</span>) <span class="ruby-operator">?</span>
|
||||
89: <span class="ruby-node">%(<option value="#{month_number}" selected="selected">#{month_name}</option>\n)</span> <span class="ruby-operator">:</span>
|
||||
90: <span class="ruby-node">%(<option value="#{month_number}">#{month_name}</option>\n)</span>
|
||||
91: )
|
||||
92: <span class="ruby-keyword kw">end</span>
|
||||
93:
|
||||
94: <span class="ruby-identifier">select_html</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:field_name</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'month'</span>, <span class="ruby-identifier">month_options</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:prefix</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:include_blank</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:discard_type</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:disabled</span>])
|
||||
95: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000044" class="method-detail">
|
||||
<a name="M000044"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000044" class="method-signature">
|
||||
<span class="method-name">select_year</span><span class="method-args">(date, options = {})</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
This method has been modified so that
|
||||
</p>
|
||||
<ul>
|
||||
<li>it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>
|
||||
|
||||
</li>
|
||||
<li>a localized string can be appended to the years numbers.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000044-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000044-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 100</span>
|
||||
100: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">select_year</span>(<span class="ruby-identifier">date</span>, <span class="ruby-identifier">options</span> = {})
|
||||
101: <span class="ruby-identifier">year_options</span> = []
|
||||
102: <span class="ruby-identifier">y</span> = <span class="ruby-identifier">date</span> <span class="ruby-value">? </span>(<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> (<span class="ruby-identifier">y</span> = (<span class="ruby-identifier">date</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>) <span class="ruby-operator">?</span> <span class="ruby-constant">Date</span>.<span class="ruby-identifier">today</span>.<span class="ruby-identifier">year</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>) <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">year</span>) <span class="ruby-operator">:</span> <span class="ruby-constant">Date</span>.<span class="ruby-identifier">today</span>.<span class="ruby-identifier">year</span>
|
||||
103:
|
||||
104: <span class="ruby-identifier">start_year</span> = <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:min_date</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:min_date</span>].<span class="ruby-identifier">year</span> <span class="ruby-operator">:</span> (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:start_year</span>] <span class="ruby-operator">||</span> <span class="ruby-identifier">y</span><span class="ruby-operator">-</span><span class="ruby-value">5</span>)
|
||||
105: <span class="ruby-identifier">end_year</span> = <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:max_date</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:max_date</span>].<span class="ruby-identifier">year</span> <span class="ruby-operator">:</span> (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:end_year</span>] <span class="ruby-operator">||</span> <span class="ruby-identifier">y</span><span class="ruby-operator">+</span><span class="ruby-value">5</span>)
|
||||
106: <span class="ruby-identifier">step_val</span> = <span class="ruby-identifier">start_year</span> <span class="ruby-operator"><</span> <span class="ruby-identifier">end_year</span> <span class="ruby-value">? </span><span class="ruby-value">1</span> <span class="ruby-operator">:</span> <span class="ruby-value">-1</span>
|
||||
107: <span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">l</span> <span class="ruby-identifier">:actionview_datehelper_select_year_prefix</span>
|
||||
108:
|
||||
109: <span class="ruby-identifier">start_year</span>.<span class="ruby-identifier">step</span>(<span class="ruby-identifier">end_year</span>, <span class="ruby-identifier">step_val</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">year</span><span class="ruby-operator">|</span>
|
||||
110: <span class="ruby-identifier">year_options</span> <span class="ruby-operator"><<</span> ((<span class="ruby-identifier">date</span> <span class="ruby-operator">&&</span> (<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">date</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">year</span>) <span class="ruby-operator">==</span> <span class="ruby-identifier">year</span>) <span class="ruby-operator">?</span>
|
||||
111: <span class="ruby-node">%(<option value="#{year}" selected="selected">#{year}#{prefix}</option>\n)</span> <span class="ruby-operator">:</span>
|
||||
112: <span class="ruby-node">%(<option value="#{year}">#{year}#{prefix}</option>\n)</span>
|
||||
113: )
|
||||
114: <span class="ruby-keyword kw">end</span>
|
||||
115:
|
||||
116: <span class="ruby-identifier">select_html</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:field_name</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'year'</span>, <span class="ruby-identifier">year_options</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:prefix</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:include_blank</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:discard_type</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:disabled</span>])
|
||||
117: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Class: ActionView::Helpers::InstanceTag</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Class</strong></td>
|
||||
<td class="class-name-in-header">ActionView::Helpers::InstanceTag</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../../files/lib/gloc-rails-text_rb.html">
|
||||
lib/gloc-rails-text.rb
|
||||
</a>
|
||||
<br />
|
||||
<a href="../../../files/lib/gloc-rails_rb.html">
|
||||
lib/gloc-rails.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Parent:</strong></td>
|
||||
<td>
|
||||
Object
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
The private method <tt>add_options</tt> is overridden so that "Please
|
||||
select" is localized.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000045">current_language</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="../../GLoc.html">GLoc</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000045" class="method-detail">
|
||||
<a name="M000045"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000045" class="method-signature">
|
||||
<span class="method-name">current_language</span><span class="method-args">()</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Inherits the current language from the template object.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000045-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000045-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 119</span>
|
||||
119: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
|
||||
120: <span class="ruby-ivar">@template_object</span>.<span class="ruby-identifier">current_language</span>
|
||||
121: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Class: ActiveRecord::Errors</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Class</strong></td>
|
||||
<td class="class-name-in-header">ActiveRecord::Errors</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../files/lib/gloc-rails_rb.html">
|
||||
lib/gloc-rails.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Parent:</strong></td>
|
||||
<td>
|
||||
Object
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000039">add</a>
|
||||
<a href="#M000040">current_language</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="../GLoc.html">GLoc</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
<div id="aliases-list">
|
||||
<h3 class="section-bar">External Aliases</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<table summary="aliases">
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">add</td>
|
||||
<td>-></td>
|
||||
<td class="context-item-value">add_without_gloc</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000039" class="method-detail">
|
||||
<a name="M000039"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000039" class="method-signature">
|
||||
<span class="method-name">add</span><span class="method-args">(attribute, msg= @@default_error_messages[:invalid])</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
The <a href="../GLoc.html">GLoc</a> version of this method provides two
|
||||
extra features
|
||||
</p>
|
||||
<ul>
|
||||
<li>If <tt>msg</tt> is a string, it will be considered a <a
|
||||
href="../GLoc.html">GLoc</a> string key.
|
||||
|
||||
</li>
|
||||
<li>If <tt>msg</tt> is an array, the first element will be considered the
|
||||
string and the remaining elements will be considered arguments for the
|
||||
string. Eg. <tt>[‘Hi %s.’,’John’]</tt>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000039-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000039-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 141</span>
|
||||
141: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">add</span>(<span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">msg</span>= <span class="ruby-ivar">@@default_error_messages</span>[<span class="ruby-identifier">:invalid</span>])
|
||||
142: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
|
||||
143: <span class="ruby-identifier">args</span>= <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">clone</span>
|
||||
144: <span class="ruby-identifier">msg</span>= <span class="ruby-identifier">args</span>.<span class="ruby-identifier">shift</span>
|
||||
145: <span class="ruby-identifier">args</span>= <span class="ruby-keyword kw">nil</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">empty?</span>
|
||||
146: <span class="ruby-keyword kw">end</span>
|
||||
147: <span class="ruby-identifier">msg</span>= <span class="ruby-identifier">ltry</span>(<span class="ruby-identifier">msg</span>)
|
||||
148: <span class="ruby-identifier">msg</span>= <span class="ruby-identifier">msg</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">args</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">nil?</span>
|
||||
149: <span class="ruby-identifier">add_without_gloc</span>(<span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">msg</span>)
|
||||
150: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000040" class="method-detail">
|
||||
<a name="M000040"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000040" class="method-signature">
|
||||
<span class="method-name">current_language</span><span class="method-args">()</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Inherits the current language from the base record.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000040-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000040-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 152</span>
|
||||
152: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
|
||||
153: <span class="ruby-ivar">@base</span>.<span class="ruby-identifier">current_language</span>
|
||||
154: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+217
@@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: ActiveRecord::Validations::ClassMethods</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">ActiveRecord::Validations::ClassMethods</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../../files/lib/gloc-rails_rb.html">
|
||||
lib/gloc-rails.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000037">validates_length_of</a>
|
||||
<a href="#M000038">validates_size_of</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000037" class="method-detail">
|
||||
<a name="M000037"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000037" class="method-signature">
|
||||
<span class="method-name">validates_length_of</span><span class="method-args">(*attrs)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
The default Rails version of this function creates an error message and
|
||||
then passes it to <a href="../Errors.html">ActiveRecord.Errors</a>. The <a
|
||||
href="../../GLoc.html">GLoc</a> version of this method, sends an array to
|
||||
<a href="../Errors.html">ActiveRecord.Errors</a> that will be turned into a
|
||||
string by <a href="../Errors.html">ActiveRecord.Errors</a> which in turn
|
||||
allows for the message of this validation function to be a <a
|
||||
href="../../GLoc.html">GLoc</a> string key.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000037-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000037-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 164</span>
|
||||
164: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">validates_length_of</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">attrs</span>)
|
||||
165: <span class="ruby-comment cmt"># Merge given options with defaults.</span>
|
||||
166: <span class="ruby-identifier">options</span> = {
|
||||
167: <span class="ruby-identifier">:too_long</span> =<span class="ruby-operator">></span> <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Errors</span>.<span class="ruby-identifier">default_error_messages</span>[<span class="ruby-identifier">:too_long</span>],
|
||||
168: <span class="ruby-identifier">:too_short</span> =<span class="ruby-operator">></span> <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Errors</span>.<span class="ruby-identifier">default_error_messages</span>[<span class="ruby-identifier">:too_short</span>],
|
||||
169: <span class="ruby-identifier">:wrong_length</span> =<span class="ruby-operator">></span> <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Errors</span>.<span class="ruby-identifier">default_error_messages</span>[<span class="ruby-identifier">:wrong_length</span>]
|
||||
170: }.<span class="ruby-identifier">merge</span>(<span class="ruby-constant">DEFAULT_VALIDATION_OPTIONS</span>)
|
||||
171: <span class="ruby-identifier">options</span>.<span class="ruby-identifier">update</span>(<span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">pop</span>.<span class="ruby-identifier">symbolize_keys</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>)
|
||||
172:
|
||||
173: <span class="ruby-comment cmt"># Ensure that one and only one range option is specified.</span>
|
||||
174: <span class="ruby-identifier">range_options</span> = <span class="ruby-constant">ALL_RANGE_OPTIONS</span> <span class="ruby-operator">&</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">keys</span>
|
||||
175: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">range_options</span>.<span class="ruby-identifier">size</span>
|
||||
176: <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span>
|
||||
177: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-value str">'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'</span>
|
||||
178: <span class="ruby-keyword kw">when</span> <span class="ruby-value">1</span>
|
||||
179: <span class="ruby-comment cmt"># Valid number of options; do nothing.</span>
|
||||
180: <span class="ruby-keyword kw">else</span>
|
||||
181: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-value str">'Too many range options specified. Choose only one.'</span>
|
||||
182: <span class="ruby-keyword kw">end</span>
|
||||
183:
|
||||
184: <span class="ruby-comment cmt"># Get range option and value.</span>
|
||||
185: <span class="ruby-identifier">option</span> = <span class="ruby-identifier">range_options</span>.<span class="ruby-identifier">first</span>
|
||||
186: <span class="ruby-identifier">option_value</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">range_options</span>.<span class="ruby-identifier">first</span>]
|
||||
187:
|
||||
188: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">option</span>
|
||||
189: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:within</span>, <span class="ruby-identifier">:in</span>
|
||||
190: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-node">":#{option} must be a Range"</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Range</span>)
|
||||
191:
|
||||
192: <span class="ruby-identifier">too_short</span> = [<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:too_short</span>] , <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">begin</span>]
|
||||
193: <span class="ruby-identifier">too_long</span> = [<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:too_long</span>] , <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">end</span> ]
|
||||
194:
|
||||
195: <span class="ruby-identifier">validates_each</span>(<span class="ruby-identifier">attrs</span>, <span class="ruby-identifier">options</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">record</span>, <span class="ruby-identifier">attr</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
|
||||
196: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">//</span>).<span class="ruby-identifier">size</span> <span class="ruby-operator"><</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">begin</span>
|
||||
197: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">too_short</span>)
|
||||
198: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">//</span>).<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">end</span>
|
||||
199: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">too_long</span>)
|
||||
200: <span class="ruby-keyword kw">end</span>
|
||||
201: <span class="ruby-keyword kw">end</span>
|
||||
202: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:is</span>, <span class="ruby-identifier">:minimum</span>, <span class="ruby-identifier">:maximum</span>
|
||||
203: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-node">":#{option} must be a nonnegative Integer"</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Integer</span>) <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">option_value</span> <span class="ruby-operator">>=</span> <span class="ruby-value">0</span>
|
||||
204:
|
||||
205: <span class="ruby-comment cmt"># Declare different validations per option.</span>
|
||||
206: <span class="ruby-identifier">validity_checks</span> = { <span class="ruby-identifier">:is</span> =<span class="ruby-operator">></span> <span class="ruby-value str">"=="</span>, <span class="ruby-identifier">:minimum</span> =<span class="ruby-operator">></span> <span class="ruby-value str">">="</span>, <span class="ruby-identifier">:maximum</span> =<span class="ruby-operator">></span> <span class="ruby-value str">"<="</span> }
|
||||
207: <span class="ruby-identifier">message_options</span> = { <span class="ruby-identifier">:is</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">:wrong_length</span>, <span class="ruby-identifier">:minimum</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">:too_short</span>, <span class="ruby-identifier">:maximum</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">:too_long</span> }
|
||||
208:
|
||||
209: <span class="ruby-identifier">message</span> = [(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:message</span>] <span class="ruby-operator">||</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">message_options</span>[<span class="ruby-identifier">option</span>]]) , <span class="ruby-identifier">option_value</span>]
|
||||
210:
|
||||
211: <span class="ruby-identifier">validates_each</span>(<span class="ruby-identifier">attrs</span>, <span class="ruby-identifier">options</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">record</span>, <span class="ruby-identifier">attr</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
|
||||
212: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">String</span>)
|
||||
213: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">message</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-operator">!</span><span class="ruby-identifier">value</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">//</span>).<span class="ruby-identifier">size</span>.<span class="ruby-identifier">method</span>(<span class="ruby-identifier">validity_checks</span>[<span class="ruby-identifier">option</span>])[<span class="ruby-identifier">option_value</span>]
|
||||
214: <span class="ruby-keyword kw">else</span>
|
||||
215: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">message</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-operator">!</span><span class="ruby-identifier">value</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">size</span>.<span class="ruby-identifier">method</span>(<span class="ruby-identifier">validity_checks</span>[<span class="ruby-identifier">option</span>])[<span class="ruby-identifier">option_value</span>]
|
||||
216: <span class="ruby-keyword kw">end</span>
|
||||
217: <span class="ruby-keyword kw">end</span>
|
||||
218: <span class="ruby-keyword kw">end</span>
|
||||
219: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000038" class="method-detail">
|
||||
<a name="M000038"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<span class="method-name">validates_size_of</span><span class="method-args">(*attrs)</span>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Alias for <a href="ClassMethods.html#M000037">validates_length_of</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,774 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: GLoc</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">GLoc</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../files/lib/gloc-helpers_rb.html">
|
||||
lib/gloc-helpers.rb
|
||||
</a>
|
||||
<br />
|
||||
<a href="../files/lib/gloc-internal_rb.html">
|
||||
lib/gloc-internal.rb
|
||||
</a>
|
||||
<br />
|
||||
<a href="../files/lib/gloc-version_rb.html">
|
||||
lib/gloc-version.rb
|
||||
</a>
|
||||
<br />
|
||||
<a href="../files/lib/gloc_rb.html">
|
||||
lib/gloc.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000004">add_localized_strings</a>
|
||||
<a href="#M000005">backup_state</a>
|
||||
<a href="#M000006">clear_strings</a>
|
||||
<a href="#M000007">clear_strings_except</a>
|
||||
<a href="#M000002">current_language</a>
|
||||
<a href="#M000003">current_language</a>
|
||||
<a href="#M000008">get_charset</a>
|
||||
<a href="#M000009">get_config</a>
|
||||
<a href="#M000010">load_gloc_default_localized_strings</a>
|
||||
<a href="#M000011">load_localized_strings</a>
|
||||
<a href="#M000012">restore_state</a>
|
||||
<a href="#M000013">set_charset</a>
|
||||
<a href="#M000014">set_config</a>
|
||||
<a href="#M000015">set_kcode</a>
|
||||
<a href="#M000016">similar_language</a>
|
||||
<a href="#M000018">valid_language?</a>
|
||||
<a href="#M000017">valid_languages</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="GLoc/InstanceMethods.html">::GLoc::InstanceMethods</a></span>
|
||||
<span class="include-name"><a href="GLoc/InstanceMethods.html">::GLoc::InstanceMethods</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
<div id="class-list">
|
||||
<h3 class="section-bar">Classes and Modules</h3>
|
||||
|
||||
Module <a href="GLoc/ClassMethods.html" class="link">GLoc::ClassMethods</a><br />
|
||||
Module <a href="GLoc/Helpers.html" class="link">GLoc::Helpers</a><br />
|
||||
Module <a href="GLoc/InstanceMethods.html" class="link">GLoc::InstanceMethods</a><br />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="constants-list">
|
||||
<h3 class="section-bar">Constants</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<table summary="Constants">
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">LOCALIZED_STRINGS</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">{}</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">RULES</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">{}</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">LOWERCASE_LANGUAGES</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">{}</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">UTF_8</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">'utf-8'</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">SHIFT_JIS</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">'sjis'</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">EUC_JP</td>
|
||||
<td>=</td>
|
||||
<td class="context-item-value">'euc-jp'</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="aliases-list">
|
||||
<h3 class="section-bar">External Aliases</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<table summary="aliases">
|
||||
<tr class="top-aligned-row context-row">
|
||||
<td class="context-item-name">clear_strings</td>
|
||||
<td>-></td>
|
||||
<td class="context-item-value">_clear_strings</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Class methods</h3>
|
||||
|
||||
<div id="method-M000004" class="method-detail">
|
||||
<a name="M000004"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000004" class="method-signature">
|
||||
<span class="method-name">add_localized_strings</span><span class="method-args">(lang, symbol_hash, override=true, strings_charset=nil)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Adds a collection of localized strings to the in-memory string store.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000004-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000004-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 113</span>
|
||||
113: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">add_localized_strings</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol_hash</span>, <span class="ruby-identifier">override</span>=<span class="ruby-keyword kw">true</span>, <span class="ruby-identifier">strings_charset</span>=<span class="ruby-keyword kw">nil</span>)
|
||||
114: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"Adding #{symbol_hash.size} #{lang} strings."</span>}
|
||||
115: <span class="ruby-identifier">_add_localized_strings</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol_hash</span>, <span class="ruby-identifier">override</span>, <span class="ruby-identifier">strings_charset</span>)
|
||||
116: <span class="ruby-identifier">_verbose_msg</span> <span class="ruby-identifier">:stats</span>
|
||||
117: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000005" class="method-detail">
|
||||
<a name="M000005"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000005" class="method-signature">
|
||||
<span class="method-name">backup_state</span><span class="method-args">(clear=false)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Creates a backup of the internal state of <a href="GLoc.html">GLoc</a> (ie.
|
||||
strings, langs, rules, config) and optionally clears everything.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000005-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000005-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 121</span>
|
||||
121: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">backup_state</span>(<span class="ruby-identifier">clear</span>=<span class="ruby-keyword kw">false</span>)
|
||||
122: <span class="ruby-identifier">s</span>= <span class="ruby-identifier">_get_internal_state_vars</span>.<span class="ruby-identifier">map</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span> <span class="ruby-identifier">o</span>.<span class="ruby-identifier">clone</span>}
|
||||
123: <span class="ruby-identifier">_get_internal_state_vars</span>.<span class="ruby-identifier">each</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span> <span class="ruby-identifier">o</span>.<span class="ruby-identifier">clear</span>} <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">clear</span>
|
||||
124: <span class="ruby-identifier">s</span>
|
||||
125: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000006" class="method-detail">
|
||||
<a name="M000006"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000006" class="method-signature">
|
||||
<span class="method-name">clear_strings</span><span class="method-args">(*languages)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Removes all localized strings from memory, either of a certain language (or
|
||||
languages), or entirely.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000006-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 129</span>
|
||||
129: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">clear_strings</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">languages</span>)
|
||||
130: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">languages</span>.<span class="ruby-identifier">empty?</span>
|
||||
131: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-value str">"Clearing all strings"</span>}
|
||||
132: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">clear</span>
|
||||
133: <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">clear</span>
|
||||
134: <span class="ruby-keyword kw">else</span>
|
||||
135: <span class="ruby-identifier">languages</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">l</span><span class="ruby-operator">|</span>
|
||||
136: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"Clearing :#{l} strings"</span>}
|
||||
137: <span class="ruby-identifier">l</span>= <span class="ruby-identifier">l</span>.<span class="ruby-identifier">to_sym</span>
|
||||
138: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">delete</span> <span class="ruby-identifier">l</span>
|
||||
139: <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">each_pair</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>,<span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">delete</span> <span class="ruby-identifier">k</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">v</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">l</span>}
|
||||
140: }
|
||||
141: <span class="ruby-keyword kw">end</span>
|
||||
142: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000007" class="method-detail">
|
||||
<a name="M000007"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000007" class="method-signature">
|
||||
<span class="method-name">clear_strings_except</span><span class="method-args">(*languages)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Removes all localized strings from memory, except for those of certain
|
||||
specified languages.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000007-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 146</span>
|
||||
146: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">clear_strings_except</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">languages</span>)
|
||||
147: <span class="ruby-identifier">clear</span>= (<span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">keys</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">languages</span>)
|
||||
148: <span class="ruby-identifier">_clear_strings</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">clear</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">clear</span>.<span class="ruby-identifier">empty?</span>
|
||||
149: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000003" class="method-detail">
|
||||
<a name="M000003"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000003" class="method-signature">
|
||||
<span class="method-name">current_language</span><span class="method-args">()</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns the default language
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000003-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 108</span>
|
||||
108: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
|
||||
109: <span class="ruby-constant">GLoc</span><span class="ruby-operator">::</span><span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:default_language</span>]
|
||||
110: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000008" class="method-detail">
|
||||
<a name="M000008"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000008" class="method-signature">
|
||||
<span class="method-name">get_charset</span><span class="method-args">(lang)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns the charset used to store localized strings in memory.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000008-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 152</span>
|
||||
152: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">lang</span>)
|
||||
153: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>][<span class="ruby-identifier">lang</span>] <span class="ruby-operator">||</span> <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset</span>]
|
||||
154: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000009" class="method-detail">
|
||||
<a name="M000009"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000009" class="method-signature">
|
||||
<span class="method-name">get_config</span><span class="method-args">(key)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns a <a href="GLoc.html">GLoc</a> configuration value.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000009-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000009-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 157</span>
|
||||
157: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">get_config</span>(<span class="ruby-identifier">key</span>)
|
||||
158: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">key</span>]
|
||||
159: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000010" class="method-detail">
|
||||
<a name="M000010"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000010" class="method-signature">
|
||||
<span class="method-name">load_gloc_default_localized_strings</span><span class="method-args">(override=false)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Loads the localized strings that are included in the <a
|
||||
href="GLoc.html">GLoc</a> library.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000010-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000010-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 162</span>
|
||||
162: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">load_gloc_default_localized_strings</span>(<span class="ruby-identifier">override</span>=<span class="ruby-keyword kw">false</span>)
|
||||
163: <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">load_localized_strings</span> <span class="ruby-node">"#{File.dirname(__FILE__)}/../lang"</span>, <span class="ruby-identifier">override</span>
|
||||
164: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000011" class="method-detail">
|
||||
<a name="M000011"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000011" class="method-signature">
|
||||
<span class="method-name">load_localized_strings</span><span class="method-args">(dir=nil, override=true)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Loads localized strings from all yml files in the specifed directory.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000011-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000011-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 167</span>
|
||||
167: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">load_localized_strings</span>(<span class="ruby-identifier">dir</span>=<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">override</span>=<span class="ruby-keyword kw">true</span>)
|
||||
168: <span class="ruby-identifier">_charset_required</span>
|
||||
169: <span class="ruby-identifier">_get_lang_file_list</span>(<span class="ruby-identifier">dir</span>).<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">filename</span><span class="ruby-operator">|</span>
|
||||
170:
|
||||
171: <span class="ruby-comment cmt"># Load file</span>
|
||||
172: <span class="ruby-identifier">raw_hash</span> = <span class="ruby-constant">YAML</span><span class="ruby-operator">::</span><span class="ruby-identifier">load</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-identifier">filename</span>))
|
||||
173: <span class="ruby-identifier">raw_hash</span>={} <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">raw_hash</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Hash</span>)
|
||||
174: <span class="ruby-identifier">filename</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/([^\/\\]+)\.ya?ml$/</span>
|
||||
175: <span class="ruby-identifier">lang</span> = <span class="ruby-identifier">$1</span>.<span class="ruby-identifier">to_sym</span>
|
||||
176: <span class="ruby-identifier">file_charset</span> = <span class="ruby-identifier">raw_hash</span>[<span class="ruby-value str">'file_charset'</span>] <span class="ruby-operator">||</span> <span class="ruby-constant">UTF_8</span>
|
||||
177:
|
||||
178: <span class="ruby-comment cmt"># Convert string keys to symbols</span>
|
||||
179: <span class="ruby-identifier">dest_charset</span>= <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">lang</span>)
|
||||
180: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"Reading file #{filename} [charset: #{file_charset} --> #{dest_charset}]"</span>}
|
||||
181: <span class="ruby-identifier">symbol_hash</span> = {}
|
||||
182: <span class="ruby-constant">Iconv</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">dest_charset</span>, <span class="ruby-identifier">file_charset</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
|
||||
183: <span class="ruby-identifier">raw_hash</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
|
||||
184: <span class="ruby-identifier">symbol_hash</span>[<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_sym</span>] = <span class="ruby-identifier">i</span>.<span class="ruby-identifier">iconv</span>(<span class="ruby-identifier">value</span>)
|
||||
185: }
|
||||
186: <span class="ruby-keyword kw">end</span>
|
||||
187:
|
||||
188: <span class="ruby-comment cmt"># Add strings to repos</span>
|
||||
189: <span class="ruby-identifier">_add_localized_strings</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol_hash</span>, <span class="ruby-identifier">override</span>)
|
||||
190: }
|
||||
191: <span class="ruby-identifier">_verbose_msg</span> <span class="ruby-identifier">:stats</span>
|
||||
192: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000012" class="method-detail">
|
||||
<a name="M000012"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000012" class="method-signature">
|
||||
<span class="method-name">restore_state</span><span class="method-args">(state)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Restores a backup of <a href="GLoc.html">GLoc</a>’s internal state
|
||||
that was made with <a href="GLoc.html#M000005">backup_state</a>.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000012-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000012-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 195</span>
|
||||
195: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">restore_state</span>(<span class="ruby-identifier">state</span>)
|
||||
196: <span class="ruby-identifier">_get_internal_state_vars</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span>
|
||||
197: <span class="ruby-identifier">o</span>.<span class="ruby-identifier">clear</span>
|
||||
198: <span class="ruby-identifier">o</span>.<span class="ruby-identifier">send</span> <span class="ruby-identifier">o</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">:merge!</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">:merge!</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">:concat</span>, <span class="ruby-identifier">state</span>.<span class="ruby-identifier">shift</span>
|
||||
199: <span class="ruby-keyword kw">end</span>
|
||||
200: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000013" class="method-detail">
|
||||
<a name="M000013"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000013" class="method-signature">
|
||||
<span class="method-name">set_charset</span><span class="method-args">(new_charset, *langs)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Sets the charset used to internally store localized strings. You can set
|
||||
the charset to use for a specific language or languages, or if none are
|
||||
specified the charset for ALL localized strings will be set.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000013-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000013-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 205</span>
|
||||
205: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_charset</span>(<span class="ruby-identifier">new_charset</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">langs</span>)
|
||||
206: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>] <span class="ruby-operator">||=</span> {}
|
||||
207:
|
||||
208: <span class="ruby-comment cmt"># Convert symbol shortcuts</span>
|
||||
209: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">new_charset</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>)
|
||||
210: <span class="ruby-identifier">new_charset</span>= <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">new_charset</span>
|
||||
211: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:utf8</span>, <span class="ruby-identifier">:utf_8</span> <span class="ruby-keyword kw">then</span> <span class="ruby-constant">UTF_8</span>
|
||||
212: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:sjis</span>, <span class="ruby-identifier">:shift_jis</span>, <span class="ruby-identifier">:shiftjis</span> <span class="ruby-keyword kw">then</span> <span class="ruby-constant">SHIFT_JIS</span>
|
||||
213: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:eucjp</span>, <span class="ruby-identifier">:euc_jp</span> <span class="ruby-keyword kw">then</span> <span class="ruby-constant">EUC_JP</span>
|
||||
214: <span class="ruby-keyword kw">else</span> <span class="ruby-identifier">new_charset</span>.<span class="ruby-identifier">to_s</span>
|
||||
215: <span class="ruby-keyword kw">end</span>
|
||||
216: <span class="ruby-keyword kw">end</span>
|
||||
217:
|
||||
218: <span class="ruby-comment cmt"># Convert existing strings</span>
|
||||
219: (<span class="ruby-identifier">langs</span>.<span class="ruby-identifier">empty?</span> <span class="ruby-value">? </span><span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">keys</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">langs</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">lang</span><span class="ruby-operator">|</span>
|
||||
220: <span class="ruby-identifier">cur_charset</span>= <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">lang</span>)
|
||||
221: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">cur_charset</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">new_charset</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">cur_charset</span>
|
||||
222: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"Converting :#{lang} strings from #{cur_charset} to #{new_charset}"</span>}
|
||||
223: <span class="ruby-constant">Iconv</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">new_charset</span>, <span class="ruby-identifier">cur_charset</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
|
||||
224: <span class="ruby-identifier">bundle</span>= <span class="ruby-constant">LOCALIZED_STRINGS</span>[<span class="ruby-identifier">lang</span>]
|
||||
225: <span class="ruby-identifier">bundle</span>.<span class="ruby-identifier">each_pair</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>,<span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-identifier">bundle</span>[<span class="ruby-identifier">k</span>]= <span class="ruby-identifier">i</span>.<span class="ruby-identifier">iconv</span>(<span class="ruby-identifier">v</span>)}
|
||||
226: <span class="ruby-keyword kw">end</span>
|
||||
227: <span class="ruby-keyword kw">end</span>
|
||||
228: <span class="ruby-keyword kw">end</span>
|
||||
229:
|
||||
230: <span class="ruby-comment cmt"># Set new charset value</span>
|
||||
231: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">langs</span>.<span class="ruby-identifier">empty?</span>
|
||||
232: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"Setting GLoc charset for all languages to #{new_charset}"</span>}
|
||||
233: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset</span>]= <span class="ruby-identifier">new_charset</span>
|
||||
234: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>].<span class="ruby-identifier">clear</span>
|
||||
235: <span class="ruby-keyword kw">else</span>
|
||||
236: <span class="ruby-identifier">langs</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">lang</span><span class="ruby-operator">|</span>
|
||||
237: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"Setting GLoc charset for :#{lang} strings to #{new_charset}"</span>}
|
||||
238: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>][<span class="ruby-identifier">lang</span>]= <span class="ruby-identifier">new_charset</span>
|
||||
239: <span class="ruby-keyword kw">end</span>
|
||||
240: <span class="ruby-keyword kw">end</span>
|
||||
241: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000014" class="method-detail">
|
||||
<a name="M000014"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000014" class="method-signature">
|
||||
<span class="method-name">set_config</span><span class="method-args">(hash)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Sets <a href="GLoc.html">GLoc</a> configuration values.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000014-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000014-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 244</span>
|
||||
244: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_config</span>(<span class="ruby-identifier">hash</span>)
|
||||
245: <span class="ruby-constant">CONFIG</span>.<span class="ruby-identifier">merge!</span> <span class="ruby-identifier">hash</span>
|
||||
246: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000015" class="method-detail">
|
||||
<a name="M000015"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000015" class="method-signature">
|
||||
<span class="method-name">set_kcode</span><span class="method-args">(charset=nil)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Sets the $KCODE global variable according to a specified charset, or else
|
||||
the current default charset for the default language.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000015-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000015-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 250</span>
|
||||
250: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_kcode</span>(<span class="ruby-identifier">charset</span>=<span class="ruby-keyword kw">nil</span>)
|
||||
251: <span class="ruby-identifier">_charset_required</span>
|
||||
252: <span class="ruby-identifier">charset</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">current_language</span>)
|
||||
253: <span class="ruby-identifier">$KCODE</span>= <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">charset</span>
|
||||
254: <span class="ruby-keyword kw">when</span> <span class="ruby-constant">UTF_8</span> <span class="ruby-keyword kw">then</span> <span class="ruby-value str">'u'</span>
|
||||
255: <span class="ruby-keyword kw">when</span> <span class="ruby-constant">SHIFT_JIS</span> <span class="ruby-keyword kw">then</span> <span class="ruby-value str">'s'</span>
|
||||
256: <span class="ruby-keyword kw">when</span> <span class="ruby-constant">EUC_JP</span> <span class="ruby-keyword kw">then</span> <span class="ruby-value str">'e'</span>
|
||||
257: <span class="ruby-keyword kw">else</span> <span class="ruby-value str">'n'</span>
|
||||
258: <span class="ruby-keyword kw">end</span>
|
||||
259: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">"$KCODE set to #{$KCODE}"</span>}
|
||||
260: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000016" class="method-detail">
|
||||
<a name="M000016"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000016" class="method-signature">
|
||||
<span class="method-name">similar_language</span><span class="method-args">(lang)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Tries to find a valid language that is similar to the argument passed. Eg.
|
||||
:en, :en_au, :EN_US are all similar languages. Returns <tt>nil</tt> if no
|
||||
similar languages are found.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000016-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000016-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 265</span>
|
||||
265: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">similar_language</span>(<span class="ruby-identifier">lang</span>)
|
||||
266: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">nil</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">nil?</span>
|
||||
267: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">valid_language?</span>(<span class="ruby-identifier">lang</span>)
|
||||
268: <span class="ruby-comment cmt"># Check lowercase without dashes</span>
|
||||
269: <span class="ruby-identifier">lang</span>= <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">downcase</span>.<span class="ruby-identifier">gsub</span>(<span class="ruby-value str">'-'</span>,<span class="ruby-value str">'_'</span>)
|
||||
270: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>[<span class="ruby-identifier">lang</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">lang</span>)
|
||||
271: <span class="ruby-comment cmt"># Check without dialect</span>
|
||||
272: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^([a-z]+?)[^a-z].*/</span>
|
||||
273: <span class="ruby-identifier">lang</span>= <span class="ruby-identifier">$1</span>
|
||||
274: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>[<span class="ruby-identifier">lang</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">lang</span>)
|
||||
275: <span class="ruby-keyword kw">end</span>
|
||||
276: <span class="ruby-comment cmt"># Check other dialects</span>
|
||||
277: <span class="ruby-identifier">lang</span>= <span class="ruby-node">"#{lang}_"</span>
|
||||
278: <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span><span class="ruby-operator">|</span> <span class="ruby-keyword kw">return</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>[<span class="ruby-identifier">k</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">k</span>.<span class="ruby-identifier">starts_with?</span>(<span class="ruby-identifier">lang</span>)}
|
||||
279: <span class="ruby-comment cmt"># Nothing found</span>
|
||||
280: <span class="ruby-keyword kw">nil</span>
|
||||
281: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000018" class="method-detail">
|
||||
<a name="M000018"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000018" class="method-signature">
|
||||
<span class="method-name">valid_language?</span><span class="method-args">(language)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns <tt>true</tt> if there are any localized strings for a specified
|
||||
language. Note that although <tt>set_langauge nil</tt> is perfectly valid,
|
||||
<tt>nil</tt> is not a valid language.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000018-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000018-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 290</span>
|
||||
290: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">valid_language?</span>(<span class="ruby-identifier">language</span>)
|
||||
291: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">has_key?</span> <span class="ruby-identifier">language</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">rescue</span> <span class="ruby-keyword kw">false</span>
|
||||
292: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000017" class="method-detail">
|
||||
<a name="M000017"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000017" class="method-signature">
|
||||
<span class="method-name">valid_languages</span><span class="method-args">()</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns an array of (currently) valid languages (ie. languages for which
|
||||
localized data exists).
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000017-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000017-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 284</span>
|
||||
284: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">valid_languages</span>
|
||||
285: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">keys</span>
|
||||
286: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000002" class="method-detail">
|
||||
<a name="M000002"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000002" class="method-signature">
|
||||
<span class="method-name">current_language</span><span class="method-args">()</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns the instance-level current language, or if not set, returns the
|
||||
class-level current language.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000002-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000002-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 77</span>
|
||||
77: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
|
||||
78: <span class="ruby-ivar">@gloc_language</span> <span class="ruby-operator">||</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">current_language</span>
|
||||
79: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: GLoc::ClassMethods</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">GLoc::ClassMethods</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../files/lib/gloc_rb.html">
|
||||
lib/gloc.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
All classes/modules that include <a href="../GLoc.html">GLoc</a> will also
|
||||
gain these class methods. Notice that the <a
|
||||
href="InstanceMethods.html">GLoc::InstanceMethods</a> module is also
|
||||
included.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000019">current_language</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="InstanceMethods.html">::GLoc::InstanceMethods</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000019" class="method-detail">
|
||||
<a name="M000019"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000019" class="method-signature">
|
||||
<span class="method-name">current_language</span><span class="method-args">()</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns the current language, or if not set, returns the <a
|
||||
href="../GLoc.html">GLoc</a> current language.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000019-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000019-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 89</span>
|
||||
89: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
|
||||
90: <span class="ruby-ivar">@gloc_language</span> <span class="ruby-operator">||</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">current_language</span>
|
||||
91: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,323 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: GLoc::Helpers</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">GLoc::Helpers</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../files/lib/gloc-helpers_rb.html">
|
||||
lib/gloc-helpers.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
These helper methods will be included in the <a
|
||||
href="InstanceMethods.html">InstanceMethods</a> module.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000026">l_YesNo</a>
|
||||
<a href="#M000020">l_age</a>
|
||||
<a href="#M000021">l_date</a>
|
||||
<a href="#M000022">l_datetime</a>
|
||||
<a href="#M000023">l_datetime_short</a>
|
||||
<a href="#M000028">l_lang_name</a>
|
||||
<a href="#M000024">l_strftime</a>
|
||||
<a href="#M000025">l_time</a>
|
||||
<a href="#M000027">l_yesno</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000026" class="method-detail">
|
||||
<a name="M000026"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000026" class="method-signature">
|
||||
<span class="method-name">l_YesNo</span><span class="method-args">(value)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000026-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000026-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 12</span>
|
||||
12: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_YesNo</span>(<span class="ruby-identifier">value</span>) <span class="ruby-identifier">l</span>(<span class="ruby-identifier">value</span> <span class="ruby-value">? </span><span class="ruby-operator">:</span><span class="ruby-identifier">general_text_Yes</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">:general_text_No</span>) <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000020" class="method-detail">
|
||||
<a name="M000020"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000020" class="method-signature">
|
||||
<span class="method-name">l_age</span><span class="method-args">(age)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000020-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000020-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 6</span>
|
||||
6: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_age</span>(<span class="ruby-identifier">age</span>) <span class="ruby-identifier">lwr</span> <span class="ruby-operator">:</span><span class="ruby-identifier">general_fmt_age</span>, <span class="ruby-identifier">age</span> <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000021" class="method-detail">
|
||||
<a name="M000021"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000021" class="method-signature">
|
||||
<span class="method-name">l_date</span><span class="method-args">(date)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000021-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000021-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 7</span>
|
||||
7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_date</span>(<span class="ruby-identifier">date</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">date</span>, <span class="ruby-identifier">:general_fmt_date</span> <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000022" class="method-detail">
|
||||
<a name="M000022"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000022" class="method-signature">
|
||||
<span class="method-name">l_datetime</span><span class="method-args">(date)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000022-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000022-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 8</span>
|
||||
8: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_datetime</span>(<span class="ruby-identifier">date</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">date</span>, <span class="ruby-identifier">:general_fmt_datetime</span> <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000023" class="method-detail">
|
||||
<a name="M000023"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000023" class="method-signature">
|
||||
<span class="method-name">l_datetime_short</span><span class="method-args">(date)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000023-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000023-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 9</span>
|
||||
9: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_datetime_short</span>(<span class="ruby-identifier">date</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">date</span>, <span class="ruby-identifier">:general_fmt_datetime_short</span> <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000028" class="method-detail">
|
||||
<a name="M000028"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000028" class="method-signature">
|
||||
<span class="method-name">l_lang_name</span><span class="method-args">(lang, display_lang=nil)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000028-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000028-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 15</span>
|
||||
15: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_lang_name</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">display_lang</span>=<span class="ruby-keyword kw">nil</span>)
|
||||
16: <span class="ruby-identifier">ll</span> <span class="ruby-identifier">display_lang</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">current_language</span>, <span class="ruby-node">"general_lang_#{lang}"</span>
|
||||
17: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000024" class="method-detail">
|
||||
<a name="M000024"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000024" class="method-signature">
|
||||
<span class="method-name">l_strftime</span><span class="method-args">(date,fmt)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000024-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000024-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 10</span>
|
||||
10: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_strftime</span>(<span class="ruby-identifier">date</span>,<span class="ruby-identifier">fmt</span>) <span class="ruby-identifier">date</span>.<span class="ruby-identifier">strftime</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">fmt</span>) <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000025" class="method-detail">
|
||||
<a name="M000025"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000025" class="method-signature">
|
||||
<span class="method-name">l_time</span><span class="method-args">(time)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000025-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000025-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 11</span>
|
||||
11: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_time</span>(<span class="ruby-identifier">time</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">time</span>, <span class="ruby-identifier">:general_fmt_time</span> <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000027" class="method-detail">
|
||||
<a name="M000027"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000027" class="method-signature">
|
||||
<span class="method-name">l_yesno</span><span class="method-args">(value)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000027-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000027-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 13</span>
|
||||
13: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_yesno</span>(<span class="ruby-identifier">value</span>) <span class="ruby-identifier">l</span>(<span class="ruby-identifier">value</span> <span class="ruby-value">? </span><span class="ruby-operator">:</span><span class="ruby-identifier">general_text_yes</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">:general_text_no</span>) <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Module: GLoc::InstanceMethods</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="classHeader">
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Module</strong></td>
|
||||
<td class="class-name-in-header">GLoc::InstanceMethods</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>In:</strong></td>
|
||||
<td>
|
||||
<a href="../../files/lib/gloc_rb.html">
|
||||
lib/gloc.rb
|
||||
</a>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
This module will be included in both instances and classes of <a
|
||||
href="../GLoc.html">GLoc</a> includees. It is also included as class
|
||||
methods in the <a href="../GLoc.html">GLoc</a> module itself.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="method-list">
|
||||
<h3 class="section-bar">Methods</h3>
|
||||
|
||||
<div class="name-list">
|
||||
<a href="#M000029">l</a>
|
||||
<a href="#M000034">l_has_string?</a>
|
||||
<a href="#M000030">ll</a>
|
||||
<a href="#M000031">ltry</a>
|
||||
<a href="#M000032">lwr</a>
|
||||
<a href="#M000033">lwr_</a>
|
||||
<a href="#M000035">set_language</a>
|
||||
<a href="#M000036">set_language_if_valid</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
<div id="includes">
|
||||
<h3 class="section-bar">Included Modules</h3>
|
||||
|
||||
<div id="includes-list">
|
||||
<span class="include-name"><a href="Helpers.html">Helpers</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
<div id="methods">
|
||||
<h3 class="section-bar">Public Instance methods</h3>
|
||||
|
||||
<div id="method-M000029" class="method-detail">
|
||||
<a name="M000029"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000029" class="method-signature">
|
||||
<span class="method-name">l</span><span class="method-args">(symbol, *arguments)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns a localized string.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000029-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000029-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 18</span>
|
||||
18: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
19: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l</span>(<span class="ruby-identifier">symbol</span>,<span class="ruby-identifier">current_language</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
20: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000034" class="method-detail">
|
||||
<a name="M000034"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000034" class="method-signature">
|
||||
<span class="method-name">l_has_string?</span><span class="method-args">(symbol)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns <tt>true</tt> if a localized string with the specified key exists.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000034-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000034-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 48</span>
|
||||
48: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_has_string?</span>(<span class="ruby-identifier">symbol</span>)
|
||||
49: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l_has_string?</span>(<span class="ruby-identifier">symbol</span>,<span class="ruby-identifier">current_language</span>)
|
||||
50: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000030" class="method-detail">
|
||||
<a name="M000030"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000030" class="method-signature">
|
||||
<span class="method-name">ll</span><span class="method-args">(lang, symbol, *arguments)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns a localized string in a specified language. This does not effect
|
||||
<tt>current_language</tt>.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000030-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000030-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 24</span>
|
||||
24: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">ll</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
25: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l</span>(<span class="ruby-identifier">symbol</span>,<span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_sym</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
26: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000031" class="method-detail">
|
||||
<a name="M000031"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000031" class="method-signature">
|
||||
<span class="method-name">ltry</span><span class="method-args">(possible_key)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Returns a localized string if the argument is a Symbol, else just returns
|
||||
the argument.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000031-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000031-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 29</span>
|
||||
29: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">ltry</span>(<span class="ruby-identifier">possible_key</span>)
|
||||
30: <span class="ruby-identifier">possible_key</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">possible_key</span>) <span class="ruby-operator">:</span> <span class="ruby-identifier">possible_key</span>
|
||||
31: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000032" class="method-detail">
|
||||
<a name="M000032"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000032" class="method-signature">
|
||||
<span class="method-name">lwr</span><span class="method-args">(symbol, *arguments)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Uses the default <a href="../GLoc.html">GLoc</a> rule to return a localized
|
||||
string. See lwr_() for more info.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000032-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000032-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 35</span>
|
||||
35: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
36: <span class="ruby-identifier">lwr_</span>(<span class="ruby-identifier">:default</span>, <span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
37: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000033" class="method-detail">
|
||||
<a name="M000033"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000033" class="method-signature">
|
||||
<span class="method-name">lwr_</span><span class="method-args">(rule, symbol, *arguments)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Uses a <em>rule</em> to return a localized string. A rule is a function
|
||||
that uses specified arguments to return a localization key prefix. The
|
||||
prefix is appended to the localization key originally specified, to create
|
||||
a new key which is then used to lookup a localized string.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000033-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000033-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 43</span>
|
||||
43: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">lwr_</span>(<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
44: <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l</span>(<span class="ruby-node">"#{symbol}#{GLoc::_l_rule(rule,current_language).call(*arguments)}"</span>,<span class="ruby-identifier">current_language</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
|
||||
45: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000035" class="method-detail">
|
||||
<a name="M000035"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000035" class="method-signature">
|
||||
<span class="method-name">set_language</span><span class="method-args">(language)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Sets the current language for this instance/class. Setting the language of
|
||||
a class effects all instances unless the instance has its own language
|
||||
defined.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000035-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000035-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 54</span>
|
||||
54: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_language</span>(<span class="ruby-identifier">language</span>)
|
||||
55: <span class="ruby-ivar">@gloc_language</span>= <span class="ruby-identifier">language</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-value">? </span><span class="ruby-keyword kw">nil</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">language</span>.<span class="ruby-identifier">to_sym</span>
|
||||
56: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="method-M000036" class="method-detail">
|
||||
<a name="M000036"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<a href="#M000036" class="method-signature">
|
||||
<span class="method-name">set_language_if_valid</span><span class="method-args">(language)</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<p>
|
||||
Sets the current language if the language passed is a valid language. If
|
||||
the language was valid, this method returns <tt>true</tt> else it will
|
||||
return <tt>false</tt>. Note that <tt>nil</tt> is not a valid language. See
|
||||
<a href="InstanceMethods.html#M000035">set_language</a>(language) for more
|
||||
info.
|
||||
</p>
|
||||
<p><a class="source-toggle" href="#"
|
||||
onclick="toggleCode('M000036-source');return false;">[Source]</a></p>
|
||||
<div class="method-source-code" id="M000036-source">
|
||||
<pre>
|
||||
<span class="ruby-comment cmt"># File lib/gloc.rb, line 62</span>
|
||||
62: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_language_if_valid</span>(<span class="ruby-identifier">language</span>)
|
||||
63: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">valid_language?</span>(<span class="ruby-identifier">language</span>)
|
||||
64: <span class="ruby-identifier">set_language</span>(<span class="ruby-identifier">language</span>)
|
||||
65: <span class="ruby-keyword kw">true</span>
|
||||
66: <span class="ruby-keyword kw">else</span>
|
||||
67: <span class="ruby-keyword kw">false</span>
|
||||
68: <span class="ruby-keyword kw">end</span>
|
||||
69: <span class="ruby-keyword kw">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Sun May 28 15:21:13 E. Australia Standard Time 2006
|
||||
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: CHANGELOG</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>CHANGELOG</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>CHANGELOG
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<h2>Version 1.1 (28 May 2006)</h2>
|
||||
<ul>
|
||||
<li>The charset for each and/or all languages can now be easily configured.
|
||||
|
||||
</li>
|
||||
<li>Added a ActionController filter that auto-detects the client language.
|
||||
|
||||
</li>
|
||||
<li>The rake task "sort" now merges lines that match 100%, and warns
|
||||
if duplicate keys are found.
|
||||
|
||||
</li>
|
||||
<li>Rule support. Create flexible rules to handle issues such as pluralization.
|
||||
|
||||
</li>
|
||||
<li>Massive speed and stability improvements to development mode.
|
||||
|
||||
</li>
|
||||
<li>Added Russian strings. (Thanks to Evgeny Lineytsev)
|
||||
|
||||
</li>
|
||||
<li>Complete RDoc documentation.
|
||||
|
||||
</li>
|
||||
<li>Improved helpers.
|
||||
|
||||
</li>
|
||||
<li><a href="../classes/GLoc.html">GLoc</a> now configurable via get_config and
|
||||
set_config
|
||||
|
||||
</li>
|
||||
<li>Added an option to tell <a href="../classes/GLoc.html">GLoc</a> to output
|
||||
various verbose information.
|
||||
|
||||
</li>
|
||||
<li>More useful functions such as set_language_if_valid, similar_language
|
||||
|
||||
</li>
|
||||
<li><a href="../classes/GLoc.html">GLoc</a>’s entire internal state can
|
||||
now be backed up and restored.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Version 1.0 (17 April 2006)</h2>
|
||||
<ul>
|
||||
<li>Initial public release.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,480 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: README</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>README</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>README
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<h1>About</h1>
|
||||
<h3>Preface</h3>
|
||||
<p>
|
||||
I originally started designing this on weekends and after work in 2005. We
|
||||
started to become very interested in Rails at work and I wanted to get some
|
||||
experience with ruby with before we started using it full-time. I
|
||||
didn’t have very many ideas for anything interesting to create so,
|
||||
because we write a lot of multilingual webapps at my company, I decided to
|
||||
write a localization library. That way if my little hobby project developed
|
||||
into something decent, I could at least put it to good use. And here we are
|
||||
in 2006, my little hobby project has come a long way and become quite a
|
||||
useful piece of software. Not only do I use it in production sites I write
|
||||
at work, but I also prefer it to other existing alternatives. Therefore I
|
||||
have decided to make it publicly available, and I hope that other
|
||||
developers will find it useful too.
|
||||
</p>
|
||||
<h3>About</h3>
|
||||
<p>
|
||||
<a href="../classes/GLoc.html">GLoc</a> is a localization library. It
|
||||
doesn’t aim to do everything l10n-related that you can imagine, but
|
||||
what it does, it does very well. It was originally designed as a Rails
|
||||
plugin, but can also be used for plain ruby projects. Here are a list of
|
||||
its main features:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Lightweight and efficient.
|
||||
|
||||
</li>
|
||||
<li>Uses file-based string bundles. Strings can also be set directly.
|
||||
|
||||
</li>
|
||||
<li>Intelligent, cascading language configuration.
|
||||
|
||||
</li>
|
||||
<li>Create flexible rules to handle issues such as pluralization.
|
||||
|
||||
</li>
|
||||
<li>Includes a ActionController filter that auto-detects the client language.
|
||||
|
||||
</li>
|
||||
<li>Works perfectly with Rails Engines and allows strings to be overridden just
|
||||
as easily as controllers, models, etc.
|
||||
|
||||
</li>
|
||||
<li>Automatically localizes Rails functions such as distance_in_minutes,
|
||||
select_month etc
|
||||
|
||||
</li>
|
||||
<li>Supports different charsets. You can even specify the encoding to use for
|
||||
each language seperately.
|
||||
|
||||
</li>
|
||||
<li>Special Rails mods/helpers.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>What does <a href="../classes/GLoc.html">GLoc</a> mean?</h3>
|
||||
<p>
|
||||
If you’re wondering about the name "<a
|
||||
href="../classes/GLoc.html">GLoc</a>", I’m sure you’re not
|
||||
alone. This project was originally just called "Localization"
|
||||
which was a bit too common, so when I decided to release it I decided to
|
||||
call it "Golly’s Localization Library" instead (Golly is my
|
||||
nickname), and that was long and boring so I then abbreviated that to
|
||||
"<a href="../classes/GLoc.html">GLoc</a>". What a fun story!!
|
||||
</p>
|
||||
<h3>Localization helpers</h3>
|
||||
<p>
|
||||
This also includes a few helpers for common situations such as displaying
|
||||
localized date, time, "yes" or "no", etc.
|
||||
</p>
|
||||
<h3>Rails Localization</h3>
|
||||
<p>
|
||||
At the moment, unless you manually remove the <tt>require
|
||||
‘gloc-rails-text’</tt> line from init.rb, this plugin overrides
|
||||
certain Rails functions to provide multilingual versions. This
|
||||
automatically localizes functions such as select_date(),
|
||||
distance_of_time_in_words() and more… The strings can be found in
|
||||
lang/*.yml. NOTE: This is not complete. Timezones and countries are not
|
||||
currently localized.
|
||||
</p>
|
||||
<h1>Usage</h1>
|
||||
<h3>Quickstart</h3>
|
||||
<p>
|
||||
Windows users will need to first install iconv. <a
|
||||
href="http://wiki.rubyonrails.com/rails/pages/iconv">wiki.rubyonrails.com/rails/pages/iconv</a>
|
||||
</p>
|
||||
<ul>
|
||||
<li>Create a dir "#{RAILS_ROOT}/lang"
|
||||
|
||||
</li>
|
||||
<li>Create a file "#{RAILS_ROOT}/lang/en.yml" and write your strings.
|
||||
The format is "key: string". Save it as UTF-8. If you save it in
|
||||
a different encoding, add a key called file_charset (eg.
|
||||
"file_charset: iso-2022-jp")
|
||||
|
||||
</li>
|
||||
<li>Put the following in config/environment.rb and change the values as you see
|
||||
fit. The following example is for an app that uses English and Japanese,
|
||||
with Japanese being the default.
|
||||
|
||||
<pre>
|
||||
GLoc.set_config :default_language => :ja
|
||||
GLoc.clear_strings_except :en, :ja
|
||||
GLoc.set_kcode
|
||||
GLoc.load_localized_strings
|
||||
</pre>
|
||||
</li>
|
||||
<li>Add ‘include <a href="../classes/GLoc.html">GLoc</a>’ to all
|
||||
classes that will use localization. This is added to most Rails classes
|
||||
automatically.
|
||||
|
||||
</li>
|
||||
<li>Optionally, you can set the language for models and controllers by simply
|
||||
inserting <tt>set_language :en</tt> in classes and/or methods.
|
||||
|
||||
</li>
|
||||
<li>To use localized strings, replace text such as <tt>"Welcome"</tt>
|
||||
with <tt>l(:welcome_string_key)</tt>, and <tt>"Hello
|
||||
#{name}."</tt> with <tt>l(:hello_string_key, name)</tt>. (Of course
|
||||
the strings will need to exist in your string bundle.)
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
There is more functionality provided by this plugin, that is not
|
||||
demonstrated above. Please read the API summary for details.
|
||||
</p>
|
||||
<h3>API summary</h3>
|
||||
<p>
|
||||
The following methods are added as both class methods and instance methods
|
||||
to modules/classes that include <a href="../classes/GLoc.html">GLoc</a>.
|
||||
They are also available as class methods of <a
|
||||
href="../classes/GLoc.html">GLoc</a>.
|
||||
</p>
|
||||
<pre>
|
||||
current_language # Returns the current language
|
||||
l(symbol, *arguments) # Returns a localized string
|
||||
ll(lang, symbol, *arguments) # Returns a localized string in a specific language
|
||||
ltry(possible_key) # Returns a localized string if passed a Symbol, else returns the same argument passed
|
||||
lwr(symbol, *arguments) # Uses the default rule to return a localized string.
|
||||
lwr_(rule, symbol, *arguments) # Uses a specified rule to return a localized string.
|
||||
l_has_string?(symbol) # Checks if a localized string exists
|
||||
set_language(language) # Sets the language for the current class or class instance
|
||||
set_language_if_valid(lang) # Sets the current language if the language passed is a valid language
|
||||
</pre>
|
||||
<p>
|
||||
The <a href="../classes/GLoc.html">GLoc</a> module also defines the
|
||||
following class methods:
|
||||
</p>
|
||||
<pre>
|
||||
add_localized_strings(lang, symbol_hash, override=true) # Adds a hash of localized strings
|
||||
backup_state(clear=false) # Creates a backup of GLoc's internal state and optionally clears everything too
|
||||
clear_strings(*languages) # Removes localized strings from memory
|
||||
clear_strings_except(*languages) # Removes localized strings from memory except for those of certain specified languages
|
||||
get_charset(lang) # Returns the charset used to store localized strings in memory
|
||||
get_config(key) # Returns a GLoc configuration value (see below)
|
||||
load_localized_strings(dir=nil, override=true) # Loads localized strings from all YML files in a given directory
|
||||
restore_state(state) # Restores a backup of GLoc's internal state
|
||||
set_charset(new_charset, *langs) # Sets the charset used to internally store localized strings
|
||||
set_config(hash) # Sets GLoc configuration values (see below)
|
||||
set_kcode(charset=nil) # Sets the $KCODE global variable
|
||||
similar_language(language) # Tries to find a valid language that is similar to the argument passed
|
||||
valid_languages # Returns an array of (currently) valid languages (ie. languages for which localized data exists)
|
||||
valid_language?(language) # Checks whether any localized strings are in memory for a given language
|
||||
</pre>
|
||||
<p>
|
||||
<a href="../classes/GLoc.html">GLoc</a> uses the following configuration
|
||||
items. They can be accessed via <tt>get_config</tt> and
|
||||
<tt>set_config</tt>.
|
||||
</p>
|
||||
<pre>
|
||||
:default_cookie_name
|
||||
:default_language
|
||||
:default_param_name
|
||||
:raise_string_not_found_errors
|
||||
:verbose
|
||||
</pre>
|
||||
<p>
|
||||
The <a href="../classes/GLoc.html">GLoc</a> module is automatically
|
||||
included in the following classes:
|
||||
</p>
|
||||
<pre>
|
||||
ActionController::Base
|
||||
ActionMailer::Base
|
||||
ActionView::Base
|
||||
ActionView::Helpers::InstanceTag
|
||||
ActiveRecord::Base
|
||||
ActiveRecord::Errors
|
||||
ApplicationHelper
|
||||
Test::Unit::TestCase
|
||||
</pre>
|
||||
<p>
|
||||
The <a href="../classes/GLoc.html">GLoc</a> module also defines the
|
||||
following controller filters:
|
||||
</p>
|
||||
<pre>
|
||||
autodetect_language_filter
|
||||
</pre>
|
||||
<p>
|
||||
<a href="../classes/GLoc.html">GLoc</a> also makes the following change to
|
||||
Rails:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Views for ActionMailer are now #{view_name}_#{language}.rb rather than just
|
||||
#{view_name}.rb
|
||||
|
||||
</li>
|
||||
<li>All ActiveRecord validation class methods now accept a localized string key
|
||||
(symbol) as a :message value.
|
||||
|
||||
</li>
|
||||
<li><a
|
||||
href="../classes/ActiveRecord/Errors.html#M000039">ActiveRecord::Errors.add</a>
|
||||
now accepts symbols as valid message values. At runtime these symbols are
|
||||
converted to localized strings using the current_language of the base
|
||||
record.
|
||||
|
||||
</li>
|
||||
<li><a
|
||||
href="../classes/ActiveRecord/Errors.html#M000039">ActiveRecord::Errors.add</a>
|
||||
now accepts arrays as arguments so that printf-style strings can be
|
||||
generated at runtime. This also applies to the validates_* class methods.
|
||||
|
||||
<pre>
|
||||
Eg. validates_xxxxxx_of :name, :message => ['Your name must be at least %d characters.', MIN_LEN]
|
||||
Eg. validates_xxxxxx_of :name, :message => [:user_error_validation_name_too_short, MIN_LEN]
|
||||
</pre>
|
||||
</li>
|
||||
<li>Instances of ActiveView inherit their current_language from the controller
|
||||
(or mailer) creating them.
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
This plugin also adds the following rake tasks:
|
||||
</p>
|
||||
<pre>
|
||||
* gloc:sort - Sorts the keys in the lang ymls (also accepts a DIR argument)
|
||||
</pre>
|
||||
<h3>Cascading language configuration</h3>
|
||||
<p>
|
||||
The language can be set at three levels:
|
||||
</p>
|
||||
<pre>
|
||||
1. The default # GLoc.get_config :default_language
|
||||
2. Class level # class A; set_language :de; end
|
||||
3. Instance level # b= B.new; b.set_language :zh
|
||||
</pre>
|
||||
<p>
|
||||
Instance level has the highest priority and the default has the lowest.
|
||||
</p>
|
||||
<p>
|
||||
Because <a href="../classes/GLoc.html">GLoc</a> is included at class level
|
||||
too, it becomes easy to associate languages with contexts. For example:
|
||||
</p>
|
||||
<pre>
|
||||
class Student
|
||||
set_language :en
|
||||
def say_hello
|
||||
puts "We say #{l :hello} but our teachers say #{Teacher.l :hello}"
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<h3>Rules</h3>
|
||||
<p>
|
||||
There are often situations when depending on the value of one or more
|
||||
variables, the surrounding text changes. The most common case of this is
|
||||
pluralization. Rather than hardcode these rules, they are completely
|
||||
definable by the user so that the user can eaasily accomodate for more
|
||||
complicated grammatical rules such as those found in Russian and Polish (or
|
||||
so I hear). To define a rule, simply include a string in the string bundle
|
||||
whose key begins with "<em>gloc_rule</em>" and then write ruby
|
||||
code as the value. The ruby code will be converted to a Proc when the
|
||||
string bundle is first read, and should return a prefix that will be
|
||||
appended to the string key at runtime to point to a new string. Make sense?
|
||||
Probably not… Please look at the following example and I am sure it
|
||||
will all make sense.
|
||||
</p>
|
||||
<p>
|
||||
Simple example (string bundle / en.yml)
|
||||
</p>
|
||||
<pre>
|
||||
_gloc_rule_default: ' |n| n==1 ? "_single" : "_plural" '
|
||||
man_count_plural: There are %d men.
|
||||
man_count_single: There is 1 man.
|
||||
</pre>
|
||||
<p>
|
||||
Simple example (code)
|
||||
</p>
|
||||
<pre>
|
||||
lwr(:man_count, 1) # => There is 1 man.
|
||||
lwr(:man_count, 8) # => There are 8 men.
|
||||
</pre>
|
||||
<p>
|
||||
To use rules other than the default simply call lwr_ instead of lwr, and
|
||||
specify the rule.
|
||||
</p>
|
||||
<p>
|
||||
Example 2 (string bundle / en.yml)
|
||||
</p>
|
||||
<pre>
|
||||
_gloc_rule_default: ' |n| n==1 ? "_single" : "_plural" '
|
||||
_gloc_rule_custom: ' |n| return "_none" if n==0; return "_heaps" if n>100; n==1 ? "_single" : "_plural" '
|
||||
man_count_none: There are no men.
|
||||
man_count_heaps: There are heaps of men!!
|
||||
man_count_plural: There are %d men.
|
||||
man_count_single: There is 1 man.
|
||||
</pre>
|
||||
<p>
|
||||
Example 2 (code)
|
||||
</p>
|
||||
<pre>
|
||||
lwr_(:custom, :man_count, 0) # => There are no men.
|
||||
lwr_(:custom, :man_count, 1) # => There is 1 man.
|
||||
lwr_(:custom, :man_count, 8) # => There are 8 men.
|
||||
lwr_(:custom, :man_count, 150) # => There are heaps of men!!
|
||||
</pre>
|
||||
<h3>Helpers</h3>
|
||||
<p>
|
||||
<a href="../classes/GLoc.html">GLoc</a> includes the following helpers:
|
||||
</p>
|
||||
<pre>
|
||||
l_age(age) # Returns a localized version of an age. eg "3 years old"
|
||||
l_date(date) # Returns a date in a localized format
|
||||
l_datetime(date) # Returns a date+time in a localized format
|
||||
l_datetime_short(date) # Returns a date+time in a localized short format.
|
||||
l_lang_name(l,dl=nil) # Returns the name of a language (you must supply your own strings)
|
||||
l_strftime(date,fmt) # Formats a date/time in a localized format.
|
||||
l_time(date) # Returns a time in a localized format
|
||||
l_YesNo(value) # Returns localized string of "Yes" or "No" depending on the arg
|
||||
l_yesno(value) # Returns localized string of "yes" or "no" depending on the arg
|
||||
</pre>
|
||||
<h3>Rails localization</h3>
|
||||
<p>
|
||||
Not all of Rails is covered but the following functions are:
|
||||
</p>
|
||||
<pre>
|
||||
distance_of_time_in_words
|
||||
select_day
|
||||
select_month
|
||||
select_year
|
||||
add_options
|
||||
</pre>
|
||||
<h1>FAQ</h1>
|
||||
<h4>How do I use it in engines?</h4>
|
||||
<p>
|
||||
Simply put this in your init_engine.rb
|
||||
</p>
|
||||
<pre>
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
</pre>
|
||||
<p>
|
||||
That way your engines strings will be loaded when the engine is started.
|
||||
Just simply make sure that you load your application strings after you
|
||||
start your engines to safely override any engine strings.
|
||||
</p>
|
||||
<h4>Why am I getting an Iconv::IllegalSequence error when calling <a href="../classes/GLoc.html#M000013">GLoc.set_charset</a>?</h4>
|
||||
<p>
|
||||
By default <a href="../classes/GLoc.html">GLoc</a> loads all of its default
|
||||
strings at startup. For example, calling <tt>set_charset
|
||||
‘iso-2022-jp’</tt> will cause this error because Russian
|
||||
strings are loaded by default, and the Russian strings use characters that
|
||||
cannot be expressed in the ISO-2022-JP charset. Before calling
|
||||
<tt>set_charset</tt> you should call <tt>clear_strings_except</tt> to
|
||||
remove strings from any languages that you will not be using.
|
||||
Alternatively, you can simply specify the language(s) as follows,
|
||||
<tt>set_charset ‘iso-2022-jp’, :ja</tt>.
|
||||
</p>
|
||||
<h4>How do I make <a href="../classes/GLoc.html">GLoc</a> ignore StringNotFoundErrors?</h4>
|
||||
<p>
|
||||
Disable it as follows:
|
||||
</p>
|
||||
<pre>
|
||||
GLoc.set_config :raise_string_not_found_errors => false
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc-helpers.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc-helpers.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc-helpers.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc-internal.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc-internal.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc-internal.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="requires-list">
|
||||
<h3 class="section-bar">Required files</h3>
|
||||
|
||||
<div class="name-list">
|
||||
iconv
|
||||
gloc-version
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc-rails-text.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc-rails-text.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc-rails-text.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="requires-list">
|
||||
<h3 class="section-bar">Required files</h3>
|
||||
|
||||
<div class="name-list">
|
||||
date
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc-rails.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc-rails.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc-rails.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="requires-list">
|
||||
<h3 class="section-bar">Required files</h3>
|
||||
|
||||
<div class="name-list">
|
||||
gloc
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc-ruby.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc-ruby.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc-ruby.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc-version.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc-version.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc-version.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>File: gloc.rb</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function popupCode( url ) {
|
||||
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
||||
}
|
||||
|
||||
function toggleCode( id ) {
|
||||
if ( document.getElementById )
|
||||
elem = document.getElementById( id );
|
||||
else if ( document.all )
|
||||
elem = eval( "document.all." + id );
|
||||
else
|
||||
return false;
|
||||
|
||||
elemStyle = elem.style;
|
||||
|
||||
if ( elemStyle.display != "block" ) {
|
||||
elemStyle.display = "block"
|
||||
} else {
|
||||
elemStyle.display = "none"
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make codeblocks hidden by default
|
||||
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="fileHeader">
|
||||
<h1>gloc.rb</h1>
|
||||
<table class="header-table">
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Path:</strong></td>
|
||||
<td>lib/gloc.rb
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="top-aligned-row">
|
||||
<td><strong>Last Update:</strong></td>
|
||||
<td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
|
||||
|
||||
|
||||
<div id="contextContent">
|
||||
|
||||
<div id="description">
|
||||
<p>
|
||||
Copyright © 2005-2006 David Barri
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="requires-list">
|
||||
<h3 class="section-bar">Required files</h3>
|
||||
|
||||
<div class="name-list">
|
||||
yaml
|
||||
gloc-internal
|
||||
gloc-helpers
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if includes -->
|
||||
|
||||
<div id="section">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- if method_list -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Classes
|
||||
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Classes</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
||||
<base target="docwin" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="index">
|
||||
<h1 class="section-bar">Classes</h1>
|
||||
<div id="index-entries">
|
||||
<a href="classes/ActionController/Filters/ClassMethods.html">ActionController::Filters::ClassMethods</a><br />
|
||||
<a href="classes/ActionMailer/Base.html">ActionMailer::Base</a><br />
|
||||
<a href="classes/ActionView/Base.html">ActionView::Base</a><br />
|
||||
<a href="classes/ActionView/Helpers/DateHelper.html">ActionView::Helpers::DateHelper</a><br />
|
||||
<a href="classes/ActionView/Helpers/InstanceTag.html">ActionView::Helpers::InstanceTag</a><br />
|
||||
<a href="classes/ActiveRecord/Errors.html">ActiveRecord::Errors</a><br />
|
||||
<a href="classes/ActiveRecord/Validations/ClassMethods.html">ActiveRecord::Validations::ClassMethods</a><br />
|
||||
<a href="classes/GLoc.html">GLoc</a><br />
|
||||
<a href="classes/GLoc/ClassMethods.html">GLoc::ClassMethods</a><br />
|
||||
<a href="classes/GLoc/Helpers.html">GLoc::Helpers</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html">GLoc::InstanceMethods</a><br />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Files
|
||||
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Files</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
||||
<base target="docwin" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="index">
|
||||
<h1 class="section-bar">Files</h1>
|
||||
<div id="index-entries">
|
||||
<a href="files/CHANGELOG.html">CHANGELOG</a><br />
|
||||
<a href="files/README.html">README</a><br />
|
||||
<a href="files/lib/gloc-helpers_rb.html">lib/gloc-helpers.rb</a><br />
|
||||
<a href="files/lib/gloc-internal_rb.html">lib/gloc-internal.rb</a><br />
|
||||
<a href="files/lib/gloc-rails-text_rb.html">lib/gloc-rails-text.rb</a><br />
|
||||
<a href="files/lib/gloc-rails_rb.html">lib/gloc-rails.rb</a><br />
|
||||
<a href="files/lib/gloc-ruby_rb.html">lib/gloc-ruby.rb</a><br />
|
||||
<a href="files/lib/gloc-version_rb.html">lib/gloc-version.rb</a><br />
|
||||
<a href="files/lib/gloc_rb.html">lib/gloc.rb</a><br />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Methods
|
||||
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Methods</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
||||
<base target="docwin" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="index">
|
||||
<h1 class="section-bar">Methods</h1>
|
||||
<div id="index-entries">
|
||||
<a href="classes/ActiveRecord/Errors.html#M000039">add (ActiveRecord::Errors)</a><br />
|
||||
<a href="classes/GLoc.html#M000004">add_localized_strings (GLoc)</a><br />
|
||||
<a href="classes/ActionController/Filters/ClassMethods.html#M000001">autodetect_language_filter (ActionController::Filters::ClassMethods)</a><br />
|
||||
<a href="classes/GLoc.html#M000005">backup_state (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000006">clear_strings (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000007">clear_strings_except (GLoc)</a><br />
|
||||
<a href="classes/GLoc/ClassMethods.html#M000019">current_language (GLoc::ClassMethods)</a><br />
|
||||
<a href="classes/GLoc.html#M000003">current_language (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000002">current_language (GLoc)</a><br />
|
||||
<a href="classes/ActionView/Helpers/InstanceTag.html#M000045">current_language (ActionView::Helpers::InstanceTag)</a><br />
|
||||
<a href="classes/ActiveRecord/Errors.html#M000040">current_language (ActiveRecord::Errors)</a><br />
|
||||
<a href="classes/ActionView/Helpers/DateHelper.html#M000041">distance_of_time_in_words (ActionView::Helpers::DateHelper)</a><br />
|
||||
<a href="classes/GLoc.html#M000008">get_charset (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000009">get_config (GLoc)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000029">l (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000026">l_YesNo (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000020">l_age (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000021">l_date (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000022">l_datetime (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000023">l_datetime_short (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000034">l_has_string? (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000028">l_lang_name (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000024">l_strftime (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000025">l_time (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/Helpers.html#M000027">l_yesno (GLoc::Helpers)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000030">ll (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc.html#M000010">load_gloc_default_localized_strings (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000011">load_localized_strings (GLoc)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000031">ltry (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000032">lwr (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000033">lwr_ (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/ActionView/Base.html#M000046">new (ActionView::Base)</a><br />
|
||||
<a href="classes/GLoc.html#M000012">restore_state (GLoc)</a><br />
|
||||
<a href="classes/ActionView/Helpers/DateHelper.html#M000042">select_day (ActionView::Helpers::DateHelper)</a><br />
|
||||
<a href="classes/ActionView/Helpers/DateHelper.html#M000043">select_month (ActionView::Helpers::DateHelper)</a><br />
|
||||
<a href="classes/ActionView/Helpers/DateHelper.html#M000044">select_year (ActionView::Helpers::DateHelper)</a><br />
|
||||
<a href="classes/GLoc.html#M000013">set_charset (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000014">set_config (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000015">set_kcode (GLoc)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000035">set_language (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc/InstanceMethods.html#M000036">set_language_if_valid (GLoc::InstanceMethods)</a><br />
|
||||
<a href="classes/GLoc.html#M000016">similar_language (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000018">valid_language? (GLoc)</a><br />
|
||||
<a href="classes/GLoc.html#M000017">valid_languages (GLoc)</a><br />
|
||||
<a href="classes/ActiveRecord/Validations/ClassMethods.html#M000037">validates_length_of (ActiveRecord::Validations::ClassMethods)</a><br />
|
||||
<a href="classes/ActiveRecord/Validations/ClassMethods.html#M000038">validates_size_of (ActiveRecord::Validations::ClassMethods)</a><br />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
GLoc Localization Library Documentation
|
||||
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>GLoc Localization Library Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<frameset rows="20%, 80%">
|
||||
<frameset cols="25%,35%,45%">
|
||||
<frame src="fr_file_index.html" title="Files" name="Files" />
|
||||
<frame src="fr_class_index.html" name="Classes" />
|
||||
<frame src="fr_method_index.html" name="Methods" />
|
||||
</frameset>
|
||||
<frame src="files/README.html" name="docwin" />
|
||||
</frameset>
|
||||
</html>
|
||||
@@ -0,0 +1,208 @@
|
||||
|
||||
body {
|
||||
font-family: Verdana,Arial,Helvetica,sans-serif;
|
||||
font-size: 90%;
|
||||
margin: 0;
|
||||
margin-left: 40px;
|
||||
padding: 0;
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
||||
h1 { font-size: 150%; }
|
||||
h2,h3,h4 { margin-top: 1em; }
|
||||
|
||||
a { background: #eef; color: #039; text-decoration: none; }
|
||||
a:hover { background: #039; color: #eef; }
|
||||
|
||||
/* Override the base stylesheet's Anchor inside a table cell */
|
||||
td > a {
|
||||
background: transparent;
|
||||
color: #039;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* and inside a section title */
|
||||
.section-title > a {
|
||||
background: transparent;
|
||||
color: #eee;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* === Structural elements =================================== */
|
||||
|
||||
div#index {
|
||||
margin: 0;
|
||||
margin-left: -40px;
|
||||
padding: 0;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
div#index a {
|
||||
margin-left: 0.7em;
|
||||
}
|
||||
|
||||
div#index .section-bar {
|
||||
margin-left: 0px;
|
||||
padding-left: 0.7em;
|
||||
background: #ccc;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
|
||||
div#classHeader, div#fileHeader {
|
||||
width: auto;
|
||||
color: white;
|
||||
padding: 0.5em 1.5em 0.5em 1.5em;
|
||||
margin: 0;
|
||||
margin-left: -40px;
|
||||
border-bottom: 3px solid #006;
|
||||
}
|
||||
|
||||
div#classHeader a, div#fileHeader a {
|
||||
background: inherit;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div#classHeader td, div#fileHeader td {
|
||||
background: inherit;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
div#fileHeader {
|
||||
background: #057;
|
||||
}
|
||||
|
||||
div#classHeader {
|
||||
background: #048;
|
||||
}
|
||||
|
||||
|
||||
.class-name-in-header {
|
||||
font-size: 180%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
div#bodyContent {
|
||||
padding: 0 1.5em 0 1.5em;
|
||||
}
|
||||
|
||||
div#description {
|
||||
padding: 0.5em 1.5em;
|
||||
background: #efefef;
|
||||
border: 1px dotted #999;
|
||||
}
|
||||
|
||||
div#description h1,h2,h3,h4,h5,h6 {
|
||||
color: #125;;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
div#validator-badges {
|
||||
text-align: center;
|
||||
}
|
||||
div#validator-badges img { border: 0; }
|
||||
|
||||
div#copyright {
|
||||
color: #333;
|
||||
background: #efefef;
|
||||
font: 0.75em sans-serif;
|
||||
margin-top: 5em;
|
||||
margin-bottom: 0;
|
||||
padding: 0.5em 2em;
|
||||
}
|
||||
|
||||
|
||||
/* === Classes =================================== */
|
||||
|
||||
table.header-table {
|
||||
color: white;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.type-note {
|
||||
font-size: small;
|
||||
color: #DEDEDE;
|
||||
}
|
||||
|
||||
.xxsection-bar {
|
||||
background: #eee;
|
||||
color: #333;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.section-bar {
|
||||
color: #333;
|
||||
border-bottom: 1px solid #999;
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
||||
|
||||
.section-title {
|
||||
background: #79a;
|
||||
color: #eee;
|
||||
padding: 3px;
|
||||
margin-top: 2em;
|
||||
margin-left: -30px;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.top-aligned-row { vertical-align: top }
|
||||
.bottom-aligned-row { vertical-align: bottom }
|
||||
|
||||
/* --- Context section classes ----------------------- */
|
||||
|
||||
.context-row { }
|
||||
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
||||
.context-item-value { font-size: small; color: #448; }
|
||||
.context-item-desc { color: #333; padding-left: 2em; }
|
||||
|
||||
/* --- Method classes -------------------------- */
|
||||
.method-detail {
|
||||
background: #efefef;
|
||||
padding: 0;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
border: 1px dotted #ccc;
|
||||
}
|
||||
.method-heading {
|
||||
color: black;
|
||||
background: #ccc;
|
||||
border-bottom: 1px solid #666;
|
||||
padding: 0.2em 0.5em 0 0.5em;
|
||||
}
|
||||
.method-signature { color: black; background: inherit; }
|
||||
.method-name { font-weight: bold; }
|
||||
.method-args { font-style: italic; }
|
||||
.method-description { padding: 0 0.5em 0 0.5em; }
|
||||
|
||||
/* --- Source code sections -------------------- */
|
||||
|
||||
a.source-toggle { font-size: 90%; }
|
||||
div.method-source-code {
|
||||
background: #262626;
|
||||
color: #ffdead;
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
border: 1px dashed #999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
||||
|
||||
/* --- Ruby keyword styles --------------------- */
|
||||
|
||||
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
||||
|
||||
.ruby-constant { color: #7fffd4; background: transparent; }
|
||||
.ruby-keyword { color: #00ffff; background: transparent; }
|
||||
.ruby-ivar { color: #eedd82; background: transparent; }
|
||||
.ruby-operator { color: #00ffee; background: transparent; }
|
||||
.ruby-identifier { color: #ffdead; background: transparent; }
|
||||
.ruby-node { color: #ffa07a; background: transparent; }
|
||||
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
||||
.ruby-regexp { color: #ffa07a; background: transparent; }
|
||||
.ruby-value { color: #7fffd4; background: transparent; }
|
||||
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
require 'gloc'
|
||||
require 'gloc-ruby'
|
||||
require 'gloc-rails'
|
||||
require 'gloc-rails-text'
|
||||
require 'gloc-config'
|
||||
|
||||
require 'gloc-dev' if ENV['RAILS_ENV'] == 'development'
|
||||
|
||||
GLoc.load_gloc_default_localized_strings
|
||||
@@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
module GLoc
|
||||
|
||||
private
|
||||
|
||||
CONFIG= {} unless const_defined?(:CONFIG)
|
||||
unless CONFIG.frozen?
|
||||
CONFIG[:default_language] ||= :en
|
||||
CONFIG[:default_param_name] ||= 'lang'
|
||||
CONFIG[:default_cookie_name] ||= 'lang'
|
||||
CONFIG[:raise_string_not_found_errors]= true unless CONFIG.has_key?(:raise_string_not_found_errors)
|
||||
CONFIG[:verbose] ||= false
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
puts "GLoc v#{GLoc::VERSION} running in development mode. Strings can be modified at runtime."
|
||||
|
||||
module GLoc
|
||||
class << self
|
||||
|
||||
alias :actual_add_localized_strings :add_localized_strings
|
||||
def add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil)
|
||||
_verbose_msg {"dev::add_localized_strings #{lang}, [#{symbol_hash.size}], #{override}, #{strings_charset ? strings_charset : 'nil'}"}
|
||||
STATE.push [:hash, lang, {}.merge(symbol_hash), override, strings_charset]
|
||||
_force_refresh
|
||||
end
|
||||
|
||||
alias :actual_load_localized_strings :load_localized_strings
|
||||
def load_localized_strings(dir=nil, override=true)
|
||||
_verbose_msg {"dev::load_localized_strings #{dir ? dir : 'nil'}, #{override}"}
|
||||
STATE.push [:dir, dir, override]
|
||||
_get_lang_file_list(dir).each {|filename| FILES[filename]= nil}
|
||||
end
|
||||
|
||||
alias :actual_clear_strings :clear_strings
|
||||
def clear_strings(*languages)
|
||||
_verbose_msg {"dev::clear_strings #{languages.map{|l|l.to_s}.join(', ')}"}
|
||||
STATE.push [:clear, languages.clone]
|
||||
_force_refresh
|
||||
end
|
||||
|
||||
alias :actual_clear_strings_except :clear_strings_except
|
||||
def clear_strings_except(*languages)
|
||||
_verbose_msg {"dev::clear_strings_except #{languages.map{|l|l.to_s}.join(', ')}"}
|
||||
STATE.push [:clear_except, languages.clone]
|
||||
_force_refresh
|
||||
end
|
||||
|
||||
# Replace methods
|
||||
[:_l, :_l_rule, :_l_has_string?, :similar_language, :valid_languages, :valid_language?].each do |m|
|
||||
class_eval <<-EOB
|
||||
alias :actual_#{m} :#{m}
|
||||
def #{m}(*args)
|
||||
_assert_gloc_strings_up_to_date
|
||||
actual_#{m}(*args)
|
||||
end
|
||||
EOB
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
private
|
||||
|
||||
STATE= []
|
||||
FILES= {}
|
||||
|
||||
def _assert_gloc_strings_up_to_date
|
||||
changed= @@force_refresh
|
||||
|
||||
# Check if any lang files have changed
|
||||
unless changed
|
||||
FILES.each_pair {|f,mtime|
|
||||
changed ||= (File.stat(f).mtime != mtime)
|
||||
}
|
||||
end
|
||||
|
||||
return unless changed
|
||||
puts "GLoc reloading strings..."
|
||||
@@force_refresh= false
|
||||
|
||||
# Update file timestamps
|
||||
FILES.each_key {|f|
|
||||
FILES[f]= File.stat(f).mtime
|
||||
}
|
||||
|
||||
# Reload strings
|
||||
actual_clear_strings
|
||||
STATE.each {|s|
|
||||
case s[0]
|
||||
when :dir then actual_load_localized_strings s[1], s[2]
|
||||
when :hash then actual_add_localized_strings s[1], s[2], s[3], s[4]
|
||||
when :clear then actual_clear_strings(*s[1])
|
||||
when :clear_except then actual_clear_strings_except(*s[1])
|
||||
else raise "Invalid state id: '#{s[0]}'"
|
||||
end
|
||||
}
|
||||
_verbose_msg :stats
|
||||
end
|
||||
|
||||
@@force_refresh= false
|
||||
def _force_refresh
|
||||
@@force_refresh= true
|
||||
end
|
||||
|
||||
alias :super_get_internal_state_vars :_get_internal_state_vars
|
||||
def _get_internal_state_vars
|
||||
super_get_internal_state_vars + [ STATE, FILES ]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
module GLoc
|
||||
# These helper methods will be included in the InstanceMethods module.
|
||||
module Helpers
|
||||
def l_age(age) lwr :general_fmt_age, age end
|
||||
def l_date(date) l_strftime date, :general_fmt_date end
|
||||
def l_datetime(date) l_strftime date, :general_fmt_datetime end
|
||||
def l_datetime_short(date) l_strftime date, :general_fmt_datetime_short end
|
||||
def l_strftime(date,fmt) date.strftime l(fmt) end
|
||||
def l_time(time) l_strftime time, :general_fmt_time end
|
||||
def l_YesNo(value) l(value ? :general_text_Yes : :general_text_No) end
|
||||
def l_yesno(value) l(value ? :general_text_yes : :general_text_no) end
|
||||
|
||||
def l_lang_name(lang, display_lang=nil)
|
||||
ll display_lang || current_language, "general_lang_#{lang}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,134 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
require 'iconv'
|
||||
require 'gloc-version'
|
||||
|
||||
module GLoc
|
||||
class GLocError < StandardError #:nodoc:
|
||||
end
|
||||
class InvalidArgumentsError < GLocError #:nodoc:
|
||||
end
|
||||
class InvalidKeyError < GLocError #:nodoc:
|
||||
end
|
||||
class RuleNotFoundError < GLocError #:nodoc:
|
||||
end
|
||||
class StringNotFoundError < GLocError #:nodoc:
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
def _add_localized_data(lang, symbol_hash, override, target) #:nodoc:
|
||||
lang= lang.to_sym
|
||||
if override
|
||||
target[lang] ||= {}
|
||||
target[lang].merge!(symbol_hash)
|
||||
else
|
||||
symbol_hash.merge!(target[lang]) if target[lang]
|
||||
target[lang]= symbol_hash
|
||||
end
|
||||
end
|
||||
|
||||
def _add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil) #:nodoc:
|
||||
_charset_required
|
||||
|
||||
# Convert all incoming strings to the gloc charset
|
||||
if strings_charset
|
||||
Iconv.open(get_charset(lang), strings_charset) do |i|
|
||||
symbol_hash.each_pair {|k,v| symbol_hash[k]= i.iconv(v)}
|
||||
end
|
||||
end
|
||||
|
||||
# Convert rules
|
||||
rules= {}
|
||||
old_kcode= $KCODE
|
||||
begin
|
||||
$KCODE= 'u'
|
||||
Iconv.open(UTF_8, get_charset(lang)) do |i|
|
||||
symbol_hash.each {|k,v|
|
||||
if /^_gloc_rule_(.+)$/ =~ k.to_s
|
||||
v= i.iconv(v) if v
|
||||
v= '""' if v.nil?
|
||||
rules[$1.to_sym]= eval "Proc.new do #{v} end"
|
||||
end
|
||||
}
|
||||
end
|
||||
ensure
|
||||
$KCODE= old_kcode
|
||||
end
|
||||
rules.keys.each {|k| symbol_hash.delete "_gloc_rule_#{k}".to_sym}
|
||||
|
||||
# Add new localized data
|
||||
LOWERCASE_LANGUAGES[lang.to_s.downcase]= lang
|
||||
_add_localized_data(lang, symbol_hash, override, LOCALIZED_STRINGS)
|
||||
_add_localized_data(lang, rules, override, RULES)
|
||||
end
|
||||
|
||||
def _charset_required #:nodoc:
|
||||
set_charset UTF_8 unless CONFIG[:internal_charset]
|
||||
end
|
||||
|
||||
def _get_internal_state_vars
|
||||
[ CONFIG, LOCALIZED_STRINGS, RULES, LOWERCASE_LANGUAGES ]
|
||||
end
|
||||
|
||||
def _get_lang_file_list(dir) #:nodoc:
|
||||
dir= File.join(RAILS_ROOT,'lang') if dir.nil?
|
||||
Dir[File.join(dir,'*.{yaml,yml}')]
|
||||
end
|
||||
|
||||
def _l(symbol, language, *arguments) #:nodoc:
|
||||
symbol= symbol.to_sym if symbol.is_a?(String)
|
||||
raise InvalidKeyError.new("Symbol or String expected as key.") unless symbol.kind_of?(Symbol)
|
||||
|
||||
translation= LOCALIZED_STRINGS[language][symbol] rescue nil
|
||||
if translation.nil?
|
||||
raise StringNotFoundError.new("There is no key called '#{symbol}' in the #{language} strings.") if CONFIG[:raise_string_not_found_errors]
|
||||
translation= symbol.to_s
|
||||
end
|
||||
|
||||
begin
|
||||
return translation % arguments
|
||||
rescue => e
|
||||
raise InvalidArgumentsError.new("Translation value #{translation.inspect} with arguments #{arguments.inspect} caused error '#{e.message}'")
|
||||
end
|
||||
end
|
||||
|
||||
def _l_has_string?(symbol,lang) #:nodoc:
|
||||
symbol= symbol.to_sym if symbol.is_a?(String)
|
||||
LOCALIZED_STRINGS[lang].has_key?(symbol.to_sym) rescue false
|
||||
end
|
||||
|
||||
def _l_rule(symbol,lang) #:nodoc:
|
||||
symbol= symbol.to_sym if symbol.is_a?(String)
|
||||
raise InvalidKeyError.new("Symbol or String expected as key.") unless symbol.kind_of?(Symbol)
|
||||
|
||||
r= RULES[lang][symbol] rescue nil
|
||||
raise RuleNotFoundError.new("There is no rule called '#{symbol}' in the #{lang} rules.") if r.nil?
|
||||
r
|
||||
end
|
||||
|
||||
def _verbose_msg(type=nil)
|
||||
return unless CONFIG[:verbose]
|
||||
x= case type
|
||||
when :stats
|
||||
x= valid_languages.map{|l| ":#{l}(#{LOCALIZED_STRINGS[l].size}/#{RULES[l].size})"}.sort.join(', ')
|
||||
"Current stats -- #{x}"
|
||||
else
|
||||
yield
|
||||
end
|
||||
puts "[GLoc] #{x}"
|
||||
end
|
||||
|
||||
public :_l, :_l_has_string?, :_l_rule
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
unless const_defined?(:LOCALIZED_STRINGS)
|
||||
LOCALIZED_STRINGS= {}
|
||||
RULES= {}
|
||||
LOWERCASE_LANGUAGES= {}
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,137 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
require 'date'
|
||||
|
||||
module ActionView #:nodoc:
|
||||
module Helpers #:nodoc:
|
||||
module DateHelper
|
||||
|
||||
unless const_defined?(:LOCALIZED_HELPERS)
|
||||
LOCALIZED_HELPERS= true
|
||||
LOCALIZED_MONTHNAMES = {}
|
||||
LOCALIZED_ABBR_MONTHNAMES = {}
|
||||
end
|
||||
|
||||
# This method uses <tt>current_language</tt> to return a localized string.
|
||||
def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
|
||||
from_time = from_time.to_time if from_time.respond_to?(:to_time)
|
||||
to_time = to_time.to_time if to_time.respond_to?(:to_time)
|
||||
distance_in_minutes = (((to_time - from_time).abs)/60).round
|
||||
distance_in_seconds = ((to_time - from_time).abs).round
|
||||
|
||||
case distance_in_minutes
|
||||
when 0..1
|
||||
return (distance_in_minutes==0) ? l(:actionview_datehelper_time_in_words_minute_less_than) : l(:actionview_datehelper_time_in_words_minute_single) unless include_seconds
|
||||
case distance_in_seconds
|
||||
when 0..5 then lwr(:actionview_datehelper_time_in_words_second_less_than, 5)
|
||||
when 6..10 then lwr(:actionview_datehelper_time_in_words_second_less_than, 10)
|
||||
when 11..20 then lwr(:actionview_datehelper_time_in_words_second_less_than, 20)
|
||||
when 21..40 then l(:actionview_datehelper_time_in_words_minute_half)
|
||||
when 41..59 then l(:actionview_datehelper_time_in_words_minute_less_than)
|
||||
else l(:actionview_datehelper_time_in_words_minute)
|
||||
end
|
||||
|
||||
when 2..45 then lwr(:actionview_datehelper_time_in_words_minute, distance_in_minutes)
|
||||
when 46..90 then l(:actionview_datehelper_time_in_words_hour_about_single)
|
||||
when 90..1440 then lwr(:actionview_datehelper_time_in_words_hour_about, (distance_in_minutes.to_f / 60.0).round)
|
||||
when 1441..2880 then lwr(:actionview_datehelper_time_in_words_day, 1)
|
||||
else lwr(:actionview_datehelper_time_in_words_day, (distance_in_minutes / 1440).round)
|
||||
end
|
||||
end
|
||||
|
||||
# This method has been modified so that a localized string can be appended to the day numbers.
|
||||
def select_day(date, options = {})
|
||||
day_options = []
|
||||
prefix = l :actionview_datehelper_select_day_prefix
|
||||
|
||||
1.upto(31) do |day|
|
||||
day_options << ((date && (date.kind_of?(Fixnum) ? date : date.day) == day) ?
|
||||
%(<option value="#{day}" selected="selected">#{day}#{prefix}</option>\n) :
|
||||
%(<option value="#{day}">#{day}#{prefix}</option>\n)
|
||||
)
|
||||
end
|
||||
|
||||
select_html(options[:field_name] || 'day', day_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled])
|
||||
end
|
||||
|
||||
# This method has been modified so that
|
||||
# * the month names are localized.
|
||||
# * it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>, <tt>:start_month</tt>, <tt>:end_month</tt>
|
||||
# * a localized string can be appended to the month numbers when the <tt>:use_month_numbers</tt> option is specified.
|
||||
def select_month(date, options = {})
|
||||
unless LOCALIZED_MONTHNAMES.has_key?(current_language)
|
||||
LOCALIZED_MONTHNAMES[current_language] = [''] + l(:actionview_datehelper_select_month_names).split(',')
|
||||
LOCALIZED_ABBR_MONTHNAMES[current_language] = [''] + l(:actionview_datehelper_select_month_names_abbr).split(',')
|
||||
end
|
||||
|
||||
month_options = []
|
||||
month_names = options[:use_short_month] ? LOCALIZED_ABBR_MONTHNAMES[current_language] : LOCALIZED_MONTHNAMES[current_language]
|
||||
|
||||
if options.has_key?(:min_date) && options.has_key?(:max_date)
|
||||
if options[:min_date].year == options[:max_date].year
|
||||
start_month, end_month = options[:min_date].month, options[:max_date].month
|
||||
end
|
||||
end
|
||||
start_month = (options[:start_month] || 1) unless start_month
|
||||
end_month = (options[:end_month] || 12) unless end_month
|
||||
prefix = l :actionview_datehelper_select_month_prefix
|
||||
|
||||
start_month.upto(end_month) do |month_number|
|
||||
month_name = if options[:use_month_numbers]
|
||||
"#{month_number}#{prefix}"
|
||||
elsif options[:add_month_numbers]
|
||||
month_number.to_s + ' - ' + month_names[month_number]
|
||||
else
|
||||
month_names[month_number]
|
||||
end
|
||||
|
||||
month_options << ((date && (date.kind_of?(Fixnum) ? date : date.month) == month_number) ?
|
||||
%(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
|
||||
%(<option value="#{month_number}">#{month_name}</option>\n)
|
||||
)
|
||||
end
|
||||
|
||||
select_html(options[:field_name] || 'month', month_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled])
|
||||
end
|
||||
|
||||
# This method has been modified so that
|
||||
# * it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>
|
||||
# * a localized string can be appended to the years numbers.
|
||||
def select_year(date, options = {})
|
||||
year_options = []
|
||||
y = date ? (date.kind_of?(Fixnum) ? (y = (date == 0) ? Date.today.year : date) : date.year) : Date.today.year
|
||||
|
||||
start_year = options.has_key?(:min_date) ? options[:min_date].year : (options[:start_year] || y-5)
|
||||
end_year = options.has_key?(:max_date) ? options[:max_date].year : (options[:end_year] || y+5)
|
||||
step_val = start_year < end_year ? 1 : -1
|
||||
prefix = l :actionview_datehelper_select_year_prefix
|
||||
|
||||
start_year.step(end_year, step_val) do |year|
|
||||
year_options << ((date && (date.kind_of?(Fixnum) ? date : date.year) == year) ?
|
||||
%(<option value="#{year}" selected="selected">#{year}#{prefix}</option>\n) :
|
||||
%(<option value="#{year}">#{year}#{prefix}</option>\n)
|
||||
)
|
||||
end
|
||||
|
||||
select_html(options[:field_name] || 'year', year_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The private method <tt>add_options</tt> is overridden so that "Please select" is localized.
|
||||
class InstanceTag
|
||||
private
|
||||
|
||||
def add_options(option_tags, options, value = nil)
|
||||
option_tags = "<option value=\"\"></option>\n" + option_tags if options[:include_blank]
|
||||
|
||||
if value.blank? && options[:prompt]
|
||||
("<option value=\"\">#{options[:prompt].kind_of?(String) ? options[:prompt] : l(:actionview_instancetag_blank_option)}</option>\n") + option_tags
|
||||
else
|
||||
option_tags
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,230 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
require 'gloc'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
class Base #:nodoc:
|
||||
include GLoc
|
||||
end
|
||||
module Filters #:nodoc:
|
||||
module ClassMethods
|
||||
|
||||
# This filter attempts to auto-detect the clients desired language.
|
||||
# It first checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE
|
||||
# request header. If a language is found to match or be similar to a currently
|
||||
# valid language, then it sets the current_language of the controller.
|
||||
#
|
||||
# class ExampleController < ApplicationController
|
||||
# set_language :en
|
||||
# autodetect_language_filter :except => 'monkey', :on_no_lang => :lang_not_autodetected_callback
|
||||
# autodetect_language_filter :only => 'monkey', :check_cookie => 'monkey_lang', :check_accept_header => false
|
||||
# ...
|
||||
# def lang_not_autodetected_callback
|
||||
# redirect_to somewhere
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# The <tt>args</tt> for this filter are exactly the same the arguments of
|
||||
# <tt>before_filter</tt> with the following exceptions:
|
||||
# * <tt>:check_params</tt> -- If false, then params will not be checked for a language.
|
||||
# If a String, then this will value will be used as the name of the param.
|
||||
# * <tt>:check_cookie</tt> -- If false, then the cookie will not be checked for a language.
|
||||
# If a String, then this will value will be used as the name of the cookie.
|
||||
# * <tt>:check_accept_header</tt> -- If false, then HTTP_ACCEPT_LANGUAGE will not be checked for a language.
|
||||
# * <tt>:on_set_lang</tt> -- You can specify the name of a callback function to be called when the language
|
||||
# is successfully detected and set. The param must be a Symbol or a String which is the name of the function.
|
||||
# The callback function must accept one argument (the language) and must be instance level.
|
||||
# * <tt>:on_no_lang</tt> -- You can specify the name of a callback function to be called when the language
|
||||
# couldn't be detected automatically. The param must be a Symbol or a String which is the name of the function.
|
||||
# The callback function must be instance level.
|
||||
#
|
||||
# You override the default names of the param or cookie by calling <tt>GLoc.set_config :default_param_name => 'new_param_name'</tt>
|
||||
# and <tt>GLoc.set_config :default_cookie_name => 'new_cookie_name'</tt>.
|
||||
def autodetect_language_filter(*args)
|
||||
options= args.last.is_a?(Hash) ? args.last : {}
|
||||
x= 'Proc.new { |c| l= nil;'
|
||||
# :check_params
|
||||
unless (v= options.delete(:check_params)) == false
|
||||
name= v ? ":#{v}" : 'GLoc.get_config(:default_param_name)'
|
||||
x << "l ||= GLoc.similar_language(c.params[#{name}]);"
|
||||
end
|
||||
# :check_cookie
|
||||
unless (v= options.delete(:check_cookie)) == false
|
||||
name= v ? ":#{v}" : 'GLoc.get_config(:default_cookie_name)'
|
||||
x << "l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);"
|
||||
end
|
||||
# :check_accept_header
|
||||
unless options.delete(:check_accept_header) == false
|
||||
x << %<
|
||||
unless l
|
||||
a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
|
||||
a.each {|x| l ||= GLoc.similar_language(x)} if a
|
||||
end; >
|
||||
end
|
||||
# Set language
|
||||
x << 'ret= true;'
|
||||
x << 'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '
|
||||
if options.has_key?(:on_set_lang)
|
||||
x << "ret= c.#{options.delete(:on_set_lang)}(l);"
|
||||
end
|
||||
if options.has_key?(:on_no_lang)
|
||||
x << "else; ret= c.#{options.delete(:on_no_lang)};"
|
||||
end
|
||||
x << 'end; ret }'
|
||||
|
||||
# Create filter
|
||||
block= eval x
|
||||
before_filter(*args, &block)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
module ActionMailer #:nodoc:
|
||||
# In addition to including GLoc, <tt>render_message</tt> is also overridden so
|
||||
# that mail templates contain the current language at the end of the file.
|
||||
# Eg. <tt>deliver_hello</tt> will render <tt>hello_en.rhtml</tt>.
|
||||
class Base
|
||||
include GLoc
|
||||
private
|
||||
alias :render_message_without_gloc :render_message
|
||||
def render_message(method_name, body)
|
||||
render_message_without_gloc("#{method_name}_#{current_language}", body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
module ActionView #:nodoc:
|
||||
# <tt>initialize</tt> is overridden so that new instances of this class inherit
|
||||
# the current language of the controller.
|
||||
class Base
|
||||
include GLoc
|
||||
|
||||
alias :initialize_without_gloc :initialize
|
||||
def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)
|
||||
initialize_without_gloc(base_path, assigns_for_first_render, controller)
|
||||
set_language controller.current_language unless controller.nil?
|
||||
end
|
||||
end
|
||||
|
||||
module Helpers #:nodoc:
|
||||
class InstanceTag
|
||||
include GLoc
|
||||
# Inherits the current language from the template object.
|
||||
def current_language
|
||||
@template_object.current_language
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
module ActiveRecord #:nodoc:
|
||||
class Base #:nodoc:
|
||||
include GLoc
|
||||
end
|
||||
|
||||
class Errors
|
||||
include GLoc
|
||||
alias :add_without_gloc :add
|
||||
# The GLoc version of this method provides two extra features
|
||||
# * If <tt>msg</tt> is a string, it will be considered a GLoc string key.
|
||||
# * If <tt>msg</tt> is an array, the first element will be considered
|
||||
# the string and the remaining elements will be considered arguments for the
|
||||
# string. Eg. <tt>['Hi %s.','John']</tt>
|
||||
def add(attribute, msg= @@default_error_messages[:invalid])
|
||||
if msg.is_a?(Array)
|
||||
args= msg.clone
|
||||
msg= args.shift
|
||||
args= nil if args.empty?
|
||||
end
|
||||
msg= ltry(msg)
|
||||
msg= msg % args unless args.nil?
|
||||
add_without_gloc(attribute, msg)
|
||||
end
|
||||
# Inherits the current language from the base record.
|
||||
def current_language
|
||||
@base.current_language
|
||||
end
|
||||
end
|
||||
|
||||
module Validations #:nodoc:
|
||||
module ClassMethods
|
||||
# The default Rails version of this function creates an error message and then
|
||||
# passes it to ActiveRecord.Errors.
|
||||
# The GLoc version of this method, sends an array to ActiveRecord.Errors that will
|
||||
# be turned into a string by ActiveRecord.Errors which in turn allows for the message
|
||||
# of this validation function to be a GLoc string key.
|
||||
def validates_length_of(*attrs)
|
||||
# Merge given options with defaults.
|
||||
options = {
|
||||
:too_long => ActiveRecord::Errors.default_error_messages[:too_long],
|
||||
:too_short => ActiveRecord::Errors.default_error_messages[:too_short],
|
||||
:wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
|
||||
}.merge(DEFAULT_VALIDATION_OPTIONS)
|
||||
options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
|
||||
|
||||
# Ensure that one and only one range option is specified.
|
||||
range_options = ALL_RANGE_OPTIONS & options.keys
|
||||
case range_options.size
|
||||
when 0
|
||||
raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
|
||||
when 1
|
||||
# Valid number of options; do nothing.
|
||||
else
|
||||
raise ArgumentError, 'Too many range options specified. Choose only one.'
|
||||
end
|
||||
|
||||
# Get range option and value.
|
||||
option = range_options.first
|
||||
option_value = options[range_options.first]
|
||||
|
||||
case option
|
||||
when :within, :in
|
||||
raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
|
||||
|
||||
too_short = [options[:too_short] , option_value.begin]
|
||||
too_long = [options[:too_long] , option_value.end ]
|
||||
|
||||
validates_each(attrs, options) do |record, attr, value|
|
||||
if value.nil? or value.split(//).size < option_value.begin
|
||||
record.errors.add(attr, too_short)
|
||||
elsif value.split(//).size > option_value.end
|
||||
record.errors.add(attr, too_long)
|
||||
end
|
||||
end
|
||||
when :is, :minimum, :maximum
|
||||
raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
|
||||
|
||||
# Declare different validations per option.
|
||||
validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
|
||||
message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
|
||||
|
||||
message = [(options[:message] || options[message_options[option]]) , option_value]
|
||||
|
||||
validates_each(attrs, options) do |record, attr, value|
|
||||
if value.kind_of?(String)
|
||||
record.errors.add(attr, message) unless !value.nil? and value.split(//).size.method(validity_checks[option])[option_value]
|
||||
else
|
||||
record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :validates_size_of, :validates_length_of
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
module ApplicationHelper #:nodoc:
|
||||
include GLoc
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
module Test # :nodoc:
|
||||
module Unit # :nodoc:
|
||||
class TestCase # :nodoc:
|
||||
include GLoc
|
||||
end; end; end
|
||||
@@ -0,0 +1,12 @@
|
||||
module GLoc
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 1
|
||||
MINOR = 1
|
||||
TINY = nil
|
||||
|
||||
STRING= [MAJOR, MINOR, TINY].delete_if{|x|x.nil?}.join('.')
|
||||
def self.to_s; STRING end
|
||||
end
|
||||
end
|
||||
|
||||
puts "NOTICE: You are using a dev version of GLoc." if GLoc::VERSION::TINY == 'DEV'
|
||||
@@ -0,0 +1,294 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
require 'yaml'
|
||||
require 'gloc-internal'
|
||||
require 'gloc-helpers'
|
||||
|
||||
module GLoc
|
||||
UTF_8= 'utf-8'
|
||||
SHIFT_JIS= 'sjis'
|
||||
EUC_JP= 'euc-jp'
|
||||
|
||||
# This module will be included in both instances and classes of GLoc includees.
|
||||
# It is also included as class methods in the GLoc module itself.
|
||||
module InstanceMethods
|
||||
include Helpers
|
||||
|
||||
# Returns a localized string.
|
||||
def l(symbol, *arguments)
|
||||
return GLoc._l(symbol,current_language,*arguments)
|
||||
end
|
||||
|
||||
# Returns a localized string in a specified language.
|
||||
# This does not effect <tt>current_language</tt>.
|
||||
def ll(lang, symbol, *arguments)
|
||||
return GLoc._l(symbol,lang.to_sym,*arguments)
|
||||
end
|
||||
|
||||
# Returns a localized string if the argument is a Symbol, else just returns the argument.
|
||||
def ltry(possible_key)
|
||||
possible_key.is_a?(Symbol) ? l(possible_key) : possible_key
|
||||
end
|
||||
|
||||
# Uses the default GLoc rule to return a localized string.
|
||||
# See lwr_() for more info.
|
||||
def lwr(symbol, *arguments)
|
||||
lwr_(:default, symbol, *arguments)
|
||||
end
|
||||
|
||||
# Uses a <em>rule</em> to return a localized string.
|
||||
# A rule is a function that uses specified arguments to return a localization key prefix.
|
||||
# The prefix is appended to the localization key originally specified, to create a new key which
|
||||
# is then used to lookup a localized string.
|
||||
def lwr_(rule, symbol, *arguments)
|
||||
GLoc._l("#{symbol}#{GLoc::_l_rule(rule,current_language).call(*arguments)}",current_language,*arguments)
|
||||
end
|
||||
|
||||
# Returns <tt>true</tt> if a localized string with the specified key exists.
|
||||
def l_has_string?(symbol)
|
||||
return GLoc._l_has_string?(symbol,current_language)
|
||||
end
|
||||
|
||||
# Sets the current language for this instance/class.
|
||||
# Setting the language of a class effects all instances unless the instance has its own language defined.
|
||||
def set_language(language)
|
||||
@gloc_language= language.nil? ? nil : language.to_sym
|
||||
end
|
||||
|
||||
# Sets the current language if the language passed is a valid language.
|
||||
# If the language was valid, this method returns <tt>true</tt> else it will return <tt>false</tt>.
|
||||
# Note that <tt>nil</tt> is not a valid language.
|
||||
# See set_language(language) for more info.
|
||||
def set_language_if_valid(language)
|
||||
if GLoc.valid_language?(language)
|
||||
set_language(language)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Instance
|
||||
|
||||
include ::GLoc::InstanceMethods
|
||||
# Returns the instance-level current language, or if not set, returns the class-level current language.
|
||||
def current_language
|
||||
@gloc_language || self.class.current_language
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Class
|
||||
|
||||
# All classes/modules that include GLoc will also gain these class methods.
|
||||
# Notice that the GLoc::InstanceMethods module is also included.
|
||||
module ClassMethods
|
||||
include ::GLoc::InstanceMethods
|
||||
# Returns the current language, or if not set, returns the GLoc current language.
|
||||
def current_language
|
||||
@gloc_language || GLoc.current_language
|
||||
end
|
||||
end
|
||||
|
||||
def self.included(target) #:nodoc:
|
||||
super
|
||||
class << target
|
||||
include ::GLoc::ClassMethods
|
||||
end
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# GLoc module
|
||||
|
||||
class << self
|
||||
include ::GLoc::InstanceMethods
|
||||
|
||||
# Returns the default language
|
||||
def current_language
|
||||
GLoc::CONFIG[:default_language]
|
||||
end
|
||||
|
||||
# Adds a collection of localized strings to the in-memory string store.
|
||||
def add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil)
|
||||
_verbose_msg {"Adding #{symbol_hash.size} #{lang} strings."}
|
||||
_add_localized_strings(lang, symbol_hash, override, strings_charset)
|
||||
_verbose_msg :stats
|
||||
end
|
||||
|
||||
# Creates a backup of the internal state of GLoc (ie. strings, langs, rules, config)
|
||||
# and optionally clears everything.
|
||||
def backup_state(clear=false)
|
||||
s= _get_internal_state_vars.map{|o| o.clone}
|
||||
_get_internal_state_vars.each{|o| o.clear} if clear
|
||||
s
|
||||
end
|
||||
|
||||
# Removes all localized strings from memory, either of a certain language (or languages),
|
||||
# or entirely.
|
||||
def clear_strings(*languages)
|
||||
if languages.empty?
|
||||
_verbose_msg {"Clearing all strings"}
|
||||
LOCALIZED_STRINGS.clear
|
||||
LOWERCASE_LANGUAGES.clear
|
||||
else
|
||||
languages.each {|l|
|
||||
_verbose_msg {"Clearing :#{l} strings"}
|
||||
l= l.to_sym
|
||||
LOCALIZED_STRINGS.delete l
|
||||
LOWERCASE_LANGUAGES.each_pair {|k,v| LOWERCASE_LANGUAGES.delete k if v == l}
|
||||
}
|
||||
end
|
||||
end
|
||||
alias :_clear_strings :clear_strings
|
||||
|
||||
# Removes all localized strings from memory, except for those of certain specified languages.
|
||||
def clear_strings_except(*languages)
|
||||
clear= (LOCALIZED_STRINGS.keys - languages)
|
||||
_clear_strings(*clear) unless clear.empty?
|
||||
end
|
||||
|
||||
# Returns the charset used to store localized strings in memory.
|
||||
def get_charset(lang)
|
||||
CONFIG[:internal_charset_per_lang][lang] || CONFIG[:internal_charset]
|
||||
end
|
||||
|
||||
# Returns a GLoc configuration value.
|
||||
def get_config(key)
|
||||
CONFIG[key]
|
||||
end
|
||||
|
||||
# Loads the localized strings that are included in the GLoc library.
|
||||
def load_gloc_default_localized_strings(override=false)
|
||||
GLoc.load_localized_strings "#{File.dirname(__FILE__)}/../lang", override
|
||||
end
|
||||
|
||||
# Loads localized strings from all yml files in the specifed directory.
|
||||
def load_localized_strings(dir=nil, override=true)
|
||||
_charset_required
|
||||
_get_lang_file_list(dir).each {|filename|
|
||||
|
||||
# Load file
|
||||
raw_hash = YAML::load(File.read(filename))
|
||||
raw_hash={} unless raw_hash.kind_of?(Hash)
|
||||
filename =~ /([^\/\\]+)\.ya?ml$/
|
||||
lang = $1.to_sym
|
||||
file_charset = raw_hash['file_charset'] || UTF_8
|
||||
|
||||
# Convert string keys to symbols
|
||||
dest_charset= get_charset(lang)
|
||||
_verbose_msg {"Reading file #{filename} [charset: #{file_charset} --> #{dest_charset}]"}
|
||||
symbol_hash = {}
|
||||
Iconv.open(dest_charset, file_charset) do |i|
|
||||
raw_hash.each {|key, value|
|
||||
symbol_hash[key.to_sym] = i.iconv(value)
|
||||
}
|
||||
end
|
||||
|
||||
# Add strings to repos
|
||||
_add_localized_strings(lang, symbol_hash, override)
|
||||
}
|
||||
_verbose_msg :stats
|
||||
end
|
||||
|
||||
# Restores a backup of GLoc's internal state that was made with backup_state.
|
||||
def restore_state(state)
|
||||
_get_internal_state_vars.each do |o|
|
||||
o.clear
|
||||
o.send o.respond_to?(:merge!) ? :merge! : :concat, state.shift
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the charset used to internally store localized strings.
|
||||
# You can set the charset to use for a specific language or languages,
|
||||
# or if none are specified the charset for ALL localized strings will be set.
|
||||
def set_charset(new_charset, *langs)
|
||||
CONFIG[:internal_charset_per_lang] ||= {}
|
||||
|
||||
# Convert symbol shortcuts
|
||||
if new_charset.is_a?(Symbol)
|
||||
new_charset= case new_charset
|
||||
when :utf8, :utf_8 then UTF_8
|
||||
when :sjis, :shift_jis, :shiftjis then SHIFT_JIS
|
||||
when :eucjp, :euc_jp then EUC_JP
|
||||
else new_charset.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Convert existing strings
|
||||
(langs.empty? ? LOCALIZED_STRINGS.keys : langs).each do |lang|
|
||||
cur_charset= get_charset(lang)
|
||||
if cur_charset && new_charset != cur_charset
|
||||
_verbose_msg {"Converting :#{lang} strings from #{cur_charset} to #{new_charset}"}
|
||||
Iconv.open(new_charset, cur_charset) do |i|
|
||||
bundle= LOCALIZED_STRINGS[lang]
|
||||
bundle.each_pair {|k,v| bundle[k]= i.iconv(v)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Set new charset value
|
||||
if langs.empty?
|
||||
_verbose_msg {"Setting GLoc charset for all languages to #{new_charset}"}
|
||||
CONFIG[:internal_charset]= new_charset
|
||||
CONFIG[:internal_charset_per_lang].clear
|
||||
else
|
||||
langs.each do |lang|
|
||||
_verbose_msg {"Setting GLoc charset for :#{lang} strings to #{new_charset}"}
|
||||
CONFIG[:internal_charset_per_lang][lang]= new_charset
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Sets GLoc configuration values.
|
||||
def set_config(hash)
|
||||
CONFIG.merge! hash
|
||||
end
|
||||
|
||||
# Sets the $KCODE global variable according to a specified charset, or else the
|
||||
# current default charset for the default language.
|
||||
def set_kcode(charset=nil)
|
||||
_charset_required
|
||||
charset ||= get_charset(current_language)
|
||||
$KCODE= case charset
|
||||
when UTF_8 then 'u'
|
||||
when SHIFT_JIS then 's'
|
||||
when EUC_JP then 'e'
|
||||
else 'n'
|
||||
end
|
||||
_verbose_msg {"$KCODE set to #{$KCODE}"}
|
||||
end
|
||||
|
||||
# Tries to find a valid language that is similar to the argument passed.
|
||||
# Eg. :en, :en_au, :EN_US are all similar languages.
|
||||
# Returns <tt>nil</tt> if no similar languages are found.
|
||||
def similar_language(lang)
|
||||
return nil if lang.nil?
|
||||
return lang.to_sym if valid_language?(lang)
|
||||
# Check lowercase without dashes
|
||||
lang= lang.to_s.downcase.gsub('-','_')
|
||||
return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
|
||||
# Check without dialect
|
||||
if lang.to_s =~ /^([a-z]+?)[^a-z].*/
|
||||
lang= $1
|
||||
return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
|
||||
end
|
||||
# Check other dialects
|
||||
lang= "#{lang}_"
|
||||
LOWERCASE_LANGUAGES.keys.each {|k| return LOWERCASE_LANGUAGES[k] if k.starts_with?(lang)}
|
||||
# Nothing found
|
||||
nil
|
||||
end
|
||||
|
||||
# Returns an array of (currently) valid languages (ie. languages for which localized data exists).
|
||||
def valid_languages
|
||||
LOCALIZED_STRINGS.keys
|
||||
end
|
||||
|
||||
# Returns <tt>true</tt> if there are any localized strings for a specified language.
|
||||
# Note that although <tt>set_langauge nil</tt> is perfectly valid, <tt>nil</tt> is not a valid language.
|
||||
def valid_language?(language)
|
||||
LOCALIZED_STRINGS.has_key? language.to_sym rescue false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace :gloc do
|
||||
desc 'Sorts the keys in the lang ymls'
|
||||
task :sort do
|
||||
dir = ENV['DIR'] || '{.,vendor/plugins/*}/lang'
|
||||
puts "Processing directory #{dir}"
|
||||
files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
|
||||
puts 'No files found.' if files.empty?
|
||||
files.each {|file|
|
||||
puts "Sorting file: #{file}"
|
||||
header = []
|
||||
content = IO.readlines(file)
|
||||
content.each {|line| line.gsub!(/[\s\r\n\t]+$/,'')}
|
||||
content.delete_if {|line| line==''}
|
||||
tmp= []
|
||||
content.each {|x| tmp << x unless tmp.include?(x)}
|
||||
content= tmp
|
||||
header << content.shift if !content.empty? && content[0] =~ /^file_charset:/
|
||||
content.sort!
|
||||
filebak = "#{file}.bak"
|
||||
File.rename file, filebak
|
||||
File.open(file, 'w') {|fout| fout << header.join("\n") << content.join("\n") << "\n"}
|
||||
File.delete filebak
|
||||
# Report duplicates
|
||||
count= {}
|
||||
content.map {|x| x.gsub(/:.+$/, '') }.each {|x| count[x] ||= 0; count[x] += 1}
|
||||
count.delete_if {|k,v|v==1}
|
||||
puts count.keys.sort.map{|x|" WARNING: Duplicate key '#{x}' (#{count[x]} occurances)"}.join("\n") unless count.empty?
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,118 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
$LOAD_PATH.push File.join(File.dirname(__FILE__),'..','lib')
|
||||
require "#{File.dirname(__FILE__)}/../../../../test/test_helper"
|
||||
require "#{File.dirname(__FILE__)}/../init"
|
||||
|
||||
class GLocRailsTestController < ActionController::Base
|
||||
autodetect_language_filter :only => :auto, :on_set_lang => :called_when_set, :on_no_lang => :called_when_bad
|
||||
autodetect_language_filter :only => :auto2, :check_accept_header => false, :check_params => 'xx'
|
||||
autodetect_language_filter :only => :auto3, :check_cookie => false
|
||||
autodetect_language_filter :only => :auto4, :check_cookie => 'qwe', :check_params => false
|
||||
def rescue_action(e) raise e end
|
||||
def auto; render :text => 'auto'; end
|
||||
def auto2; render :text => 'auto'; end
|
||||
def auto3; render :text => 'auto'; end
|
||||
def auto4; render :text => 'auto'; end
|
||||
attr_accessor :callback_set, :callback_bad
|
||||
def called_when_set(l) @callback_set ||= 0; @callback_set += 1 end
|
||||
def called_when_bad; @callback_bad ||= 0; @callback_bad += 1 end
|
||||
end
|
||||
|
||||
class GLocRailsTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@lstrings = GLoc::LOCALIZED_STRINGS.clone
|
||||
@old_config= GLoc::CONFIG.clone
|
||||
begin_new_request
|
||||
end
|
||||
|
||||
def teardown
|
||||
GLoc.clear_strings
|
||||
GLoc::LOCALIZED_STRINGS.merge! @lstrings
|
||||
GLoc::CONFIG.merge! @old_config
|
||||
end
|
||||
|
||||
def begin_new_request
|
||||
@controller = GLocRailsTestController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
def test_autodetect_language
|
||||
GLoc::CONFIG[:default_language]= :def
|
||||
GLoc::CONFIG[:default_param_name] = 'plang'
|
||||
GLoc::CONFIG[:default_cookie_name] = 'clang'
|
||||
GLoc.clear_strings
|
||||
GLoc.add_localized_strings :en, :a => 'a'
|
||||
GLoc.add_localized_strings :en_au, :a => 'a'
|
||||
GLoc.add_localized_strings :en_US, :a => 'a'
|
||||
GLoc.add_localized_strings :Ja, :a => 'a'
|
||||
GLoc.add_localized_strings :ZH_HK, :a => 'a'
|
||||
|
||||
# default
|
||||
subtest_autodetect_language :def, nil, nil, nil
|
||||
subtest_autodetect_language :def, 'its', 'all', 'bullshit,man;q=zxc'
|
||||
# simple
|
||||
subtest_autodetect_language :en_au, 'en_au', nil, nil
|
||||
subtest_autodetect_language :en_US, nil, 'en_us', nil
|
||||
subtest_autodetect_language :Ja, nil, nil, 'ja'
|
||||
# priority
|
||||
subtest_autodetect_language :Ja, 'ja', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5'
|
||||
subtest_autodetect_language :en_US, 'why', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5'
|
||||
subtest_autodetect_language :Ja, nil, nil, 'qwe_en,JA,zh,monkey_en;q=0.5'
|
||||
# dashes to underscores in accept string
|
||||
subtest_autodetect_language :en_au, 'monkey', nil, 'de,EN-Au'
|
||||
# remove dialect
|
||||
subtest_autodetect_language :en, nil, 'en-bullshit', nil
|
||||
subtest_autodetect_language :en, 'monkey', nil, 'de,EN-NZ,ja'
|
||||
# different dialect
|
||||
subtest_autodetect_language :ZH_HK, 'zh', nil, 'de,EN-NZ,ja'
|
||||
subtest_autodetect_language :ZH_HK, 'monkey', 'zh', 'de,EN-NZ,ja'
|
||||
|
||||
# Check param/cookie names use defaults
|
||||
GLoc::CONFIG[:default_param_name] = 'p_lang'
|
||||
GLoc::CONFIG[:default_cookie_name] = 'c_lang'
|
||||
# :check_params
|
||||
subtest_autodetect_language :def, 'en_au', nil, nil
|
||||
subtest_autodetect_language :en_au, {:p_lang => 'en_au'}, nil, nil
|
||||
# :check_cookie
|
||||
subtest_autodetect_language :def, nil, 'en_us', nil
|
||||
subtest_autodetect_language :en_US, nil, {:c_lang => 'en_us'}, nil
|
||||
GLoc::CONFIG[:default_param_name] = 'plang'
|
||||
GLoc::CONFIG[:default_cookie_name] = 'clang'
|
||||
|
||||
# autodetect_language_filter :only => :auto2, :check_accept_header => false, :check_params => 'xx'
|
||||
subtest_autodetect_language :def, 'ja', nil, 'en_US', :auto2
|
||||
subtest_autodetect_language :Ja, {:xx => 'ja'}, nil, 'en_US', :auto2
|
||||
subtest_autodetect_language :en_au, 'ja', 'en_au', 'en_US', :auto2
|
||||
|
||||
# autodetect_language_filter :only => :auto3, :check_cookie => false
|
||||
subtest_autodetect_language :Ja, 'ja', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5', :auto3
|
||||
subtest_autodetect_language :ZH_HK, 'hehe', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5', :auto3
|
||||
|
||||
# autodetect_language_filter :only => :auto4, :check_cookie => 'qwe', :check_params => false
|
||||
subtest_autodetect_language :def, 'ja', 'en_us', nil, :auto4
|
||||
subtest_autodetect_language :ZH_HK, 'ja', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5', :auto4
|
||||
subtest_autodetect_language :en_US, 'ja', {:qwe => 'en_us'}, 'ja', :auto4
|
||||
end
|
||||
|
||||
def subtest_autodetect_language(expected,params,cookie,accept, action=:auto)
|
||||
begin_new_request
|
||||
params= {'plang' => params} if params.is_a?(String)
|
||||
params ||= {}
|
||||
if cookie
|
||||
cookie={'clang' => cookie} unless cookie.is_a?(Hash)
|
||||
cookie.each_pair {|k,v| @request.cookies[k.to_s]= CGI::Cookie.new(k.to_s,v)}
|
||||
end
|
||||
@request.env['HTTP_ACCEPT_LANGUAGE']= accept
|
||||
get action, params
|
||||
assert_equal expected, @controller.current_language
|
||||
if action == :auto
|
||||
s,b = expected != :def ? [1,nil] : [nil,1]
|
||||
assert_equal s, @controller.callback_set
|
||||
assert_equal b, @controller.callback_bad
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,433 @@
|
||||
# Copyright (c) 2005-2006 David Barri
|
||||
|
||||
$LOAD_PATH.push File.join(File.dirname(__FILE__),'..','lib')
|
||||
require 'gloc'
|
||||
require 'gloc-ruby'
|
||||
require 'gloc-config'
|
||||
require 'gloc-rails-text'
|
||||
require File.join(File.dirname(__FILE__),'lib','rails-time_ext') unless 3.respond_to?(:days)
|
||||
require File.join(File.dirname(__FILE__),'lib','rails-string_ext') unless ''.respond_to?(:starts_with?)
|
||||
#require 'gloc-dev'
|
||||
|
||||
class LClass; include GLoc; end
|
||||
class LClass2 < LClass; end
|
||||
class LClass_en < LClass2; set_language :en; end
|
||||
class LClass_ja < LClass2; set_language :ja; end
|
||||
# class LClass_forced_au < LClass; set_language :en; force_language :en_AU; set_language :ja; end
|
||||
|
||||
class GLocTest < Test::Unit::TestCase
|
||||
include GLoc
|
||||
include ActionView::Helpers::DateHelper
|
||||
|
||||
def setup
|
||||
@l1 = LClass.new
|
||||
@l2 = LClass.new
|
||||
@l3 = LClass.new
|
||||
@l1.set_language :ja
|
||||
@l2.set_language :en
|
||||
@l3.set_language 'en_AU'
|
||||
@gloc_state= GLoc.backup_state true
|
||||
GLoc::CONFIG.merge!({
|
||||
:default_param_name => 'lang',
|
||||
:default_cookie_name => 'lang',
|
||||
:default_language => :ja,
|
||||
:raise_string_not_found_errors => true,
|
||||
:verbose => false,
|
||||
})
|
||||
end
|
||||
|
||||
def teardown
|
||||
GLoc.restore_state @gloc_state
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def test_basic
|
||||
assert_localized_value [nil, @l1, @l2, @l3], nil, :in_both_langs
|
||||
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
|
||||
assert_localized_value [nil, @l1], 'enにもjaにもある', :in_both_langs
|
||||
assert_localized_value [nil, @l1], '日本語のみ', :ja_only
|
||||
assert_localized_value [nil, @l1], nil, :en_only
|
||||
|
||||
assert_localized_value @l2, 'This is in en+ja', :in_both_langs
|
||||
assert_localized_value @l2, nil, :ja_only
|
||||
assert_localized_value @l2, 'English only', :en_only
|
||||
|
||||
assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
|
||||
assert_localized_value @l3, nil, :ja_only
|
||||
assert_localized_value @l3, 'Aussie English only bro', :en_only
|
||||
|
||||
@l3.set_language :en
|
||||
assert_localized_value @l3, 'This is in en+ja', :in_both_langs
|
||||
assert_localized_value @l3, nil, :ja_only
|
||||
assert_localized_value @l3, 'English only', :en_only
|
||||
|
||||
assert_localized_value nil, 'enにもjaにもある', :in_both_langs
|
||||
assert_localized_value nil, '日本語のみ', :ja_only
|
||||
assert_localized_value nil, nil, :en_only
|
||||
end
|
||||
|
||||
def test_load_twice_with_override
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang2')
|
||||
|
||||
assert_localized_value [nil, @l1], '更新された', :in_both_langs
|
||||
assert_localized_value [nil, @l1], '日本語のみ', :ja_only
|
||||
assert_localized_value [nil, @l1], nil, :en_only
|
||||
assert_localized_value [nil, @l1], nil, :new_en
|
||||
assert_localized_value [nil, @l1], '新たな日本語ストリング', :new_ja
|
||||
|
||||
assert_localized_value @l2, 'This is in en+ja', :in_both_langs
|
||||
assert_localized_value @l2, nil, :ja_only
|
||||
assert_localized_value @l2, 'overriden dude', :en_only
|
||||
assert_localized_value @l2, 'This is a new English string', :new_en
|
||||
assert_localized_value @l2, nil, :new_ja
|
||||
|
||||
assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
|
||||
assert_localized_value @l3, nil, :ja_only
|
||||
assert_localized_value @l3, 'Aussie English only bro', :en_only
|
||||
end
|
||||
|
||||
def test_load_twice_without_override
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang2'), false
|
||||
|
||||
assert_localized_value [nil, @l1], 'enにもjaにもある', :in_both_langs
|
||||
assert_localized_value [nil, @l1], '日本語のみ', :ja_only
|
||||
assert_localized_value [nil, @l1], nil, :en_only
|
||||
assert_localized_value [nil, @l1], nil, :new_en
|
||||
assert_localized_value [nil, @l1], '新たな日本語ストリング', :new_ja
|
||||
|
||||
assert_localized_value @l2, 'This is in en+ja', :in_both_langs
|
||||
assert_localized_value @l2, nil, :ja_only
|
||||
assert_localized_value @l2, 'English only', :en_only
|
||||
assert_localized_value @l2, 'This is a new English string', :new_en
|
||||
assert_localized_value @l2, nil, :new_ja
|
||||
|
||||
assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
|
||||
assert_localized_value @l3, nil, :ja_only
|
||||
assert_localized_value @l3, 'Aussie English only bro', :en_only
|
||||
end
|
||||
|
||||
def test_add_localized_strings
|
||||
assert_localized_value nil, nil, :add
|
||||
assert_localized_value nil, nil, :ja_only
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
assert_localized_value nil, nil, :add
|
||||
assert_localized_value nil, '日本語のみ', :ja_only
|
||||
GLoc.add_localized_strings 'en', {:ja_only => 'bullshit'}, true
|
||||
GLoc.add_localized_strings 'en', {:ja_only => 'bullshit'}, false
|
||||
assert_localized_value nil, nil, :add
|
||||
assert_localized_value nil, '日本語のみ', :ja_only
|
||||
GLoc.add_localized_strings 'ja', {:ja_only => 'bullshit', :add => '123'}, false
|
||||
assert_localized_value nil, '123', :add
|
||||
assert_localized_value nil, '日本語のみ', :ja_only
|
||||
GLoc.add_localized_strings 'ja', {:ja_only => 'bullshit', :add => '234'}
|
||||
assert_localized_value nil, '234', :add
|
||||
assert_localized_value nil, 'bullshit', :ja_only
|
||||
end
|
||||
|
||||
def test_class_set_language
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
|
||||
@l1 = LClass_ja.new
|
||||
@l2 = LClass_en.new
|
||||
@l3 = LClass_en.new
|
||||
|
||||
assert_localized_value @l1, 'enにもjaにもある', :in_both_langs
|
||||
assert_localized_value @l2, 'This is in en+ja', :in_both_langs
|
||||
assert_localized_value @l3, 'This is in en+ja', :in_both_langs
|
||||
|
||||
@l3.set_language 'en_AU'
|
||||
|
||||
assert_localized_value @l1, 'enにもjaにもある', :in_both_langs
|
||||
assert_localized_value @l2, 'This is in en+ja', :in_both_langs
|
||||
assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
|
||||
end
|
||||
|
||||
def test_ll
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
|
||||
assert_equal 'enにもjaにもある', ll('ja',:in_both_langs)
|
||||
assert_equal 'enにもjaにもある', GLoc::ll('ja',:in_both_langs)
|
||||
assert_equal 'enにもjaにもある', LClass_en.ll('ja',:in_both_langs)
|
||||
assert_equal 'enにもjaにもある', LClass_ja.ll('ja',:in_both_langs)
|
||||
|
||||
assert_equal 'This is in en+ja', ll('en',:in_both_langs)
|
||||
assert_equal 'This is in en+ja', GLoc::ll('en',:in_both_langs)
|
||||
assert_equal 'This is in en+ja', LClass_en.ll('en',:in_both_langs)
|
||||
assert_equal 'This is in en+ja', LClass_ja.ll('en',:in_both_langs)
|
||||
end
|
||||
|
||||
def test_lsym
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
|
||||
assert_equal 'enにもjaにもある', LClass_ja.ltry(:in_both_langs)
|
||||
assert_equal 'hello', LClass_ja.ltry('hello')
|
||||
assert_equal nil, LClass_ja.ltry(nil)
|
||||
end
|
||||
|
||||
# def test_forced
|
||||
# assert_equal :en_AU, LClass_forced_au.current_language
|
||||
# a= LClass_forced_au.new
|
||||
# a.set_language :ja
|
||||
# assert_equal :en_AU, a.current_language
|
||||
# a.force_language :ja
|
||||
# assert_equal :ja, a.current_language
|
||||
# assert_equal :en_AU, LClass_forced_au.current_language
|
||||
# end
|
||||
|
||||
def test_pluralization
|
||||
GLoc.add_localized_strings :en, :_gloc_rule_default => %[|n| case n; when 0 then '_none'; when 1 then '_single'; else '_many'; end], :a_single => '%d man', :a_many => '%d men', :a_none => 'No men'
|
||||
GLoc.add_localized_strings :en, :_gloc_rule_asd => %[|n| n<10 ? '_few' : '_heaps'], :a_few => 'a few men (%d)', :a_heaps=> 'soo many men'
|
||||
set_language :en
|
||||
|
||||
assert_equal 'No men', lwr(:a, 0)
|
||||
assert_equal '1 man', lwr(:a, 1)
|
||||
assert_equal '3 men', lwr(:a, 3)
|
||||
assert_equal '20 men', lwr(:a, 20)
|
||||
|
||||
assert_equal 'a few men (0)', lwr_(:asd, :a, 0)
|
||||
assert_equal 'a few men (1)', lwr_(:asd, :a, 1)
|
||||
assert_equal 'a few men (3)', lwr_(:asd, :a, 3)
|
||||
assert_equal 'soo many men', lwr_(:asd, :a, 12)
|
||||
assert_equal 'soo many men', lwr_(:asd, :a, 20)
|
||||
|
||||
end
|
||||
|
||||
def test_distance_in_words
|
||||
load_default_strings
|
||||
[
|
||||
[20.seconds, 'less than a minute', '1分以内', 'меньше минуты'],
|
||||
[80.seconds, '1 minute', '1分', '1 минуту'],
|
||||
[3.seconds, 'less than 5 seconds', '5秒以内', 'менее 5 секунд', true],
|
||||
[9.seconds, 'less than 10 seconds', '10秒以内', 'менее 10 секунд', true],
|
||||
[16.seconds, 'less than 20 seconds', '20秒以内', 'менее 20 секунд', true],
|
||||
[35.seconds, 'half a minute', '約30秒', 'полминуты', true],
|
||||
[50.seconds, 'less than a minute', '1分以内', 'меньше минуты', true],
|
||||
[1.1.minutes, '1 minute', '1分', '1 минуту'],
|
||||
[2.1.minutes, '2 minutes', '2分', '2 минуты'],
|
||||
[4.1.minutes, '4 minutes', '4分', '4 минуты'],
|
||||
[5.1.minutes, '5 minutes', '5分', '5 минут'],
|
||||
[1.1.hours, 'about an hour', '約1時間', 'около часа'],
|
||||
[3.1.hours, 'about 3 hours', '約3時間', 'около 3 часов'],
|
||||
[9.1.hours, 'about 9 hours', '約9時間', 'около 9 часов'],
|
||||
[1.1.days, '1 day', '1日間', '1 день'],
|
||||
[2.1.days, '2 days', '2日間', '2 дня'],
|
||||
[4.days, '4 days', '4日間', '4 дня'],
|
||||
[6.days, '6 days', '6日間', '6 дней'],
|
||||
[11.days, '11 days', '11日間', '11 дней'],
|
||||
[12.days, '12 days', '12日間', '12 дней'],
|
||||
[15.days, '15 days', '15日間', '15 дней'],
|
||||
[20.days, '20 days', '20日間', '20 дней'],
|
||||
[21.days, '21 days', '21日間', '21 день'],
|
||||
[22.days, '22 days', '22日間', '22 дня'],
|
||||
[25.days, '25 days', '25日間', '25 дней'],
|
||||
].each do |a|
|
||||
t, en, ja, ru = a
|
||||
inc_sec= (a.size == 5) ? a[-1] : false
|
||||
set_language :en
|
||||
assert_equal en, distance_of_time_in_words(t,0,inc_sec)
|
||||
set_language :ja
|
||||
assert_equal ja, distance_of_time_in_words(t,0,inc_sec)
|
||||
set_language :ru
|
||||
assert_equal ru, distance_of_time_in_words(t,0,inc_sec)
|
||||
end
|
||||
end
|
||||
|
||||
def test_age
|
||||
load_default_strings
|
||||
[
|
||||
[1, '1 yr', '1歳', '1 год'],
|
||||
[22, '22 yrs', '22歳', '22 года'],
|
||||
[27, '27 yrs', '27歳', '27 лет'],
|
||||
].each do |a, en, ja, ru|
|
||||
set_language :en
|
||||
assert_equal en, l_age(a)
|
||||
set_language :ja
|
||||
assert_equal ja, l_age(a)
|
||||
set_language :ru
|
||||
assert_equal ru, l_age(a)
|
||||
end
|
||||
end
|
||||
|
||||
def test_yesno
|
||||
load_default_strings
|
||||
set_language :en
|
||||
assert_equal 'yes', l_yesno(true)
|
||||
assert_equal 'no', l_yesno(false)
|
||||
assert_equal 'Yes', l_YesNo(true)
|
||||
assert_equal 'No', l_YesNo(false)
|
||||
end
|
||||
|
||||
def test_all_languages_have_values_for_helpers
|
||||
load_default_strings
|
||||
t= Time.local(2000, 9, 15, 11, 23, 57)
|
||||
GLoc.valid_languages.each {|l|
|
||||
set_language l
|
||||
0.upto(120) {|n| l_age(n)}
|
||||
l_date(t)
|
||||
l_datetime(t)
|
||||
l_datetime_short(t)
|
||||
l_time(t)
|
||||
[true,false].each{|v| l_YesNo(v); l_yesno(v) }
|
||||
}
|
||||
end
|
||||
|
||||
def test_similar_languages
|
||||
GLoc.add_localized_strings :en, :a => 'a'
|
||||
GLoc.add_localized_strings :en_AU, :a => 'a'
|
||||
GLoc.add_localized_strings :ja, :a => 'a'
|
||||
GLoc.add_localized_strings :zh_tw, :a => 'a'
|
||||
|
||||
assert_equal :en, GLoc.similar_language(:en)
|
||||
assert_equal :en, GLoc.similar_language('en')
|
||||
assert_equal :ja, GLoc.similar_language(:ja)
|
||||
assert_equal :ja, GLoc.similar_language('ja')
|
||||
# lowercase + dashes to underscores
|
||||
assert_equal :en, GLoc.similar_language('EN')
|
||||
assert_equal :en, GLoc.similar_language(:EN)
|
||||
assert_equal :en_AU, GLoc.similar_language(:EN_Au)
|
||||
assert_equal :en_AU, GLoc.similar_language('eN-Au')
|
||||
# remove dialect
|
||||
assert_equal :ja, GLoc.similar_language(:ja_Au)
|
||||
assert_equal :ja, GLoc.similar_language('JA-ASDF')
|
||||
assert_equal :ja, GLoc.similar_language('jA_ASD_ZXC')
|
||||
# different dialect
|
||||
assert_equal :zh_tw, GLoc.similar_language('ZH')
|
||||
assert_equal :zh_tw, GLoc.similar_language('ZH_HK')
|
||||
assert_equal :zh_tw, GLoc.similar_language('ZH-BUL')
|
||||
# non matching
|
||||
assert_equal nil, GLoc.similar_language('WW')
|
||||
assert_equal nil, GLoc.similar_language('WW_AU')
|
||||
assert_equal nil, GLoc.similar_language('WW-AU')
|
||||
assert_equal nil, GLoc.similar_language('eZ_en')
|
||||
assert_equal nil, GLoc.similar_language('AU-ZH')
|
||||
end
|
||||
|
||||
def test_clear_strings_and_similar_langs
|
||||
GLoc.add_localized_strings :en, :a => 'a'
|
||||
GLoc.add_localized_strings :en_AU, :a => 'a'
|
||||
GLoc.add_localized_strings :ja, :a => 'a'
|
||||
GLoc.add_localized_strings :zh_tw, :a => 'a'
|
||||
GLoc.clear_strings :en, :ja
|
||||
assert_equal nil, GLoc.similar_language('ja')
|
||||
assert_equal :en_AU, GLoc.similar_language('en')
|
||||
assert_equal :zh_tw, GLoc.similar_language('ZH_HK')
|
||||
GLoc.clear_strings
|
||||
assert_equal nil, GLoc.similar_language('ZH_HK')
|
||||
end
|
||||
|
||||
def test_lang_name
|
||||
GLoc.add_localized_strings :en, :general_lang_en => 'English', :general_lang_ja => 'Japanese'
|
||||
GLoc.add_localized_strings :ja, :general_lang_en => '英語', :general_lang_ja => '日本語'
|
||||
set_language :en
|
||||
assert_equal 'Japanese', l_lang_name(:ja)
|
||||
assert_equal 'English', l_lang_name('en')
|
||||
set_language :ja
|
||||
assert_equal '日本語', l_lang_name('ja')
|
||||
assert_equal '英語', l_lang_name(:en)
|
||||
end
|
||||
|
||||
def test_charset_change_all
|
||||
load_default_strings
|
||||
GLoc.add_localized_strings :ja2, :a => 'a'
|
||||
GLoc.valid_languages # Force refresh if in dev mode
|
||||
GLoc.class_eval 'LOCALIZED_STRINGS[:ja2]= LOCALIZED_STRINGS[:ja].clone'
|
||||
|
||||
[:ja, :ja2].each do |l|
|
||||
set_language l
|
||||
assert_equal 'はい', l_yesno(true)
|
||||
assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
|
||||
end
|
||||
|
||||
GLoc.set_charset 'sjis'
|
||||
assert_equal 'sjis', GLoc.get_charset(:ja)
|
||||
assert_equal 'sjis', GLoc.get_charset(:ja2)
|
||||
|
||||
[:ja, :ja2].each do |l|
|
||||
set_language l
|
||||
assert_equal "82CD82A2", l_yesno(true).unpack('H*')[0].upcase
|
||||
end
|
||||
end
|
||||
|
||||
def test_charset_change_single
|
||||
load_default_strings
|
||||
GLoc.add_localized_strings :ja2, :a => 'a'
|
||||
GLoc.add_localized_strings :ja3, :a => 'a'
|
||||
GLoc.valid_languages # Force refresh if in dev mode
|
||||
GLoc.class_eval 'LOCALIZED_STRINGS[:ja2]= LOCALIZED_STRINGS[:ja].clone'
|
||||
GLoc.class_eval 'LOCALIZED_STRINGS[:ja3]= LOCALIZED_STRINGS[:ja].clone'
|
||||
|
||||
[:ja, :ja2, :ja3].each do |l|
|
||||
set_language l
|
||||
assert_equal 'はい', l_yesno(true)
|
||||
assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
|
||||
end
|
||||
|
||||
GLoc.set_charset 'sjis', :ja
|
||||
assert_equal 'sjis', GLoc.get_charset(:ja)
|
||||
assert_equal 'utf-8', GLoc.get_charset(:ja2)
|
||||
assert_equal 'utf-8', GLoc.get_charset(:ja3)
|
||||
|
||||
set_language :ja
|
||||
assert_equal "82CD82A2", l_yesno(true).unpack('H*')[0].upcase
|
||||
set_language :ja2
|
||||
assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
|
||||
set_language :ja3
|
||||
assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
|
||||
|
||||
GLoc.set_charset 'euc-jp', :ja, :ja3
|
||||
assert_equal 'euc-jp', GLoc.get_charset(:ja)
|
||||
assert_equal 'utf-8', GLoc.get_charset(:ja2)
|
||||
assert_equal 'euc-jp', GLoc.get_charset(:ja3)
|
||||
|
||||
set_language :ja
|
||||
assert_equal "A4CFA4A4", l_yesno(true).unpack('H*')[0].upcase
|
||||
set_language :ja2
|
||||
assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
|
||||
set_language :ja3
|
||||
assert_equal "A4CFA4A4", l_yesno(true).unpack('H*')[0].upcase
|
||||
end
|
||||
|
||||
def test_set_language_if_valid
|
||||
GLoc.add_localized_strings :en, :a => 'a'
|
||||
GLoc.add_localized_strings :zh_tw, :a => 'a'
|
||||
|
||||
assert set_language_if_valid('en')
|
||||
assert_equal :en, current_language
|
||||
|
||||
assert set_language_if_valid('zh_tw')
|
||||
assert_equal :zh_tw, current_language
|
||||
|
||||
assert !set_language_if_valid(nil)
|
||||
assert_equal :zh_tw, current_language
|
||||
|
||||
assert !set_language_if_valid('ja')
|
||||
assert_equal :zh_tw, current_language
|
||||
|
||||
assert set_language_if_valid(:en)
|
||||
assert_equal :en, current_language
|
||||
end
|
||||
|
||||
#===========================================================================
|
||||
protected
|
||||
|
||||
def assert_localized_value(objects,expected,key)
|
||||
objects = [objects] unless objects.kind_of?(Array)
|
||||
objects.each {|object|
|
||||
o = object || GLoc
|
||||
assert_equal !expected.nil?, o.l_has_string?(key)
|
||||
if expected.nil?
|
||||
assert_raise(GLoc::StringNotFoundError) {o.l(key)}
|
||||
else
|
||||
assert_equal expected, o.l(key)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def load_default_strings
|
||||
GLoc.load_localized_strings File.join(File.dirname(__FILE__),'..','lang')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
in_both_langs: This is in en+ja
|
||||
en_only: English only
|
||||
@@ -0,0 +1,2 @@
|
||||
in_both_langs: Thiz in en 'n' ja
|
||||
en_only: Aussie English only bro
|
||||
@@ -0,0 +1,2 @@
|
||||
in_both_langs: enにもjaにもある
|
||||
ja_only: 日本語のみ
|
||||
@@ -0,0 +1,2 @@
|
||||
en_only: overriden dude
|
||||
new_en: This is a new English string
|
||||
@@ -0,0 +1,2 @@
|
||||
in_both_langs: 更新された
|
||||
new_ja: 新たな日本語ストリング
|
||||
@@ -0,0 +1,23 @@
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module String #:nodoc:
|
||||
# Additional string tests.
|
||||
module StartsEndsWith
|
||||
# Does the string start with the specified +prefix+?
|
||||
def starts_with?(prefix)
|
||||
prefix = prefix.to_s
|
||||
self[0, prefix.length] == prefix
|
||||
end
|
||||
|
||||
# Does the string end with the specified +suffix+?
|
||||
def ends_with?(suffix)
|
||||
suffix = suffix.to_s
|
||||
self[-suffix.length, suffix.length] == suffix
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
class String
|
||||
include ActiveSupport::CoreExtensions::String::StartsEndsWith
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Numeric #:nodoc:
|
||||
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
|
||||
#
|
||||
# If you need precise date calculations that doesn't just treat months as 30 days, then have
|
||||
# a look at Time#advance.
|
||||
#
|
||||
# Some of these methods are approximations, Ruby's core
|
||||
# Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and
|
||||
# Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision
|
||||
# date and time arithmetic
|
||||
module Time
|
||||
def seconds
|
||||
self
|
||||
end
|
||||
alias :second :seconds
|
||||
|
||||
def minutes
|
||||
self * 60
|
||||
end
|
||||
alias :minute :minutes
|
||||
|
||||
def hours
|
||||
self * 60.minutes
|
||||
end
|
||||
alias :hour :hours
|
||||
|
||||
def days
|
||||
self * 24.hours
|
||||
end
|
||||
alias :day :days
|
||||
|
||||
def weeks
|
||||
self * 7.days
|
||||
end
|
||||
alias :week :weeks
|
||||
|
||||
def fortnights
|
||||
self * 2.weeks
|
||||
end
|
||||
alias :fortnight :fortnights
|
||||
|
||||
def months
|
||||
self * 30.days
|
||||
end
|
||||
alias :month :months
|
||||
|
||||
def years
|
||||
(self * 365.25.days).to_i
|
||||
end
|
||||
alias :year :years
|
||||
|
||||
# Reads best without arguments: 10.minutes.ago
|
||||
def ago(time = ::Time.now)
|
||||
time - self
|
||||
end
|
||||
|
||||
# Reads best with argument: 10.minutes.until(time)
|
||||
alias :until :ago
|
||||
|
||||
# Reads best with argument: 10.minutes.since(time)
|
||||
def since(time = ::Time.now)
|
||||
time + self
|
||||
end
|
||||
|
||||
# Reads best without arguments: 10.minutes.from_now
|
||||
alias :from_now :since
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Numeric #:nodoc:
|
||||
include ActiveSupport::CoreExtensions::Numeric::Time
|
||||
end
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
1.00 Added view template functionality
|
||||
1.10 Added Chinese support
|
||||
1.11 Added Japanese support
|
||||
1.12 Added Korean support
|
||||
1.13 Updated to fpdf.rb 1.53d.
|
||||
Added makefont and fpdf_eps.
|
||||
Handle \n at the beginning of a string in MultiCell.
|
||||
Tried to fix clipping issue in MultiCell - still needs some work.
|
||||
1.14 2006-09-26
|
||||
* Added support for @options_for_rfpdf hash for configuration:
|
||||
* Added :filename option in this hash
|
||||
If you're using the same settings for @options_for_rfpdf often, you might want to
|
||||
put your assignment in a before_filter (perhaps overriding :filename, etc in your actions).
|
||||
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
|
||||
|
||||
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 PURPOa AND
|
||||
NONINFRINGEMENT. IN NO EVENT SaALL 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.
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
= RFPDF Template Plugin
|
||||
|
||||
A template plugin allowing the inclusion of ERB-enabled RFPDF template files.
|
||||
|
||||
== Example .rb method Usage
|
||||
|
||||
In the controller, something like:
|
||||
|
||||
def mypdf
|
||||
pdf = FPDF.new()
|
||||
|
||||
#
|
||||
# Chinese
|
||||
#
|
||||
pdf.extend(PDF_Chinese)
|
||||
pdf.AddPage
|
||||
pdf.AddBig5Font
|
||||
pdf.SetFont('Big5','',18)
|
||||
pdf.Write(5, '²{®É®ð·Å 18 C Àã«× 83 %')
|
||||
icBig5 = Iconv.new('Big5', 'UTF-8')
|
||||
pdf.Write(15, icBig5.iconv("宋体 should be working"))
|
||||
send_data pdf.Output, :filename => "something.pdf", :type => "application/pdf"
|
||||
end
|
||||
|
||||
== Example .rfdf Usage
|
||||
|
||||
In the controller, something like:
|
||||
|
||||
def mypdf
|
||||
@options_for_rfpdf ||= {}
|
||||
@options_for_rfpdf[:file_name] = "nice_looking.pdf"
|
||||
end
|
||||
|
||||
In the layout (make sure this is the only item in the layout):
|
||||
<%= @content_for_layout %>
|
||||
|
||||
In the view (mypdf.rfpdf):
|
||||
|
||||
<%
|
||||
pdf = FPDF.new()
|
||||
#
|
||||
# Chinese
|
||||
#
|
||||
pdf.extend(PDF_Chinese)
|
||||
pdf.AddPage
|
||||
pdf.AddBig5Font
|
||||
pdf.SetFont('Big5','',18)
|
||||
pdf.Write(5, '²{®É®ð·Å 18 C Àã«× 83 %')
|
||||
icBig5 = Iconv.new('Big5', 'UTF-8')
|
||||
pdf.Write(15, icBig5.iconv("宋体 should be working"))
|
||||
|
||||
#
|
||||
# Japanese
|
||||
#
|
||||
pdf.extend(PDF_Japanese)
|
||||
pdf.AddSJISFont();
|
||||
pdf.AddPage();
|
||||
pdf.SetFont('SJIS','',18);
|
||||
pdf.Write(5,'9ÉñåéÇÃåˆäJÉeÉXÉgÇåoǃPHP 3.0ÇÕ1998îN6åéÇ…åˆéÆÇ…ÉäÉäÅ[ÉXÇ≥ÇÍNjǵÇΩÅB');
|
||||
icSJIS = Iconv.new('SJIS', 'UTF-8')
|
||||
pdf.Write(15, icSJIS.iconv("これはテキストである should be working"))
|
||||
|
||||
#
|
||||
# Korean
|
||||
#
|
||||
pdf.extend(PDF_Korean)
|
||||
pdf.AddUHCFont();
|
||||
pdf.AddPage();
|
||||
pdf.SetFont('UHC','',18);
|
||||
pdf.Write(5,'PHP 3.0Àº 1998³â 6¿ù¿¡ °ø½ÄÀûÀ¸·Î ¸±¸®ÁîµÇ¾ú´Ù. °ø°³ÀûÀÎ Å×½ºÆ® ÀÌÈľà 9°³¿ù¸¸À̾ú´Ù.');
|
||||
icUHC = Iconv.new('UHC', 'UTF-8')
|
||||
pdf.Write(15, icUHC.iconv("이것은 원본 이다"))
|
||||
|
||||
#
|
||||
# English
|
||||
#
|
||||
pdf.AddPage();
|
||||
pdf.SetFont('Arial', '', 10)
|
||||
pdf.Write(5, "should be working")
|
||||
%>
|
||||
<%= pdf.Output() %>
|
||||
|
||||
|
||||
== Configuring
|
||||
|
||||
You can configure Rfpdf by using an @options_for_rfpdf hash in your controllers.
|
||||
|
||||
Here are a few options:
|
||||
|
||||
:filename (default: action_name.pdf)
|
||||
Filename of PDF to generate
|
||||
|
||||
Note: If you're using the same settings for @options_for_rfpdf often, you might want to
|
||||
put your assignment in a before_filter (perhaps overriding :filename, etc in your actions).
|
||||
|
||||
== Problems
|
||||
|
||||
Layouts and partials are currently not supported; just need
|
||||
to wrap the PDF generation differently.
|
||||
@@ -0,0 +1,3 @@
|
||||
require 'rfpdf'
|
||||
|
||||
ActionView::Base::register_template_handler 'rfpdf', RFPDF::View
|
||||
@@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# 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.
|
||||
|
||||
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
||||
|
||||
require 'rfpdf/errors'
|
||||
require 'rfpdf/view'
|
||||
require 'rfpdf/fpdf'
|
||||
require 'rfpdf/rfpdf'
|
||||
require 'rfpdf/chinese'
|
||||
require 'rfpdf/japanese'
|
||||
require 'rfpdf/korean'
|
||||
@@ -0,0 +1,99 @@
|
||||
# Translation of the bookmark class from the PHP FPDF script from Olivier Plathey
|
||||
# Translated by Sylvain Lafleur and ?? with the help of Brian Ollenberger
|
||||
#
|
||||
# First added in 1.53b
|
||||
#
|
||||
# Usage is as follows:
|
||||
#
|
||||
# require 'fpdf'
|
||||
# require 'bookmark'
|
||||
# pdf = FPDF.new
|
||||
# pdf.extend(PDF_Bookmark)
|
||||
#
|
||||
# This allows it to be combined with other extensions, such as the Chinese
|
||||
# module.
|
||||
|
||||
module PDF_Bookmark
|
||||
def PDF_Bookmark.extend_object(o)
|
||||
o.instance_eval('@outlines,@OutlineRoot=[],0')
|
||||
super(o)
|
||||
end
|
||||
|
||||
def Bookmark(txt,level=0,y=0)
|
||||
y=self.GetY() if y==-1
|
||||
@outlines.push({'t'=>txt,'l'=>level,'y'=>y,'p'=>self.PageNo()})
|
||||
end
|
||||
|
||||
def putbookmarks
|
||||
@nb=@outlines.size
|
||||
return if @nb==0
|
||||
lru=[]
|
||||
level=0
|
||||
@outlines.each_index do |i|
|
||||
o=@outlines[i]
|
||||
if o['l']>0
|
||||
parent=lru[o['l']-1]
|
||||
# Set parent and last pointers
|
||||
@outlines[i]['parent']=parent
|
||||
@outlines[parent]['last']=i
|
||||
if o['l']>level
|
||||
# Level increasing: set first pointer
|
||||
@outlines[parent]['first']=i
|
||||
end
|
||||
else
|
||||
@outlines[i]['parent']=@nb
|
||||
end
|
||||
if o['l']<=level and i>0
|
||||
# Set prev and next pointers
|
||||
prev=lru[o['l']]
|
||||
@outlines[prev]['next']=i
|
||||
@outlines[i]['prev']=prev
|
||||
end
|
||||
lru[o['l']]=i
|
||||
level=o['l']
|
||||
end
|
||||
# Outline items
|
||||
n=@n+1
|
||||
@outlines.each_index do |i|
|
||||
o=@outlines[i]
|
||||
newobj
|
||||
out('<</Title '+(textstring(o['t'])))
|
||||
out('/Parent '+(n+o['parent']).to_s+' 0 R')
|
||||
if o['prev']
|
||||
out('/Prev '+(n+o['prev']).to_s+' 0 R')
|
||||
end
|
||||
if o['next']
|
||||
out('/Next '+(n+o['next']).to_s+' 0 R')
|
||||
end
|
||||
if o['first']
|
||||
out('/First '+(n+o['first']).to_s+' 0 R')
|
||||
end
|
||||
if o['last']
|
||||
out('/Last '+(n+o['last']).to_s+' 0 R')
|
||||
end
|
||||
out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f
|
||||
null]',1+2*o['p'],(@h-o['y'])*@k))
|
||||
out('/Count 0>>')
|
||||
out('endobj')
|
||||
end
|
||||
# Outline root
|
||||
newobj
|
||||
@OutlineRoot=@n
|
||||
out('<</Type /Outlines /First '+n.to_s+' 0 R')
|
||||
out('/Last '+(n+lru[0]).to_s+' 0 R>>')
|
||||
out('endobj')
|
||||
end
|
||||
|
||||
def putresources
|
||||
super
|
||||
putbookmarks
|
||||
end
|
||||
|
||||
def putcatalog
|
||||
super
|
||||
if not @outlines.empty?
|
||||
out('/Outlines '+@OutlineRoot.to_s+' 0 R')
|
||||
out('/PageMode /UseOutlines')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,473 @@
|
||||
# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
|
||||
# 1.12 contributed by Ed Moss.
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This is direct port of chinese.php
|
||||
#
|
||||
# Chinese PDF support.
|
||||
#
|
||||
# Usage is as follows:
|
||||
#
|
||||
# require 'fpdf'
|
||||
# require 'chinese'
|
||||
# pdf = FPDF.new
|
||||
# pdf.extend(PDF_Chinese)
|
||||
#
|
||||
# This allows it to be combined with other extensions, such as the bookmark
|
||||
# module.
|
||||
|
||||
module PDF_Chinese
|
||||
|
||||
Big5_widths={' '=>250,'!'=>250,'"'=>408,'#'=>668,''=>490,'%'=>875,'&'=>698,'\''=>250,
|
||||
'('=>240,')'=>240,'*'=>417,'+'=>667,','=>250,'-'=>313,'.'=>250,'/'=>520,'0'=>500,'1'=>500,
|
||||
'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>250,''=>250,
|
||||
'<'=>667,'='=>667,'>'=>667,'?'=>396,'@'=>921,'A'=>677,'B'=>615,'C'=>719,'D'=>760,'E'=>625,
|
||||
'F'=>552,'G'=>771,'H'=>802,'I'=>354,'J'=>354,'K'=>781,'L'=>604,'M'=>927,'N'=>750,'O'=>823,
|
||||
'P'=>563,'Q'=>823,'R'=>729,'S'=>542,'T'=>698,'U'=>771,'V'=>729,'W'=>948,'X'=>771,'Y'=>677,
|
||||
'Z'=>635,'['=>344,'\\'=>520,']'=>344,'^'=>469,'_'=>500,'`'=>250,'a'=>469,'b'=>521,'c'=>427,
|
||||
'd'=>521,'e'=>438,'f'=>271,'g'=>469,'h'=>531,'i'=>250,'j'=>250,'k'=>458,'l'=>240,'m'=>802,
|
||||
'n'=>531,'o'=>500,'p'=>521,'q'=>521,'r'=>365,'s'=>333,'t'=>292,'u'=>521,'v'=>458,'w'=>677,
|
||||
'x'=>479,'y'=>458,'z'=>427,'{'=>480,'|'=>496,'end'=>480,'~'=>667}
|
||||
|
||||
GB_widths={' '=>207,'!'=>270,'"'=>342,'#'=>467,''=>462,'%'=>797,'&'=>710,'\''=>239,
|
||||
'('=>374,')'=>374,'*'=>423,'+'=>605,','=>238,'-'=>375,'.'=>238,'/'=>334,'0'=>462,'1'=>462,
|
||||
'2'=>462,'3'=>462,'4'=>462,'5'=>462,'6'=>462,'7'=>462,'8'=>462,'9'=>462,':'=>238,''=>238,
|
||||
'<'=>605,'='=>605,'>'=>605,'?'=>344,'@'=>748,'A'=>684,'B'=>560,'C'=>695,'D'=>739,'E'=>563,
|
||||
'F'=>511,'G'=>729,'H'=>793,'I'=>318,'J'=>312,'K'=>666,'L'=>526,'M'=>896,'N'=>758,'O'=>772,
|
||||
'P'=>544,'Q'=>772,'R'=>628,'S'=>465,'T'=>607,'U'=>753,'V'=>711,'W'=>972,'X'=>647,'Y'=>620,
|
||||
'Z'=>607,'['=>374,'\\'=>333,']'=>374,'^'=>606,'_'=>500,'`'=>239,'a'=>417,'b'=>503,'c'=>427,
|
||||
'd'=>529,'e'=>415,'f'=>264,'g'=>444,'h'=>518,'i'=>241,'j'=>230,'k'=>495,'l'=>228,'m'=>793,
|
||||
'n'=>527,'o'=>524,'p'=>524,'q'=>504,'r'=>338,'s'=>336,'t'=>277,'u'=>517,'v'=>450,'w'=>652,
|
||||
'x'=>466,'y'=>452,'z'=>407,'{'=>370,'|'=>258,'end'=>370,'~'=>605}
|
||||
|
||||
def AddCIDFont(family,style,name,cw,cMap,registry)
|
||||
#ActionController::Base::logger.debug registry.to_a.join(":").to_s
|
||||
fontkey=family.downcase+style.upcase
|
||||
unless @fonts[fontkey].nil?
|
||||
Error("Font already added: family style")
|
||||
end
|
||||
i=@fonts.length+1
|
||||
name=name.gsub(' ','')
|
||||
@fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, 'CMap'=>cMap,'registry'=>registry}
|
||||
end
|
||||
|
||||
def AddCIDFonts(family,name,cw,cMap,registry)
|
||||
AddCIDFont(family,'',name,cw,cMap,registry)
|
||||
AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
|
||||
AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
|
||||
AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddBig5Font(family='Big5',name='MSungStd-Light-Acro')
|
||||
#Add Big5 font with proportional Latin
|
||||
cw=Big5_widths
|
||||
cMap='ETenms-B5-H'
|
||||
registry={'ordering'=>'CNS1','supplement'=>0}
|
||||
#ActionController::Base::logger.debug registry.to_a.join(":").to_s
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddBig5hwFont(family='Big5-hw',name='MSungStd-Light-Acro')
|
||||
#Add Big5 font with half-witdh Latin
|
||||
cw = {}
|
||||
32.upto(126) do |i|
|
||||
cw[i.chr]=500
|
||||
end
|
||||
cMap='ETen-B5-H'
|
||||
registry={'ordering'=>'CNS1','supplement'=>0}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddGBFont(family='GB',name='STSongStd-Light-Acro')
|
||||
#Add GB font with proportional Latin
|
||||
cw=GB_widths
|
||||
cMap='GBKp-EUC-H'
|
||||
registry={'ordering'=>'GB1','supplement'=>2}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddGBhwFont(family='GB-hw',name='STSongStd-Light-Acro')
|
||||
#Add GB font with half-width Latin
|
||||
32.upto(126) do |i|
|
||||
cw[i.chr]=500
|
||||
end
|
||||
cMap='GBK-EUC-H'
|
||||
registry={'ordering'=>'GB1','supplement'=>2}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def GetStringWidth(s)
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
return GetMBStringWidth(s)
|
||||
else
|
||||
return super(s)
|
||||
end
|
||||
end
|
||||
|
||||
def GetMBStringWidth(s)
|
||||
#Multi-byte version of GetStringWidth()
|
||||
l=0
|
||||
cw=@CurrentFont['cw']
|
||||
nb=s.length
|
||||
i=0
|
||||
while(i<nb)
|
||||
c=s[i]
|
||||
if(c<128)
|
||||
l+=cw[c.chr]
|
||||
i+=1
|
||||
else
|
||||
l+=1000
|
||||
i+=2
|
||||
end
|
||||
end
|
||||
return l*@FontSize/1000
|
||||
end
|
||||
|
||||
def MultiCell(w,h,txt,border=0,align='L',fill=0)
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
MBMultiCell(w,h,txt,border,align,fill)
|
||||
else
|
||||
super(w,h,txt,border,align,fill)
|
||||
end
|
||||
end
|
||||
|
||||
def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
|
||||
#Multi-byte version of MultiCell()
|
||||
cw=@CurrentFont['cw']
|
||||
if(w==0)
|
||||
w=@w-@rMargin-@x
|
||||
end
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
s=txt.gsub("\r",'')
|
||||
nb=s.length
|
||||
if(nb>0 and s[nb-1]=="\n")
|
||||
nb-=1
|
||||
end
|
||||
b=0
|
||||
if(border)
|
||||
if(border==1)
|
||||
border='LTRB'
|
||||
b='LRT'
|
||||
b2='LR'
|
||||
else
|
||||
b2=''
|
||||
if(border.index('L').nil?)
|
||||
b2+='L'
|
||||
end
|
||||
if(border.index('R').nil?)
|
||||
b2+='R'
|
||||
end
|
||||
b=border.index('T').nil? ? b2+'T' : b2
|
||||
end
|
||||
end
|
||||
sep=-1
|
||||
i=0
|
||||
j=0
|
||||
l=0
|
||||
nl=1
|
||||
while(i<nb)
|
||||
#Get next character
|
||||
c=s[i]
|
||||
#Check if ASCII or MB
|
||||
ascii=(c<128)
|
||||
if(c=="\n")
|
||||
#Explicit line break
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
i+=1
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
nl+=1
|
||||
if(border and nl==2)
|
||||
b=b2
|
||||
end
|
||||
next
|
||||
end
|
||||
if(!ascii)
|
||||
sep=i
|
||||
ls=l
|
||||
elsif(c==' ')
|
||||
sep=i
|
||||
ls=l
|
||||
end
|
||||
l+=ascii ? cw[c.chr] : 1000
|
||||
if(l>wmax)
|
||||
#Automatic line break
|
||||
if(sep==-1 or i==j)
|
||||
if(i==j)
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
else
|
||||
Cell(w,h,s[j,sep-j],b,2,align,fill)
|
||||
i=(s[sep]==' ') ? sep+1 : sep
|
||||
end
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
# nl+=1
|
||||
if(border and nl==2)
|
||||
b=b2
|
||||
end
|
||||
else
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
end
|
||||
#Last chunk
|
||||
if(border and not border.index('B').nil?)
|
||||
b+='B'
|
||||
end
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
@x=@lMargin
|
||||
end
|
||||
|
||||
def Write(h,txt,link='')
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
MBWrite(h,txt,link)
|
||||
else
|
||||
super(h,txt,link)
|
||||
end
|
||||
end
|
||||
|
||||
def MBWrite(h,txt,link)
|
||||
#Multi-byte version of Write()
|
||||
cw=@CurrentFont['cw']
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
s=txt.gsub("\r",'')
|
||||
nb=s.length
|
||||
sep=-1
|
||||
i=0
|
||||
j=0
|
||||
l=0
|
||||
nl=1
|
||||
while(i<nb)
|
||||
#Get next character
|
||||
c=s[i]
|
||||
#Check if ASCII or MB
|
||||
ascii=(c<128)
|
||||
if(c=="\n")
|
||||
#Explicit line break
|
||||
Cell(w,h,s[j,i-j],0,2,'',0,link)
|
||||
i+=1
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
if(nl==1)
|
||||
@x=@lMargin
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
end
|
||||
nl+=1
|
||||
next
|
||||
end
|
||||
if(!ascii or c==' ')
|
||||
sep=i
|
||||
end
|
||||
l+=ascii ? cw[c.chr] : 1000
|
||||
if(l>wmax)
|
||||
#Automatic line break
|
||||
if(sep==-1 or i==j)
|
||||
if(@x>@lMargin)
|
||||
#Move to next line
|
||||
@x=@lMargin
|
||||
@y+=h
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
i+=1
|
||||
nl+=1
|
||||
next
|
||||
end
|
||||
if(i==j)
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
Cell(w,h,s[j,i-j],0,2,'',0,link)
|
||||
else
|
||||
Cell(w,h,s[j,sep-j],0,2,'',0,link)
|
||||
i=(s[sep]==' ') ? sep+1 : sep
|
||||
end
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
if(nl==1)
|
||||
@x=@lMargin
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
end
|
||||
nl+=1
|
||||
else
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
end
|
||||
#Last chunk
|
||||
if(i!=j)
|
||||
Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def putfonts()
|
||||
nf=@n
|
||||
@diffs.each do |diff|
|
||||
#Encodings
|
||||
newobj()
|
||||
out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
|
||||
out('endobj')
|
||||
end
|
||||
# mqr=get_magic_quotes_runtime()
|
||||
# set_magic_quotes_runtime(0)
|
||||
@FontFiles.each_pair do |file, info|
|
||||
#Font file embedding
|
||||
newobj()
|
||||
@FontFiles[file]['n']=@n
|
||||
if(defined('FPDF_FONTPATH'))
|
||||
file=FPDF_FONTPATH+file
|
||||
end
|
||||
size=filesize(file)
|
||||
if(!size)
|
||||
Error('Font file not found')
|
||||
end
|
||||
out('<</Length '+size)
|
||||
if(file[-2]=='.z')
|
||||
out('/Filter /FlateDecode')
|
||||
end
|
||||
out('/Length1 '+info['length1'])
|
||||
unless info['length2'].nil?
|
||||
out('/Length2 '+info['length2']+' /Length3 0')
|
||||
end
|
||||
out('>>')
|
||||
f=fopen(file,'rb')
|
||||
putstream(fread(f,size))
|
||||
fclose(f)
|
||||
out('endobj')
|
||||
end
|
||||
#
|
||||
# set_magic_quotes_runtime(mqr)
|
||||
#
|
||||
@fonts.each_pair do |k, font|
|
||||
#Font objects
|
||||
newobj()
|
||||
@fonts[k]['n']=@n
|
||||
out('<</Type /Font')
|
||||
if(font['type']=='Type0')
|
||||
putType0(font)
|
||||
else
|
||||
name=font['name']
|
||||
out('/BaseFont /'+name)
|
||||
if(font['type']=='core')
|
||||
#Standard font
|
||||
out('/Subtype /Type1')
|
||||
if(name!='Symbol' and name!='ZapfDingbats')
|
||||
out('/Encoding /WinAnsiEncoding')
|
||||
end
|
||||
else
|
||||
#Additional font
|
||||
out('/Subtype /'+font['type'])
|
||||
out('/FirstChar 32')
|
||||
out('/LastChar 255')
|
||||
out('/Widths '+(@n+1)+' 0 R')
|
||||
out('/FontDescriptor '+(@n+2)+' 0 R')
|
||||
if(font['enc'])
|
||||
if !font['diff'].nil?
|
||||
out('/Encoding '+(nf+font['diff'])+' 0 R')
|
||||
else
|
||||
out('/Encoding /WinAnsiEncoding')
|
||||
end
|
||||
end
|
||||
end
|
||||
out('>>')
|
||||
out('endobj')
|
||||
if(font['type']!='core')
|
||||
#Widths
|
||||
newobj()
|
||||
cw=font['cw']
|
||||
s='['
|
||||
32.upto(255) do |i|
|
||||
s+=cw[i.chr]+' '
|
||||
end
|
||||
out(s+']')
|
||||
out('endobj')
|
||||
#Descriptor
|
||||
newobj()
|
||||
s='<</Type /FontDescriptor /FontName /'+name
|
||||
font['desc'].each_pair do |k, v|
|
||||
s+=' /'+k+' '+v
|
||||
end
|
||||
file=font['file']
|
||||
if(file)
|
||||
s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R'
|
||||
end
|
||||
out(s+'>>')
|
||||
out('endobj')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def putType0(font)
|
||||
#Type0
|
||||
out('/Subtype /Type0')
|
||||
out('/BaseFont /'+font['name']+'-'+font['CMap'])
|
||||
out('/Encoding /'+font['CMap'])
|
||||
out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
#CIDFont
|
||||
newobj()
|
||||
out('<</Type /Font')
|
||||
out('/Subtype /CIDFontType0')
|
||||
out('/BaseFont /'+font['name'])
|
||||
out('/CIDSystemInfo <</Registry '+textstring('Adobe')+' /Ordering '+textstring(font['registry']['ordering'])+' /Supplement '+font['registry']['supplement'].to_s+'>>')
|
||||
out('/FontDescriptor '+(@n+1).to_s+' 0 R')
|
||||
if(font['CMap']=='ETen-B5-H')
|
||||
w='13648 13742 500'
|
||||
elsif(font['CMap']=='GBK-EUC-H')
|
||||
w='814 907 500 7716 [500]'
|
||||
else
|
||||
# ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s
|
||||
# ActionController::Base::logger.debug font['cw'].values.join(' ').to_s
|
||||
w='1 ['
|
||||
font['cw'].keys.sort.each {|key|
|
||||
w+=font['cw'][key].to_s + " "
|
||||
# ActionController::Base::logger.debug key.to_s
|
||||
# ActionController::Base::logger.debug font['cw'][key].to_s
|
||||
}
|
||||
w +=']'
|
||||
end
|
||||
out('/W ['+w+']>>')
|
||||
out('endobj')
|
||||
#Font descriptor
|
||||
newobj()
|
||||
out('<</Type /FontDescriptor')
|
||||
out('/FontName /'+font['name'])
|
||||
out('/Flags 6')
|
||||
out('/FontBBox [0 -200 1000 900]')
|
||||
out('/ItalicAngle 0')
|
||||
out('/Ascent 800')
|
||||
out('/Descent -200')
|
||||
out('/CapHeight 800')
|
||||
out('/StemV 50')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
module RFPDF
|
||||
class GenerationError < StandardError #:nodoc:
|
||||
end
|
||||
end
|
||||
+1550
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
||||
# Information
|
||||
#
|
||||
# PDF_EPS class from Valentin Schmidt ported to ruby by Thiago Jackiw (tjackiw@gmail.com)
|
||||
# working for Mingle LLC (www.mingle.com)
|
||||
# Release Date: July 13th, 2006
|
||||
#
|
||||
# Description
|
||||
#
|
||||
# This script allows to embed vector-based Adobe Illustrator (AI) or AI-compatible EPS files.
|
||||
# Only vector drawing is supported, not text or bitmap. Although the script was successfully
|
||||
# tested with various AI format versions, best results are probably achieved with files that
|
||||
# were exported in the AI3 format (tested with Illustrator CS2, Freehand MX and Photoshop CS2).
|
||||
#
|
||||
# ImageEps(string file, float x, float y [, float w [, float h [, string link [, boolean useBoundingBox]]]])
|
||||
#
|
||||
# Same parameters as for regular FPDF::Image() method, with an additional one:
|
||||
#
|
||||
# useBoundingBox: specifies whether to position the bounding box (true) or the complete canvas (false)
|
||||
# at location (x,y). Default value is true.
|
||||
#
|
||||
# First added to the Ruby FPDF distribution in 1.53c
|
||||
#
|
||||
# Usage is as follows:
|
||||
#
|
||||
# require 'fpdf'
|
||||
# require 'fpdf_eps'
|
||||
# pdf = FPDF.new
|
||||
# pdf.extend(PDF_EPS)
|
||||
# pdf.ImageEps(...)
|
||||
#
|
||||
# This allows it to be combined with other extensions, such as the bookmark
|
||||
# module.
|
||||
|
||||
module PDF_EPS
|
||||
def ImageEps(file, x, y, w=0, h=0, link='', use_bounding_box=true)
|
||||
data = nil
|
||||
if File.exists?(file)
|
||||
File.open(file, 'rb') do |f|
|
||||
data = f.read()
|
||||
end
|
||||
else
|
||||
Error('EPS file not found: '+file)
|
||||
end
|
||||
|
||||
# Find BoundingBox param
|
||||
regs = data.scan(/%%BoundingBox: [^\r\n]*/m)
|
||||
regs << regs[0].gsub(/%%BoundingBox: /, '')
|
||||
if regs.size > 1
|
||||
tmp = regs[1].to_s.split(' ')
|
||||
@x1 = tmp[0].to_i
|
||||
@y1 = tmp[1].to_i
|
||||
@x2 = tmp[2].to_i
|
||||
@y2 = tmp[3].to_i
|
||||
else
|
||||
Error('No BoundingBox found in EPS file: '+file)
|
||||
end
|
||||
f_start = data.index('%%EndSetup')
|
||||
f_start = data.index('%%EndProlog') if f_start === false
|
||||
f_start = data.index('%%BoundingBox') if f_start === false
|
||||
|
||||
data = data.slice(f_start, data.length)
|
||||
|
||||
f_end = data.index('%%PageTrailer')
|
||||
f_end = data.index('showpage') if f_end === false
|
||||
data = data.slice(0, f_end) if f_end
|
||||
|
||||
# save the current graphic state
|
||||
out('q')
|
||||
|
||||
k = @k
|
||||
|
||||
# Translate
|
||||
if use_bounding_box
|
||||
dx = x*k-@x1
|
||||
dy = @hPt-@y2-y*k
|
||||
else
|
||||
dx = x*k
|
||||
dy = -y*k
|
||||
end
|
||||
tm = [1,0,0,1,dx,dy]
|
||||
out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm',
|
||||
tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]))
|
||||
|
||||
if w > 0
|
||||
scale_x = w/((@x2-@x1)/k)
|
||||
if h > 0
|
||||
scale_y = h/((@y2-@y1)/k)
|
||||
else
|
||||
scale_y = scale_x
|
||||
h = (@y2-@y1)/k * scale_y
|
||||
end
|
||||
else
|
||||
if h > 0
|
||||
scale_y = $h/((@y2-@y1)/$k)
|
||||
scale_x = scale_y
|
||||
w = (@x2-@x1)/k * scale_x
|
||||
else
|
||||
w = (@x2-@x1)/k
|
||||
h = (@y2-@y1)/k
|
||||
end
|
||||
end
|
||||
|
||||
if !scale_x.nil?
|
||||
# Scale
|
||||
tm = [scale_x,0,0,scale_y,0,@hPt*(1-scale_y)]
|
||||
out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm',
|
||||
tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]))
|
||||
end
|
||||
|
||||
data.split(/\r\n|[\r\n]/).each do |line|
|
||||
next if line == '' || line[0,1] == '%'
|
||||
len = line.length
|
||||
# next if (len > 2 && line[len-2,len] != ' ')
|
||||
cmd = line[len-2,len].strip
|
||||
case cmd
|
||||
when 'm', 'l', 'v', 'y', 'c', 'k', 'K', 'g', 'G', 's', 'S', 'J', 'j', 'w', 'M', 'd':
|
||||
out(line)
|
||||
|
||||
when 'L':
|
||||
line[len-1,len]='l'
|
||||
out(line)
|
||||
|
||||
when 'C':
|
||||
line[len-1,len]='c'
|
||||
out(line)
|
||||
|
||||
when 'f', 'F':
|
||||
out('f*')
|
||||
|
||||
when 'b', 'B':
|
||||
out(cmd + '*')
|
||||
end
|
||||
end
|
||||
|
||||
# restore previous graphic state
|
||||
out('Q')
|
||||
Link(x,y,w,h,link) if link
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,468 @@
|
||||
# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
|
||||
# 1.12 contributed by Ed Moss.
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This is direct port of japanese.php
|
||||
#
|
||||
# Japanese PDF support.
|
||||
#
|
||||
# Usage is as follows:
|
||||
#
|
||||
# require 'fpdf'
|
||||
# require 'chinese'
|
||||
# pdf = FPDF.new
|
||||
# pdf.extend(PDF_Japanese)
|
||||
#
|
||||
# This allows it to be combined with other extensions, such as the bookmark
|
||||
# module.
|
||||
|
||||
module PDF_Japanese
|
||||
|
||||
SJIS_widths={' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216,
|
||||
'(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614,
|
||||
'2' => 614, '3' => 614, '4' => 614, '5' => 614, '6' => 614, '7' => 614, '8' => 614, '9' => 614, ':' => 219, ';' => 219,
|
||||
'<' => 529, '=' => 529, '>' => 529, '?' => 486, '@' => 744, 'A' => 646, 'B' => 604, 'C' => 617, 'D' => 681, 'E' => 567,
|
||||
'F' => 537, 'G' => 647, 'H' => 738, 'I' => 320, 'J' => 433, 'K' => 637, 'L' => 566, 'M' => 904, 'N' => 710, 'O' => 716,
|
||||
'P' => 605, 'Q' => 716, 'R' => 623, 'S' => 517, 'T' => 601, 'U' => 690, 'V' => 668, 'W' => 990, 'X' => 681, 'Y' => 634,
|
||||
'Z' => 578, '[' => 316, '\\' => 614, ']' => 316, '^' => 529, '_' => 500, '`' => 387, 'a' => 509, 'b' => 566, 'c' => 478,
|
||||
'd' => 565, 'e' => 503, 'f' => 337, 'g' => 549, 'h' => 580, 'i' => 275, 'j' => 266, 'k' => 544, 'l' => 276, 'm' => 854,
|
||||
'n' => 579, 'o' => 550, 'p' => 578, 'q' => 566, 'r' => 410, 's' => 444, 't' => 340, 'u' => 575, 'v' => 512, 'w' => 760,
|
||||
'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387}
|
||||
|
||||
def AddCIDFont(family,style,name,cw,cMap,registry)
|
||||
fontkey=family.downcase+style.upcase
|
||||
unless @fonts[fontkey].nil?
|
||||
Error("CID font already added: family style")
|
||||
end
|
||||
i=@fonts.length+1
|
||||
@fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-120,'ut'=>40,'cw'=>cw,
|
||||
'CMap'=>cMap,'registry'=>registry}
|
||||
end
|
||||
|
||||
def AddCIDFonts(family,name,cw,cMap,registry)
|
||||
AddCIDFont(family,'',name,cw,cMap,registry)
|
||||
AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
|
||||
AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
|
||||
AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddSJISFont(family='SJIS')
|
||||
#Add SJIS font with proportional Latin
|
||||
name='KozMinPro-Regular-Acro'
|
||||
cw=SJIS_widths
|
||||
cMap='90msp-RKSJ-H'
|
||||
registry={'ordering'=>'Japan1','supplement'=>2}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddSJIShwFont(family='SJIS-hw')
|
||||
#Add SJIS font with half-width Latin
|
||||
name='KozMinPro-Regular-Acro'
|
||||
32.upto(126) do |i|
|
||||
cw[i.chr]=500
|
||||
end
|
||||
cMap='90ms-RKSJ-H'
|
||||
registry={'ordering'=>'Japan1','supplement'=>2}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def GetStringWidth(s)
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
return GetSJISStringWidth(s)
|
||||
else
|
||||
return super(s)
|
||||
end
|
||||
end
|
||||
|
||||
def GetSJISStringWidth(s)
|
||||
#SJIS version of GetStringWidth()
|
||||
l=0
|
||||
cw=@CurrentFont['cw']
|
||||
nb=s.length
|
||||
i=0
|
||||
while(i<nb)
|
||||
o=s[i]
|
||||
if(o<128)
|
||||
#ASCII
|
||||
l+=cw[o.chr]
|
||||
i+=1
|
||||
elsif(o>=161 and o<=223)
|
||||
#Half-width katakana
|
||||
l+=500
|
||||
i+=1
|
||||
else
|
||||
#Full-width character
|
||||
l+=1000
|
||||
i+=2
|
||||
end
|
||||
end
|
||||
return l*@FontSize/1000
|
||||
end
|
||||
|
||||
def MultiCell(w,h,txt,border=0,align='L',fill=0)
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
SJISMultiCell(w,h,txt,border,align,fill)
|
||||
else
|
||||
super(w,h,txt,border,align,fill)
|
||||
end
|
||||
end
|
||||
|
||||
def SJISMultiCell(w,h,txt,border=0,align='L',fill=0)
|
||||
#Output text with automatic or explicit line breaks
|
||||
cw=@CurrentFont['cw']
|
||||
if(w==0)
|
||||
w=@w-@rMargin-@x
|
||||
end
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
s=txt.gsub("\r",'')
|
||||
nb=s.length
|
||||
if(nb>0 and s[nb-1]=="\n")
|
||||
nb-=1
|
||||
end
|
||||
b=0
|
||||
if(border)
|
||||
if(border==1)
|
||||
border='LTRB'
|
||||
b='LRT'
|
||||
b2='LR'
|
||||
else
|
||||
b2=''
|
||||
if(border.index('L').nil?)
|
||||
b2+='L'
|
||||
end
|
||||
if(border.index('R').nil?)
|
||||
b2+='R'
|
||||
end
|
||||
b=border.index('T').nil? ? b2+'T' : b2
|
||||
end
|
||||
end
|
||||
sep=-1
|
||||
i=0
|
||||
j=0
|
||||
l=0
|
||||
nl=1
|
||||
while(i<nb)
|
||||
#Get next character
|
||||
c=s[i]
|
||||
o=ord(c)
|
||||
if(o==10)
|
||||
#Explicit line break
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
i+=1
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
nl+=1
|
||||
if(border and nl==2)
|
||||
b=b2
|
||||
end
|
||||
next
|
||||
end
|
||||
if(o<128)
|
||||
#ASCII
|
||||
l+=cw[c.chr]
|
||||
n=1
|
||||
if(o==32)
|
||||
sep=i
|
||||
end
|
||||
elsif(o>=161 and o<=223)
|
||||
#Half-width katakana
|
||||
l+=500
|
||||
n=1
|
||||
sep=i
|
||||
else
|
||||
#Full-width character
|
||||
l+=1000
|
||||
n=2
|
||||
sep=i
|
||||
end
|
||||
if(l>wmax)
|
||||
#Automatic line break
|
||||
if(sep==-1 or i==j)
|
||||
if(i==j)
|
||||
i+=n
|
||||
end
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
else
|
||||
Cell(w,h,s[j,sep-j],b,2,align,fill)
|
||||
i=(s[sep]==' ') ? sep+1 : sep
|
||||
end
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
nl+=1
|
||||
if(border and nl==2)
|
||||
b=b2
|
||||
end
|
||||
else
|
||||
i+=n
|
||||
if(o>=128)
|
||||
sep=i
|
||||
end
|
||||
end
|
||||
end
|
||||
#Last chunk
|
||||
if(border and not border.index('B').nil?)
|
||||
b+='B'
|
||||
end
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
@x=@lMargin
|
||||
end
|
||||
|
||||
def Write(h,txt,link='')
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
SJISWrite(h,txt,link)
|
||||
else
|
||||
super(h,txt,link)
|
||||
end
|
||||
end
|
||||
|
||||
def SJISWrite(h,txt,link)
|
||||
#SJIS version of Write()
|
||||
cw=@CurrentFont['cw']
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
s=txt.gsub("\r",'')
|
||||
nb=s.length
|
||||
sep=-1
|
||||
i=0
|
||||
j=0
|
||||
l=0
|
||||
nl=1
|
||||
while(i<nb)
|
||||
#Get next character
|
||||
c=s[i]
|
||||
o=c
|
||||
if(o==10)
|
||||
#Explicit line break
|
||||
Cell(w,h,s[j,i-j],0,2,'',0,link)
|
||||
i+=1
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
if(nl==1)
|
||||
#Go to left margin
|
||||
@x=@lMargin
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
end
|
||||
nl+=1
|
||||
next
|
||||
end
|
||||
if(o<128)
|
||||
#ASCII
|
||||
l+=cw[c.chr]
|
||||
n=1
|
||||
if(o==32)
|
||||
sep=i
|
||||
end
|
||||
elsif(o>=161 and o<=223)
|
||||
#Half-width katakana
|
||||
l+=500
|
||||
n=1
|
||||
sep=i
|
||||
else
|
||||
#Full-width character
|
||||
l+=1000
|
||||
n=2
|
||||
sep=i
|
||||
end
|
||||
if(l>wmax)
|
||||
#Automatic line break
|
||||
if(sep==-1 or i==j)
|
||||
if(@x>@lMargin)
|
||||
#Move to next line
|
||||
@x=@lMargin
|
||||
@y+=h
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
i+=n
|
||||
nl+=1
|
||||
next
|
||||
end
|
||||
if(i==j)
|
||||
i+=n
|
||||
end
|
||||
Cell(w,h,s[j,i-j],0,2,'',0,link)
|
||||
else
|
||||
Cell(w,h,s[j,sep-j],0,2,'',0,link)
|
||||
i=(s[sep]==' ') ? sep+1 : sep
|
||||
end
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
if(nl==1)
|
||||
@x=@lMargin
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
end
|
||||
nl+=1
|
||||
else
|
||||
i+=n
|
||||
if(o>=128)
|
||||
sep=i
|
||||
end
|
||||
end
|
||||
end
|
||||
#Last chunk
|
||||
if(i!=j)
|
||||
Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def putfonts()
|
||||
nf=@n
|
||||
@diffs.each do |diff|
|
||||
#Encodings
|
||||
newobj()
|
||||
out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
|
||||
out('endobj')
|
||||
end
|
||||
# mqr=get_magic_quotes_runtime()
|
||||
# set_magic_quotes_runtime(0)
|
||||
@FontFiles.each_pair do |file, info|
|
||||
#Font file embedding
|
||||
newobj()
|
||||
@FontFiles[file]['n']=@n
|
||||
if(defined('FPDF_FONTPATH'))
|
||||
file=FPDF_FONTPATH+file
|
||||
end
|
||||
size=filesize(file)
|
||||
if(!size)
|
||||
Error('Font file not found')
|
||||
end
|
||||
out('<</Length '+size)
|
||||
if(file[-2]=='.z')
|
||||
out('/Filter /FlateDecode')
|
||||
end
|
||||
out('/Length1 '+info['length1'])
|
||||
unless info['length2'].nil?
|
||||
out('/Length2 '+info['length2']+' /Length3 0')
|
||||
end
|
||||
out('>>')
|
||||
f=fopen(file,'rb')
|
||||
putstream(fread(f,size))
|
||||
fclose(f)
|
||||
out('endobj')
|
||||
end
|
||||
# set_magic_quotes_runtime(mqr)
|
||||
@fonts.each_pair do |k, font|
|
||||
#Font objects
|
||||
newobj()
|
||||
@fonts[k]['n']=@n
|
||||
out('<</Type /Font')
|
||||
if(font['type']=='Type0')
|
||||
putType0(font)
|
||||
else
|
||||
name=font['name']
|
||||
out('/BaseFont /'+name)
|
||||
if(font['type']=='core')
|
||||
#Standard font
|
||||
out('/Subtype /Type1')
|
||||
if(name!='Symbol' and name!='ZapfDingbats')
|
||||
out('/Encoding /WinAnsiEncoding')
|
||||
end
|
||||
else
|
||||
#Additional font
|
||||
out('/Subtype /'+font['type'])
|
||||
out('/FirstChar 32')
|
||||
out('/LastChar 255')
|
||||
out('/Widths '+(@n+1)+' 0 R')
|
||||
out('/FontDescriptor '+(@n+2)+' 0 R')
|
||||
if(font['enc'])
|
||||
if !font['diff'].nil?
|
||||
out('/Encoding '+(nf+font['diff'])+' 0 R')
|
||||
else
|
||||
out('/Encoding /WinAnsiEncoding')
|
||||
end
|
||||
end
|
||||
end
|
||||
out('>>')
|
||||
out('endobj')
|
||||
if(font['type']!='core')
|
||||
#Widths
|
||||
newobj()
|
||||
cw=font['cw']
|
||||
s='['
|
||||
32.upto(255) do |i|
|
||||
s+=cw[i.chr]+' '
|
||||
end
|
||||
out(s+']')
|
||||
out('endobj')
|
||||
#Descriptor
|
||||
newobj()
|
||||
s='<</Type /FontDescriptor /FontName /'+name
|
||||
font['desc'].each_pair do |k, v|
|
||||
s+=' /'+k+' '+v
|
||||
end
|
||||
file=font['file']
|
||||
if(file)
|
||||
s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R'
|
||||
end
|
||||
out(s+'>>')
|
||||
out('endobj')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def putType0(font)
|
||||
#Type0
|
||||
out('/Subtype /Type0')
|
||||
out('/BaseFont /'+font['name']+'-'+font['CMap'])
|
||||
out('/Encoding /'+font['CMap'])
|
||||
out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
#CIDFont
|
||||
newobj()
|
||||
out('<</Type /Font')
|
||||
out('/Subtype /CIDFontType0')
|
||||
out('/BaseFont /'+font['name'])
|
||||
out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
|
||||
out('/FontDescriptor '+(@n+1).to_s+' 0 R')
|
||||
w='/W [1 ['
|
||||
font['cw'].keys.sort.each {|key|
|
||||
w+=font['cw'][key].to_s + " "
|
||||
# ActionController::Base::logger.debug key.to_s
|
||||
# ActionController::Base::logger.debug font['cw'][key].to_s
|
||||
}
|
||||
out(w+'] 231 325 500 631 [500] 326 389 500]')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
#Font descriptor
|
||||
newobj()
|
||||
out('<</Type /FontDescriptor')
|
||||
out('/FontName /'+font['name'])
|
||||
out('/Flags 6')
|
||||
out('/FontBBox [0 -200 1000 900]')
|
||||
out('/ItalicAngle 0')
|
||||
out('/Ascent 800')
|
||||
out('/Descent -200')
|
||||
out('/CapHeight 800')
|
||||
out('/StemV 60')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,436 @@
|
||||
# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
|
||||
# 1.12 contributed by Ed Moss.
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This is direct port of korean.php
|
||||
#
|
||||
# Korean PDF support.
|
||||
#
|
||||
# Usage is as follows:
|
||||
#
|
||||
# require 'fpdf'
|
||||
# require 'chinese'
|
||||
# pdf = FPDF.new
|
||||
# pdf.extend(PDF_Korean)
|
||||
#
|
||||
# This allows it to be combined with other extensions, such as the bookmark
|
||||
# module.
|
||||
|
||||
module PDF_Korean
|
||||
|
||||
UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250,
|
||||
'(' => 500, ')' => 500, '*' => 500, '+' => 833, ',' => 291, '-' => 833, '.' => 291, '/' => 375, '0' => 625, '1' => 625,
|
||||
'2' => 625, '3' => 625, '4' => 625, '5' => 625, '6' => 625, '7' => 625, '8' => 625, '9' => 625, ':' => 333, ';' => 333,
|
||||
'<' => 833, '=' => 833, '>' => 916, '?' => 500, '@' => 1000, 'A' => 791, 'B' => 708, 'C' => 708, 'D' => 750, 'E' => 708,
|
||||
'F' => 666, 'G' => 750, 'H' => 791, 'I' => 375, 'J' => 500, 'K' => 791, 'L' => 666, 'M' => 916, 'N' => 791, 'O' => 750,
|
||||
'P' => 666, 'Q' => 750, 'R' => 708, 'S' => 666, 'T' => 791, 'U' => 791, 'V' => 750, 'W' => 1000, 'X' => 708, 'Y' => 708,
|
||||
'Z' => 666, '[' => 500, '\\' => 375, ']' => 500, '^' => 500, '_' => 500, '`' => 333, 'a' => 541, 'b' => 583, 'c' => 541,
|
||||
'd' => 583, 'e' => 583, 'f' => 375, 'g' => 583, 'h' => 583, 'i' => 291, 'j' => 333, 'k' => 583, 'l' => 291, 'm' => 875,
|
||||
'n' => 583, 'o' => 583, 'p' => 583, 'q' => 583, 'r' => 458, 's' => 541, 't' => 375, 'u' => 583, 'v' => 583, 'w' => 833,
|
||||
'x' => 625, 'y' => 625, 'z' => 500, '{' => 583, '|' => 583, '}' => 583, '~' => 750}
|
||||
|
||||
def AddCIDFont(family,style,name,cw,cMap,registry)
|
||||
fontkey=family.downcase+style.upcase
|
||||
unless @fonts[fontkey].nil?
|
||||
Error("Font already added: family style")
|
||||
end
|
||||
i=@fonts.length+1
|
||||
name=name.gsub(' ','')
|
||||
@fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw,
|
||||
'CMap'=>cMap,'registry'=>registry}
|
||||
end
|
||||
|
||||
def AddCIDFonts(family,name,cw,cMap,registry)
|
||||
AddCIDFont(family,'',name,cw,cMap,registry)
|
||||
AddCIDFont(family,'B',name+',Bold',cw,cMap,registry)
|
||||
AddCIDFont(family,'I',name+',Italic',cw,cMap,registry)
|
||||
AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro')
|
||||
#Add UHC font with proportional Latin
|
||||
cw=UHC_widths
|
||||
cMap='KSCms-UHC-H'
|
||||
registry={'ordering'=>'Korea1','supplement'=>1}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro')
|
||||
#Add UHC font with half-witdh Latin
|
||||
32.upto(126) do |i|
|
||||
cw[i.chr]=500
|
||||
end
|
||||
cMap='KSCms-UHC-HW-H'
|
||||
registry={'ordering'=>'Korea1','supplement'=>1}
|
||||
AddCIDFonts(family,name,cw,cMap,registry)
|
||||
end
|
||||
|
||||
def GetStringWidth(s)
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
return GetMBStringWidth(s)
|
||||
else
|
||||
return super(s)
|
||||
end
|
||||
end
|
||||
|
||||
def GetMBStringWidth(s)
|
||||
#Multi-byte version of GetStringWidth()
|
||||
l=0
|
||||
cw=@CurrentFont['cw']
|
||||
nb=s.length
|
||||
i=0
|
||||
while(i<nb)
|
||||
c=s[i]
|
||||
if(c<128)
|
||||
l+=cw[c.chr]
|
||||
i+=1
|
||||
else
|
||||
l+=1000
|
||||
i+=2
|
||||
end
|
||||
end
|
||||
return l*@FontSize/1000
|
||||
end
|
||||
|
||||
def MultiCell(w,h,txt,border=0,align='L',fill=0)
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
MBMultiCell(w,h,txt,border,align,fill)
|
||||
else
|
||||
super(w,h,txt,border,align,fill)
|
||||
end
|
||||
end
|
||||
|
||||
def MBMultiCell(w,h,txt,border=0,align='L',fill=0)
|
||||
#Multi-byte version of MultiCell()
|
||||
cw=@CurrentFont['cw']
|
||||
if(w==0)
|
||||
w=@w-@rMargin-@x
|
||||
end
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
s=txt.gsub("\r",'')
|
||||
nb=s.length
|
||||
if(nb>0 and s[nb-1]=="\n")
|
||||
nb-=1
|
||||
end
|
||||
b=0
|
||||
if(border)
|
||||
if(border==1)
|
||||
border='LTRB'
|
||||
b='LRT'
|
||||
b2='LR'
|
||||
else
|
||||
b2=''
|
||||
if(border.index('L').nil?)
|
||||
b2+='L'
|
||||
end
|
||||
if(border.index('R').nil?)
|
||||
b2+='R'
|
||||
end
|
||||
b=border.index('T').nil? ? b2+'T' : b2
|
||||
end
|
||||
end
|
||||
sep=-1
|
||||
i=0
|
||||
j=0
|
||||
l=0
|
||||
nl=1
|
||||
while(i<nb)
|
||||
#Get next character
|
||||
c=s[i]
|
||||
#Check if ASCII or MB
|
||||
ascii=(c<128)
|
||||
if(c=="\n")
|
||||
#Explicit line break
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
i+=1
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
nl+=1
|
||||
if(border and nl==2)
|
||||
b=b2
|
||||
end
|
||||
next
|
||||
end
|
||||
if(!ascii)
|
||||
sep=i
|
||||
ls=l
|
||||
elsif(c==' ')
|
||||
sep=i
|
||||
ls=l
|
||||
end
|
||||
l+=ascii ? cw[c.chr] : 1000
|
||||
if(l>wmax)
|
||||
#Automatic line break
|
||||
if(sep==-1 or i==j)
|
||||
if(i==j)
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
else
|
||||
Cell(w,h,s[j,sep-j],b,2,align,fill)
|
||||
i=(s[sep]==' ') ? sep+1 : sep
|
||||
end
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
nl+=1
|
||||
if(border and nl==2)
|
||||
b=b2
|
||||
end
|
||||
else
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
end
|
||||
#Last chunk
|
||||
if(border and not border.index('B').nil?)
|
||||
b+='B'
|
||||
end
|
||||
Cell(w,h,s[j,i-j],b,2,align,fill)
|
||||
@x=@lMargin
|
||||
end
|
||||
|
||||
def Write(h,txt,link='')
|
||||
if(@CurrentFont['type']=='Type0')
|
||||
MBWrite(h,txt,link)
|
||||
else
|
||||
super(h,txt,link)
|
||||
end
|
||||
end
|
||||
|
||||
def MBWrite(h,txt,link)
|
||||
#Multi-byte version of Write()
|
||||
cw=@CurrentFont['cw']
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
s=txt.gsub("\r",'')
|
||||
nb=s.length
|
||||
sep=-1
|
||||
i=0
|
||||
j=0
|
||||
l=0
|
||||
nl=1
|
||||
while(i<nb)
|
||||
#Get next character
|
||||
c=s[i]
|
||||
#Check if ASCII or MB
|
||||
ascii=(c<128)
|
||||
if(c=="\n")
|
||||
#Explicit line break
|
||||
Cell(w,h,s[j,i-j],0,2,'',0,link)
|
||||
i+=1
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
if(nl==1)
|
||||
@x=@lMargin
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
end
|
||||
nl+=1
|
||||
next
|
||||
end
|
||||
if(!ascii or c==' ')
|
||||
sep=i
|
||||
end
|
||||
l+=ascii ? cw[c.chr] : 1000
|
||||
if(l>wmax)
|
||||
#Automatic line break
|
||||
if(sep==-1 or i==j)
|
||||
if(@x>@lMargin)
|
||||
#Move to next line
|
||||
@x=@lMargin
|
||||
@y+=h
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
i+=1
|
||||
nl+=1
|
||||
next
|
||||
end
|
||||
if(i==j)
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
Cell(w,h,s[j,i-j],0,2,'',0,link)
|
||||
else
|
||||
Cell(w,h,s[j,sep-j],0,2,'',0,link)
|
||||
i=(s[sep]==' ') ? sep+1 : sep
|
||||
end
|
||||
sep=-1
|
||||
j=i
|
||||
l=0
|
||||
if(nl==1)
|
||||
@x=@lMargin
|
||||
w=@w-@rMargin-@x
|
||||
wmax=(w-2*@cMargin)*1000/@FontSize
|
||||
end
|
||||
nl+=1
|
||||
else
|
||||
i+=ascii ? 1 : 2
|
||||
end
|
||||
end
|
||||
#Last chunk
|
||||
if(i!=j)
|
||||
Cell(l/1000*@FontSize,h,s[j,i-j],0,0,'',0,link)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def putfonts()
|
||||
nf=@n
|
||||
@diffs.each do |diff|
|
||||
#Encodings
|
||||
newobj()
|
||||
out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>')
|
||||
out('endobj')
|
||||
end
|
||||
# mqr=get_magic_quotes_runtime()
|
||||
# set_magic_quotes_runtime(0)
|
||||
@FontFiles.each_pair do |file, info|
|
||||
#Font file embedding
|
||||
newobj()
|
||||
@FontFiles[file]['n']=@n
|
||||
if(defined('FPDF_FONTPATH'))
|
||||
file=FPDF_FONTPATH+file
|
||||
end
|
||||
size=filesize(file)
|
||||
if(!size)
|
||||
Error('Font file not found')
|
||||
end
|
||||
out('<</Length '+size)
|
||||
if(file[-2]=='.z')
|
||||
out('/Filter /FlateDecode')
|
||||
end
|
||||
out('/Length1 '+info['length1'])
|
||||
if(not info['length2'].nil?)
|
||||
out('/Length2 '+info['length2']+' /Length3 0')
|
||||
end
|
||||
out('>>')
|
||||
f=fopen(file,'rb')
|
||||
putstream(fread(f,size))
|
||||
fclose(f)
|
||||
out('endobj')
|
||||
end
|
||||
# set_magic_quotes_runtime(mqr)
|
||||
@fonts.each_pair do |k, font|
|
||||
#Font objects
|
||||
newobj()
|
||||
@fonts[k]['n']=@n
|
||||
out('<</Type /Font')
|
||||
if(font['type']=='Type0')
|
||||
putType0(font)
|
||||
else
|
||||
name=font['name']
|
||||
out('/BaseFont /'+name)
|
||||
if(font['type']=='core')
|
||||
#Standard font
|
||||
out('/Subtype /Type1')
|
||||
if(name!='Symbol' and name!='ZapfDingbats')
|
||||
out('/Encoding /WinAnsiEncoding')
|
||||
end
|
||||
else
|
||||
#Additional font
|
||||
out('/Subtype /'+font['type'])
|
||||
out('/FirstChar 32')
|
||||
out('/LastChar 255')
|
||||
out('/Widths '+(@n+1)+' 0 R')
|
||||
out('/FontDescriptor '+(@n+2)+' 0 R')
|
||||
if(font['enc'])
|
||||
if(not font['diff'].nil?)
|
||||
out('/Encoding '+(nf+font['diff'])+' 0 R')
|
||||
else
|
||||
out('/Encoding /WinAnsiEncoding')
|
||||
end
|
||||
end
|
||||
end
|
||||
out('>>')
|
||||
out('endobj')
|
||||
if(font['type']!='core')
|
||||
#Widths
|
||||
newobj()
|
||||
cw=font['cw']
|
||||
s='['
|
||||
32.upto(255) do |i|
|
||||
s+=cw[i.chr]+' '
|
||||
end
|
||||
out(s+']')
|
||||
out('endobj')
|
||||
#Descriptor
|
||||
newobj()
|
||||
s='<</Type /FontDescriptor /FontName /'+name
|
||||
font['desc'].each_pair do |k, v|
|
||||
s+=' /'+k+' '+v
|
||||
end
|
||||
file=font['file']
|
||||
if(file)
|
||||
s+=' /FontFile'+(font['type']=='Type1' ? '' : '2')+' '+@FontFiles[file]['n']+' 0 R'
|
||||
end
|
||||
out(s+'>>')
|
||||
out('endobj')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def putType0(font)
|
||||
#Type0
|
||||
out('/Subtype /Type0')
|
||||
out('/BaseFont /'+font['name']+'-'+font['CMap'])
|
||||
out('/Encoding /'+font['CMap'])
|
||||
out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
#CIDFont
|
||||
newobj()
|
||||
out('<</Type /Font')
|
||||
out('/Subtype /CIDFontType0')
|
||||
out('/BaseFont /'+font['name'])
|
||||
out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
|
||||
out('/FontDescriptor '+(@n+1).to_s+' 0 R')
|
||||
if(font['CMap']=='KSCms-UHC-HW-H')
|
||||
w='8094 8190 500'
|
||||
else
|
||||
w='1 ['
|
||||
font['cw'].keys.sort.each {|key|
|
||||
w+=font['cw'][key].to_s + " "
|
||||
# ActionController::Base::logger.debug key.to_s
|
||||
# ActionController::Base::logger.debug font['cw'][key].to_s
|
||||
}
|
||||
w +=']'
|
||||
end
|
||||
out('/W ['+w+']>>')
|
||||
out('endobj')
|
||||
#Font descriptor
|
||||
newobj()
|
||||
out('<</Type /FontDescriptor')
|
||||
out('/FontName /'+font['name'])
|
||||
out('/Flags 6')
|
||||
out('/FontBBox [0 -200 1000 900]')
|
||||
out('/ItalicAngle 0')
|
||||
out('/Ascent 800')
|
||||
out('/Descent -200')
|
||||
out('/CapHeight 800')
|
||||
out('/StemV 50')
|
||||
out('>>')
|
||||
out('endobj')
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,346 @@
|
||||
module RFPDF
|
||||
COLOR_PALETTE = {
|
||||
:black => [0x00, 0x00, 0x00],
|
||||
:white => [0xff, 0xff, 0xff],
|
||||
}.freeze
|
||||
|
||||
# Draw a line from (<tt>x1, y1</tt>) to (<tt>x2, y2</tt>).
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:line_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:line_width</tt> - Default value is <tt>0.5</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# draw_line(x1, y1, x1, y1+h, :line_color => ReportHelper::COLOR_PALETTE[:dark_blue], :line_width => 1)
|
||||
#
|
||||
def draw_line(x1, y1, x2, y2, options = {})
|
||||
options[:line_color] ||= COLOR_PALETTE[:black]
|
||||
options[:line_width] ||= 0.5
|
||||
set_draw_color(options[:line_color])
|
||||
SetLineWidth(options[:line_width])
|
||||
Line(x1, y1, x2, y2)
|
||||
end
|
||||
|
||||
# Draw a string of <tt>text</tt> at (<tt>x, y</tt>).
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:font_size</tt> - Default value is <tt>10</tt>.
|
||||
# * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# draw_text(x, y, header_left, :font_size => 10)
|
||||
#
|
||||
def draw_text(x, y, text, options = {})
|
||||
options[:font_color] ||= COLOR_PALETTE[:black]
|
||||
options[:font_size] ||= 10
|
||||
options[:font_style] ||= ''
|
||||
set_text_color(options[:font_color])
|
||||
SetFont('Arial', options[:font_style], options[:font_size])
|
||||
SetXY(x, y)
|
||||
Write(options[:font_size] + 4, text)
|
||||
end
|
||||
|
||||
# Draw a block of <tt>text</tt> at (<tt>x, y</tt>) bounded by <tt>left_margin</tt> and <tt>right_margin</tt>. Both
|
||||
# margins are measured from their corresponding edge.
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:font_size</tt> - Default value is <tt>10</tt>.
|
||||
# * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# draw_text_block(left_margin, 85, "question", left_margin, 280,
|
||||
# :font_color => ReportHelper::COLOR_PALETTE[:dark_blue],
|
||||
# :font_size => 12,
|
||||
# :font_style => 'I')
|
||||
#
|
||||
def draw_text_block(x, y, text, left_margin, right_margin, options = {})
|
||||
options[:font_color] ||= COLOR_PALETTE[:black]
|
||||
options[:font_size] ||= 10
|
||||
options[:font_style] ||= ''
|
||||
set_text_color(options[:font_color])
|
||||
SetFont('Arial', options[:font_style], options[:font_size])
|
||||
SetXY(x, y)
|
||||
SetLeftMargin(left_margin)
|
||||
SetRightMargin(right_margin)
|
||||
Write(options[:font_size] + 4, text)
|
||||
SetMargins(0,0,0)
|
||||
end
|
||||
|
||||
# Draw a box at (<tt>x, y</tt>), <tt>w</tt> wide and <tt>h</tt> high.
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:border</tt> - Draw a border, 0 = no, 1 = yes? Default value is <tt>1</tt>.
|
||||
# * <tt>:border_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:border_width</tt> - Default value is <tt>0.5</tt>.
|
||||
# * <tt>:fill</tt> - Fill the box, 0 = no, 1 = yes? Default value is <tt>1</tt>.
|
||||
# * <tt>:fill_color</tt> - Default value is nothing or <tt>COLOR_PALETTE[:white]</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# draw_box(x, y - 1, 38, 22)
|
||||
#
|
||||
def draw_box(x, y, w, h, options = {})
|
||||
options[:border] ||= 1
|
||||
options[:border_color] ||= COLOR_PALETTE[:black]
|
||||
options[:border_width] ||= 0.5
|
||||
options[:fill] ||= 1
|
||||
options[:fill_color] ||= COLOR_PALETTE[:white]
|
||||
SetLineWidth(options[:border_width])
|
||||
set_draw_color(options[:border_color])
|
||||
set_fill_color(options[:fill_color])
|
||||
fd = ""
|
||||
fd = "D" if options[:border] == 1
|
||||
fd += "F" if options[:fill] == 1
|
||||
Rect(x, y, w, h, fd)
|
||||
end
|
||||
|
||||
# Draw a string of <tt>text</tt> at (<tt>x, y</tt>) in a box <tt>w</tt> wide and <tt>h</tt> high.
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:align</tt> - Vertical alignment 'C' = center, 'L' = left, 'R' = right. Default value is <tt>'C'</tt>.
|
||||
# * <tt>:border</tt> - Draw a border, 0 = no, 1 = yes? Default value is <tt>0</tt>.
|
||||
# * <tt>:border_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:border_width</tt> - Default value is <tt>0.5</tt>.
|
||||
# * <tt>:fill</tt> - Fill the box, 0 = no, 1 = yes? Default value is <tt>1</tt>.
|
||||
# * <tt>:fill_color</tt> - Default value is nothing or <tt>COLOR_PALETTE[:white]</tt>.
|
||||
# * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:font_size</tt> - Default value is nothing or <tt>8</tt>.
|
||||
# * <tt>:font_style</tt> - 'B' = bold, 'I' = italic, 'U' = underline. Default value is nothing <tt>''</tt>.
|
||||
# * <tt>:padding</tt> - Default value is nothing or <tt>2</tt>.
|
||||
# * <tt>:valign</tt> - 'M' = middle, 'T' = top, 'B' = bottom. Default value is nothing or <tt>'M'</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# draw_text_box(x, y - 1, 38, 22,
|
||||
# "your_score_title",
|
||||
# :fill => 0,
|
||||
# :font_color => ReportHelper::COLOR_PALETTE[:blue],
|
||||
# :font_line_spacing => 0,
|
||||
# :font_style => "B",
|
||||
# :valign => "M")
|
||||
#
|
||||
def draw_text_box(x, y, w, h, text, options = {})
|
||||
options[:align] ||= 'C'
|
||||
options[:border] ||= 0
|
||||
options[:border_color] ||= COLOR_PALETTE[:black]
|
||||
options[:border_width] ||= 0.5
|
||||
options[:fill] ||= 1
|
||||
options[:fill_color] ||= COLOR_PALETTE[:white]
|
||||
options[:font_color] ||= COLOR_PALETTE[:black]
|
||||
options[:font_size] ||= 8
|
||||
options[:font_line_spacing] ||= options[:font_size] * 0.3
|
||||
options[:font_style] ||= ''
|
||||
options[:padding] ||= 2
|
||||
options[:valign] ||= "M"
|
||||
if options[:fill] == 1 or options[:border] == 1
|
||||
draw_box(x, y, w, h, options)
|
||||
end
|
||||
SetMargins(0,0,0)
|
||||
set_text_color(options[:font_color])
|
||||
font_size = options[:font_size]
|
||||
SetFont('Arial', options[:font_style], font_size)
|
||||
font_size += options[:font_line_spacing]
|
||||
case options[:valign]
|
||||
when "B"
|
||||
y -= options[:padding]
|
||||
text = "\n" + text if text["\n"].nil?
|
||||
when "T"
|
||||
y += options[:padding]
|
||||
end
|
||||
SetXY(x, y)
|
||||
if GetStringWidth(text) > w or not text["\n"].nil? or options[:valign] == "T"
|
||||
font_size += options[:font_size] * 0.1
|
||||
#TODO 2006-07-21 Level=1 - this is assuming a 2 line text
|
||||
SetXY(x, y + ((h - (font_size * 2)) / 2)) if options[:valign] == "M"
|
||||
MultiCell(w, font_size, text, 0, options[:align])
|
||||
else
|
||||
Cell(w, h, text, 0, 0, options[:align])
|
||||
end
|
||||
end
|
||||
|
||||
# Draw a string of <tt>text</tt> at (<tt>x, y</tt>) as a title.
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:font_color</tt> - Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
# * <tt>:font_size</tt> - Default value is <tt>18</tt>.
|
||||
# * <tt>:font_style</tt> - Default value is nothing or <tt>''</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# draw_title(left_margin, 60,
|
||||
# "title:",
|
||||
# :font_color => ReportHelper::COLOR_PALETTE[:dark_blue])
|
||||
#
|
||||
def draw_title(x, y, title, options = {})
|
||||
options[:font_color] ||= COLOR_PALETTE[:black]
|
||||
options[:font_size] ||= 18
|
||||
options[:font_style] ||= ''
|
||||
set_text_color(options[:font_color])
|
||||
SetFont('Arial', options[:font_style], options[:font_size])
|
||||
SetXY(x, y)
|
||||
Write(options[:font_size] + 2, title)
|
||||
end
|
||||
|
||||
# Set the draw color. Default value is <tt>COLOR_PALETTE[:black]</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# set_draw_color(ReportHelper::COLOR_PALETTE[:dark_blue])
|
||||
#
|
||||
def set_draw_color(color = COLOR_PALETTE[:black])
|
||||
SetDrawColor(color[0], color[1], color[2])
|
||||
end
|
||||
|
||||
# Set the fill color. Default value is <tt>COLOR_PALETTE[:white]</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# set_fill_color(ReportHelper::COLOR_PALETTE[:dark_blue])
|
||||
#
|
||||
def set_fill_color(color = COLOR_PALETTE[:white])
|
||||
SetFillColor(color[0], color[1], color[2])
|
||||
end
|
||||
|
||||
# Set the text color. Default value is <tt>COLOR_PALETTE[:white]</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# set_text_color(ReportHelper::COLOR_PALETTE[:dark_blue])
|
||||
#
|
||||
def set_text_color(color = COLOR_PALETTE[:black])
|
||||
SetTextColor(color[0], color[1], color[2])
|
||||
end
|
||||
|
||||
# Write a string containing html characters. Default value is <tt>COLOR_PALETTE[:white]</tt>.
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:height</tt> - Line height. Default value is <tt>20</tt>.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# write_html(html, :height => 12)
|
||||
#
|
||||
def write_html(html, options = {})
|
||||
options[:height] ||= 20
|
||||
#HTML parser
|
||||
@href = nil
|
||||
@style = {}
|
||||
html.gsub!("\n",' ')
|
||||
re = %r{ ( <!--.*?--> |
|
||||
< (?:
|
||||
[^<>"] +
|
||||
|
|
||||
" (?: \\. | [^\\"]+ ) * "
|
||||
) *
|
||||
>
|
||||
) }xm
|
||||
|
||||
html.split(re).each do |value|
|
||||
if "<" == value[0,1]
|
||||
#Tag
|
||||
if (value[1, 1] == '/')
|
||||
close_tag(value[2..-2], options)
|
||||
else
|
||||
tag = value[1..-2]
|
||||
open_tag(tag, options)
|
||||
end
|
||||
else
|
||||
#Text
|
||||
if @href
|
||||
put_link(@href,value)
|
||||
else
|
||||
Write(options[:height], value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def open_tag(tag, options = {}) #:nodoc:
|
||||
#Opening tag
|
||||
tag = tag.to_s.upcase
|
||||
set_style(tag, true) if tag == 'B' or tag == 'I' or tag == 'U'
|
||||
@href = options['HREF'] if tag == 'A'
|
||||
Ln(options[:height]) if tag == 'BR'
|
||||
end
|
||||
|
||||
def close_tag(tag, options = {}) #:nodoc:
|
||||
#Closing tag
|
||||
tag = tag.to_s.upcase
|
||||
set_style(tag, false) if tag == 'B' or tag == 'I' or tag == 'U'
|
||||
@href = '' if $tag == 'A'
|
||||
end
|
||||
|
||||
def set_style(tag, enable = true) #:nodoc:
|
||||
#Modify style and select corresponding font
|
||||
style = ""
|
||||
@style[tag] = enable
|
||||
['B','I','U'].each do |s|
|
||||
style += s if not @style[s].nil? and @style[s]
|
||||
end
|
||||
SetFont('', style)
|
||||
end
|
||||
|
||||
def put_link(url, txt) #:nodoc:
|
||||
#Put a hyperlink
|
||||
SetTextColor(0,0,255)
|
||||
set_style('U',true)
|
||||
Write(5, txt, url)
|
||||
set_style('U',false)
|
||||
SetTextColor(0)
|
||||
end
|
||||
end
|
||||
|
||||
# class FPDF
|
||||
# alias_method :set_margins , :SetMargins
|
||||
# alias_method :set_left_margin , :SetLeftMargin
|
||||
# alias_method :set_top_margin , :SetTopMargin
|
||||
# alias_method :set_right_margin , :SetRightMargin
|
||||
# alias_method :set_auto_pagebreak , :SetAutoPageBreak
|
||||
# alias_method :set_display_mode , :SetDisplayMode
|
||||
# alias_method :set_compression , :SetCompression
|
||||
# alias_method :set_title , :SetTitle
|
||||
# alias_method :set_subject , :SetSubject
|
||||
# alias_method :set_author , :SetAuthor
|
||||
# alias_method :set_keywords , :SetKeywords
|
||||
# alias_method :set_creator , :SetCreator
|
||||
# alias_method :set_draw_color , :SetDrawColor
|
||||
# alias_method :set_fill_color , :SetFillColor
|
||||
# alias_method :set_text_color , :SetTextColor
|
||||
# alias_method :set_line_width , :SetLineWidth
|
||||
# alias_method :set_font , :SetFont
|
||||
# alias_method :set_font_size , :SetFontSize
|
||||
# alias_method :set_link , :SetLink
|
||||
# alias_method :set_y , :SetY
|
||||
# alias_method :set_xy , :SetXY
|
||||
# alias_method :get_string_width , :GetStringWidth
|
||||
# alias_method :get_x , :GetX
|
||||
# alias_method :set_x , :SetX
|
||||
# alias_method :get_y , :GetY
|
||||
# alias_method :accept_pagev_break , :AcceptPageBreak
|
||||
# alias_method :add_font , :AddFont
|
||||
# alias_method :add_link , :AddLink
|
||||
# alias_method :add_page , :AddPage
|
||||
# alias_method :alias_nb_pages , :AliasNbPages
|
||||
# alias_method :cell , :Cell
|
||||
# alias_method :close , :Close
|
||||
# alias_method :error , :Error
|
||||
# alias_method :footer , :Footer
|
||||
# alias_method :header , :Header
|
||||
# alias_method :image , :Image
|
||||
# alias_method :line , :Line
|
||||
# alias_method :link , :Link
|
||||
# alias_method :ln , :Ln
|
||||
# alias_method :multi_cell , :MultiCell
|
||||
# alias_method :open , :Open
|
||||
# alias_method :Open , :open
|
||||
# alias_method :output , :Output
|
||||
# alias_method :page_no , :PageNo
|
||||
# alias_method :rect , :Rect
|
||||
# alias_method :text , :Text
|
||||
# alias_method :write , :Write
|
||||
# end
|
||||
@@ -0,0 +1,75 @@
|
||||
# Copyright (c) 2006 4ssoM LLC <www.4ssoM.com>
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Thanks go out to Bruce Williams of codefluency who created RTex. This
|
||||
# template handler is modification of his work.
|
||||
#
|
||||
# Example Registration
|
||||
#
|
||||
# ActionView::Base::register_template_handler 'rfpdf', RFpdfView
|
||||
|
||||
module RFPDF
|
||||
|
||||
class View
|
||||
|
||||
def initialize(action_view)
|
||||
@action_view = action_view
|
||||
# Override with @options_for_rfpdf Hash in your controller
|
||||
@options = {
|
||||
# Run through latex first? (for table of contents, etc)
|
||||
:pre_process => false,
|
||||
# Debugging mode; raises exception
|
||||
:debug => false,
|
||||
# Filename of pdf to generate
|
||||
:file_name => "#{@action_view.controller.action_name}.pdf",
|
||||
# Temporary Directory
|
||||
:temp_dir => "#{File.expand_path(RAILS_ROOT)}/tmp"
|
||||
}.merge(@action_view.controller.instance_eval{ @options_for_rfpdf } || {}).with_indifferent_access
|
||||
end
|
||||
|
||||
def render(template, local_assigns = {})
|
||||
@pdf_name = "Default.pdf" if @pdf_name.nil?
|
||||
unless @action_view.controller.headers["Content-Type"] == 'application/pdf'
|
||||
@generate = true
|
||||
@action_view.controller.headers["Content-Type"] = 'application/pdf'
|
||||
@action_view.controller.headers["Content-disposition:"] = "inline; filename=\"#{@options[:file_name]}\""
|
||||
end
|
||||
assigns = @action_view.assigns.dup
|
||||
|
||||
if content_for_layout = @action_view.instance_variable_get("@content_for_layout")
|
||||
assigns['content_for_layout'] = content_for_layout
|
||||
end
|
||||
|
||||
result = @action_view.instance_eval do
|
||||
assigns.each do |key,val|
|
||||
instance_variable_set "@#{key}", val
|
||||
end
|
||||
local_assigns.each do |key,val|
|
||||
class << self; self; end.send(:define_method,key){ val }
|
||||
end
|
||||
ERB.new(template).result(binding)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1 @@
|
||||
#!/usr/bin/env ruby
|
||||
@@ -0,0 +1,272 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street,
|
||||
Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and
|
||||
distribute verbatim copies of this license document, but changing it is not
|
||||
allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to
|
||||
share and change it. By contrast, the GNU General Public License is
|
||||
intended to guarantee your freedom to share and change free software--to
|
||||
make sure the software is free for all its users. This General Public
|
||||
License applies to most of the Free Software Foundation's software and to
|
||||
any other program whose authors commit to using it. (Some other Free
|
||||
Software Foundation software is covered by the GNU Lesser General Public
|
||||
License instead.) You can apply it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom
|
||||
to distribute copies of free software (and charge for this service if you
|
||||
wish), that you receive source code or can get it if you want it, that you
|
||||
can change the software or use pieces of it in new free programs; and that
|
||||
you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to
|
||||
deny you these rights or to ask you to surrender the rights. These
|
||||
restrictions translate to certain responsibilities for you if you distribute
|
||||
copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or
|
||||
for a fee, you must give the recipients all the rights that you have. You
|
||||
must make sure that they, too, receive or can get the source code. And you
|
||||
must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If
|
||||
the software is modified by someone else and passed on, we want its
|
||||
recipients to know that what they have is not the original, so that any
|
||||
problems introduced by others will not reflect on the original authors'
|
||||
reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that redistributors of a free program will
|
||||
individually obtain patent licenses, in effect making the program
|
||||
proprietary. To prevent this, we have made it clear that any patent must be
|
||||
licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the
|
||||
terms of this General Public License. The "Program", below, refers to
|
||||
any such program or work, and a "work based on the Program" means either
|
||||
the Program or any derivative work under copyright law: that is to say, a
|
||||
work containing the Program or a portion of it, either verbatim or with
|
||||
modifications and/or translated into another language. (Hereinafter,
|
||||
translation is included without limitation in the term "modification".)
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of running
|
||||
the Program is not restricted, and the output from the Program is covered
|
||||
only if its contents constitute a work based on the Program (independent
|
||||
of having been made by running the Program). Whether that is true depends
|
||||
on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source code
|
||||
as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this
|
||||
License and to the absence of any warranty; and give any other recipients
|
||||
of the Program a copy of this License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you
|
||||
may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of it,
|
||||
thus forming a work based on the Program, and copy and distribute such
|
||||
modifications or work under the terms of Section 1 above, provided that
|
||||
you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in whole
|
||||
or in part contains or is derived from the Program or any part
|
||||
thereof, to be licensed as a whole at no charge to all third parties
|
||||
under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively when
|
||||
run, you must cause it, when started running for such interactive use
|
||||
in the most ordinary way, to print or display an announcement
|
||||
including an appropriate copyright notice and a notice that there is
|
||||
no warranty (or else, saying that you provide a warranty) and that
|
||||
users may redistribute the program under these conditions, and telling
|
||||
the user how to view a copy of this License. (Exception: if the
|
||||
Program itself is interactive but does not normally print such an
|
||||
announcement, your work based on the Program is not required to print
|
||||
an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program, and
|
||||
can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based on
|
||||
the Program, the distribution of the whole must be on the terms of this
|
||||
License, whose permissions for other licensees extend to the entire
|
||||
whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of a
|
||||
storage or distribution medium does not bring the other work under the
|
||||
scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it, under
|
||||
Section 2) in object code or executable form under the terms of Sections
|
||||
1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2
|
||||
above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three years, to
|
||||
give any third party, for a charge no more than your cost of
|
||||
physically performing source distribution, a complete machine-readable
|
||||
copy of the corresponding source code, to be distributed under the
|
||||
terms of Sections 1 and 2 above on a medium customarily used for
|
||||
software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer to
|
||||
distribute corresponding source code. (This alternative is allowed
|
||||
only for noncommercial distribution and only if you received the
|
||||
program in object code or executable form with such an offer, in
|
||||
accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source code
|
||||
means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to control
|
||||
compilation and installation of the executable. However, as a special
|
||||
exception, the source code distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on which
|
||||
the executable runs, unless that component itself accompanies the
|
||||
executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access
|
||||
to copy from a designated place, then offering equivalent access to copy
|
||||
the source code from the same place counts as distribution of the source
|
||||
code, even though third parties are not compelled to copy the source
|
||||
along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program except as
|
||||
expressly provided under this License. Any attempt otherwise to copy,
|
||||
modify, sublicense or distribute the Program is void, and will
|
||||
automatically terminate your rights under this License. However, parties
|
||||
who have received copies, or rights, from you under this License will not
|
||||
have their licenses terminated so long as such parties remain in full
|
||||
compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not signed
|
||||
it. However, nothing else grants you permission to modify or distribute
|
||||
the Program or its derivative works. These actions are prohibited by law
|
||||
if you do not accept this License. Therefore, by modifying or
|
||||
distributing the Program (or any work based on the Program), you indicate
|
||||
your acceptance of this License to do so, and all its terms and
|
||||
conditions for copying, distributing or modifying the Program or works
|
||||
based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further restrictions
|
||||
on the recipients' exercise of the rights granted herein. You are not
|
||||
responsible for enforcing compliance by third parties to this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot distribute
|
||||
so as to satisfy simultaneously your obligations under this License and
|
||||
any other pertinent obligations, then as a consequence you may not
|
||||
distribute the Program at all. For example, if a patent license would
|
||||
not permit royalty-free redistribution of the Program by all those who
|
||||
receive copies directly or indirectly through you, then the only way you
|
||||
could satisfy both it and this License would be to refrain entirely from
|
||||
distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any such
|
||||
claims; this section has the sole purpose of protecting the integrity of
|
||||
the free software distribution system, which is implemented by public
|
||||
license practices. Many people have made generous contributions to the
|
||||
wide range of software distributed through that system in reliance on
|
||||
consistent application of that system; it is up to the author/donor to
|
||||
decide if he or she is willing to distribute software through any other
|
||||
system and a licensee cannot impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be
|
||||
a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original
|
||||
copyright holder who places the Program under this License may add an
|
||||
explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions of
|
||||
the General Public License from time to time. Such new versions will be
|
||||
similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free
|
||||
Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free programs
|
||||
whose distribution conditions are different, write to the author to ask
|
||||
for permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make
|
||||
exceptions for this. Our decision will be guided by the two goals of
|
||||
preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
|
||||
YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
|
||||
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||
THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
|
||||
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
@@ -0,0 +1,58 @@
|
||||
= Net::LDAP Changelog
|
||||
|
||||
== Net::LDAP 0.0.4: August 15, 2006
|
||||
* Undeprecated Net::LDAP#modify. Thanks to Justin Forder for
|
||||
providing the rationale for this.
|
||||
* Added a much-expanded set of special characters to the parser
|
||||
for RFC-2254 filters. Thanks to Andre Nathan.
|
||||
* Changed Net::LDAP#search so you can pass it a filter in string form.
|
||||
The conversion to a Net::LDAP::Filter now happens automatically.
|
||||
* Implemented Net::LDAP#bind_as (preliminary and subject to change).
|
||||
Thanks for Simon Claret for valuable suggestions and for helping test.
|
||||
* Fixed bug in Net::LDAP#open that was preventing #open from being
|
||||
called more than one on a given Net::LDAP object.
|
||||
|
||||
== Net::LDAP 0.0.3: July 26, 2006
|
||||
* Added simple TLS encryption.
|
||||
Thanks to Garett Shulman for suggestions and for helping test.
|
||||
|
||||
== Net::LDAP 0.0.2: July 12, 2006
|
||||
* Fixed malformation in distro tarball and gem.
|
||||
* Improved documentation.
|
||||
* Supported "paged search control."
|
||||
* Added a range of API improvements.
|
||||
* Thanks to Andre Nathan, andre@digirati.com.br, for valuable
|
||||
suggestions.
|
||||
* Added support for LE and GE search filters.
|
||||
* Added support for Search referrals.
|
||||
* Fixed a regression with openldap 2.2.x and higher caused
|
||||
by the introduction of RFC-2696 controls. Thanks to Andre
|
||||
Nathan for reporting the problem.
|
||||
* Added support for RFC-2254 filter syntax.
|
||||
|
||||
== Net::LDAP 0.0.1: May 1, 2006
|
||||
* Initial release.
|
||||
* Client functionality is near-complete, although the APIs
|
||||
are not guaranteed and may change depending on feedback
|
||||
from the community.
|
||||
* We're internally working on a Ruby-based implementation
|
||||
of a full-featured, production-quality LDAP server,
|
||||
which will leverage the underlying LDAP and BER functionality
|
||||
in Net::LDAP.
|
||||
* Please tell us if you would be interested in seeing a public
|
||||
release of the LDAP server.
|
||||
* Grateful acknowledgement to Austin Ziegler, who reviewed
|
||||
this code and provided the release framework, including
|
||||
minitar.
|
||||
|
||||
#--
|
||||
# Net::LDAP for Ruby.
|
||||
# http://rubyforge.org/projects/net-ldap/
|
||||
# Copyright (C) 2006 by Francis Cianfrocca
|
||||
#
|
||||
# Available under the same terms as Ruby. See LICENCE in the main
|
||||
# distribution for full licensing information.
|
||||
#
|
||||
# $Id: ChangeLog,v 1.17.2.4 2005/09/09 12:36:42 austin Exp $
|
||||
#++
|
||||
# vim: sts=2 sw=2 ts=4 et ai tw=77
|
||||
@@ -0,0 +1,55 @@
|
||||
Net::LDAP is copyrighted free software by Francis Cianfrocca
|
||||
<garbagecat10@gmail.com>. You can redistribute it and/or modify it under either
|
||||
the terms of the GPL (see the file COPYING), or the conditions below:
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
software without restriction, provided that you duplicate all of the
|
||||
original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may modify your copy of the software in any way, provided that you do
|
||||
at least ONE of the following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or by allowing the author to include your
|
||||
modifications in the software.
|
||||
|
||||
b) use the modified software only within your corporation or
|
||||
organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict with
|
||||
standard executables, which must also be provided.
|
||||
|
||||
d) make other distribution arrangements with the author.
|
||||
|
||||
3. You may distribute the software in object code or executable form,
|
||||
provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute the executables and library files of the software, together
|
||||
with instructions (in the manual page or equivalent) on where to get
|
||||
the original distribution.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of the
|
||||
software.
|
||||
|
||||
c) give non-standard executables non-standard names, with instructions on
|
||||
where to get the original software distribution.
|
||||
|
||||
d) make other distribution arrangements with the author.
|
||||
|
||||
4. You may modify and include the part of the software into any other
|
||||
software (possibly commercial). But some files in the distribution are
|
||||
not written by the author, so that they are not under this terms.
|
||||
|
||||
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
||||
files under the ./missing directory. See each file for the copying
|
||||
condition.
|
||||
|
||||
5. The scripts and library files supplied as input to or produced as output
|
||||
from the software do not automatically fall under the copyright of the
|
||||
software, but belong to whomever generated them, and may be sold
|
||||
commercially, and may be aggregated with this software.
|
||||
|
||||
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
@@ -0,0 +1,32 @@
|
||||
= Net::LDAP for Ruby
|
||||
Net::LDAP is an LDAP support library written in pure Ruby. It supports all
|
||||
LDAP client features, and a subset of server features as well.
|
||||
|
||||
Homepage:: http://rubyforge.org/projects/net-ldap/
|
||||
Copyright:: (C) 2006 by Francis Cianfrocca
|
||||
|
||||
Original developer: Francis Cianfrocca
|
||||
Contributions by Austin Ziegler gratefully acknowledged.
|
||||
|
||||
== LICENCE NOTES
|
||||
Please read the file LICENCE for licensing restrictions on this library. In
|
||||
the simplest terms, this library is available under the same terms as Ruby
|
||||
itself.
|
||||
|
||||
== Requirements
|
||||
Net::LDAP requires Ruby 1.8.2 or better.
|
||||
|
||||
== Documentation
|
||||
See Net::LDAP for documentation and usage samples.
|
||||
|
||||
#--
|
||||
# Net::LDAP for Ruby.
|
||||
# http://rubyforge.org/projects/net-ldap/
|
||||
# Copyright (C) 2006 by Francis Cianfrocca
|
||||
#
|
||||
# Available under the same terms as Ruby. See LICENCE in the main
|
||||
# distribution for full licensing information.
|
||||
#
|
||||
# $Id: README 141 2006-07-12 10:37:37Z blackhedd $
|
||||
#++
|
||||
# vim: sts=2 sw=2 ts=4 et ai tw=77
|
||||
@@ -0,0 +1,294 @@
|
||||
# $Id: ber.rb 142 2006-07-26 12:20:33Z blackhedd $
|
||||
#
|
||||
# NET::BER
|
||||
# Mixes ASN.1/BER convenience methods into several standard classes.
|
||||
# Also provides BER parsing functionality.
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
module Net
|
||||
|
||||
module BER
|
||||
|
||||
class BerError < Exception; end
|
||||
|
||||
|
||||
# This module is for mixing into IO and IO-like objects.
|
||||
module BERParser
|
||||
|
||||
# The order of these follows the class-codes in BER.
|
||||
# Maybe this should have been a hash.
|
||||
TagClasses = [:universal, :application, :context_specific, :private]
|
||||
|
||||
BuiltinSyntax = {
|
||||
:universal => {
|
||||
:primitive => {
|
||||
1 => :boolean,
|
||||
2 => :integer,
|
||||
4 => :string,
|
||||
10 => :integer,
|
||||
},
|
||||
:constructed => {
|
||||
16 => :array,
|
||||
17 => :array
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# read_ber
|
||||
# TODO: clean this up so it works properly with partial
|
||||
# packets coming from streams that don't block when
|
||||
# we ask for more data (like StringIOs). At it is,
|
||||
# this can throw TypeErrors and other nasties.
|
||||
#
|
||||
def read_ber syntax=nil
|
||||
return nil if eof?
|
||||
|
||||
id = getc # don't trash this value, we'll use it later
|
||||
tag = id & 31
|
||||
tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
|
||||
tagclass = TagClasses[ id >> 6 ]
|
||||
encoding = (id & 0x20 != 0) ? :constructed : :primitive
|
||||
|
||||
n = getc
|
||||
lengthlength,contentlength = if n <= 127
|
||||
[1,n]
|
||||
else
|
||||
j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
|
||||
[1 + (n & 127), j]
|
||||
end
|
||||
|
||||
newobj = read contentlength
|
||||
|
||||
objtype = nil
|
||||
[syntax, BuiltinSyntax].each {|syn|
|
||||
if syn && (ot = syn[tagclass]) && (ot = ot[encoding]) && ot[tag]
|
||||
objtype = ot[tag]
|
||||
break
|
||||
end
|
||||
}
|
||||
|
||||
obj = case objtype
|
||||
when :boolean
|
||||
newobj != "\000"
|
||||
when :string
|
||||
(newobj || "").dup
|
||||
when :integer
|
||||
j = 0
|
||||
newobj.each_byte {|b| j = (j << 8) + b}
|
||||
j
|
||||
when :array
|
||||
seq = []
|
||||
sio = StringIO.new( newobj || "" )
|
||||
# Interpret the subobject, but note how the loop
|
||||
# is built: nil ends the loop, but false (a valid
|
||||
# BER value) does not!
|
||||
while (e = sio.read_ber(syntax)) != nil
|
||||
seq << e
|
||||
end
|
||||
seq
|
||||
else
|
||||
raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
|
||||
end
|
||||
|
||||
# Add the identifier bits into the object if it's a String or an Array.
|
||||
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
|
||||
obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
|
||||
obj
|
||||
|
||||
end
|
||||
|
||||
end # module BERParser
|
||||
end # module BER
|
||||
|
||||
end # module Net
|
||||
|
||||
|
||||
class IO
|
||||
include Net::BER::BERParser
|
||||
end
|
||||
|
||||
require "stringio"
|
||||
class StringIO
|
||||
include Net::BER::BERParser
|
||||
end
|
||||
|
||||
begin
|
||||
require 'openssl'
|
||||
class OpenSSL::SSL::SSLSocket
|
||||
include Net::BER::BERParser
|
||||
end
|
||||
rescue LoadError
|
||||
# Ignore LoadError.
|
||||
# DON'T ignore NameError, which means the SSLSocket class
|
||||
# is somehow unavailable on this implementation of Ruby's openssl.
|
||||
# This may be WRONG, however, because we don't yet know how Ruby's
|
||||
# openssl behaves on machines with no OpenSSL library. I suppose
|
||||
# it's possible they do not fail to require 'openssl' but do not
|
||||
# create the classes. So this code is provisional.
|
||||
# Also, you might think that OpenSSL::SSL::SSLSocket inherits from
|
||||
# IO so we'd pick it up above. But you'd be wrong.
|
||||
end
|
||||
|
||||
class String
|
||||
def read_ber syntax=nil
|
||||
StringIO.new(self).read_ber(syntax)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------
|
||||
|
||||
|
||||
class FalseClass
|
||||
#
|
||||
# to_ber
|
||||
#
|
||||
def to_ber
|
||||
"\001\001\000"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TrueClass
|
||||
#
|
||||
# to_ber
|
||||
#
|
||||
def to_ber
|
||||
"\001\001\001"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Fixnum
|
||||
#
|
||||
# to_ber
|
||||
#
|
||||
def to_ber
|
||||
i = [self].pack('w')
|
||||
[2, i.length].pack("CC") + i
|
||||
end
|
||||
|
||||
#
|
||||
# to_ber_enumerated
|
||||
#
|
||||
def to_ber_enumerated
|
||||
i = [self].pack('w')
|
||||
[10, i.length].pack("CC") + i
|
||||
end
|
||||
|
||||
#
|
||||
# to_ber_length_encoding
|
||||
#
|
||||
def to_ber_length_encoding
|
||||
if self <= 127
|
||||
[self].pack('C')
|
||||
else
|
||||
i = [self].pack('N').sub(/^[\0]+/,"")
|
||||
[0x80 + i.length].pack('C') + i
|
||||
end
|
||||
end
|
||||
|
||||
end # class Fixnum
|
||||
|
||||
|
||||
class Bignum
|
||||
|
||||
def to_ber
|
||||
i = [self].pack('w')
|
||||
i.length > 126 and raise Net::BER::BerError.new( "range error in bignum" )
|
||||
[2, i.length].pack("CC") + i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
class String
|
||||
#
|
||||
# to_ber
|
||||
# A universal octet-string is tag number 4,
|
||||
# but others are possible depending on the context, so we
|
||||
# let the caller give us one.
|
||||
# The preferred way to do this in user code is via to_ber_application_sring
|
||||
# and to_ber_contextspecific.
|
||||
#
|
||||
def to_ber code = 4
|
||||
[code].pack('C') + length.to_ber_length_encoding + self
|
||||
end
|
||||
|
||||
#
|
||||
# to_ber_application_string
|
||||
#
|
||||
def to_ber_application_string code
|
||||
to_ber( 0x40 + code )
|
||||
end
|
||||
|
||||
#
|
||||
# to_ber_contextspecific
|
||||
#
|
||||
def to_ber_contextspecific code
|
||||
to_ber( 0x80 + code )
|
||||
end
|
||||
|
||||
end # class String
|
||||
|
||||
|
||||
|
||||
class Array
|
||||
#
|
||||
# to_ber_appsequence
|
||||
# An application-specific sequence usually gets assigned
|
||||
# a tag that is meaningful to the particular protocol being used.
|
||||
# This is different from the universal sequence, which usually
|
||||
# gets a tag value of 16.
|
||||
# Now here's an interesting thing: We're adding the X.690
|
||||
# "application constructed" code at the top of the tag byte (0x60),
|
||||
# but some clients, notably ldapsearch, send "context-specific
|
||||
# constructed" (0xA0). The latter would appear to violate RFC-1777,
|
||||
# but what do I know? We may need to change this.
|
||||
#
|
||||
|
||||
def to_ber id = 0; to_ber_seq_internal( 0x30 + id ); end
|
||||
def to_ber_set id = 0; to_ber_seq_internal( 0x31 + id ); end
|
||||
def to_ber_sequence id = 0; to_ber_seq_internal( 0x30 + id ); end
|
||||
def to_ber_appsequence id = 0; to_ber_seq_internal( 0x60 + id ); end
|
||||
def to_ber_contextspecific id = 0; to_ber_seq_internal( 0xA0 + id ); end
|
||||
|
||||
private
|
||||
def to_ber_seq_internal code
|
||||
s = self.to_s
|
||||
[code].pack('C') + s.length.to_ber_length_encoding + s
|
||||
end
|
||||
|
||||
end # class Array
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,108 @@
|
||||
# $Id: dataset.rb 78 2006-04-26 02:57:34Z blackhedd $
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
module Net
|
||||
class LDAP
|
||||
|
||||
class Dataset < Hash
|
||||
|
||||
attr_reader :comments
|
||||
|
||||
|
||||
def Dataset::read_ldif io
|
||||
ds = Dataset.new
|
||||
|
||||
line = io.gets && chomp
|
||||
dn = nil
|
||||
|
||||
while line
|
||||
io.gets and chomp
|
||||
if $_ =~ /^[\s]+/
|
||||
line << " " << $'
|
||||
else
|
||||
nextline = $_
|
||||
|
||||
if line =~ /^\#/
|
||||
ds.comments << line
|
||||
elsif line =~ /^dn:[\s]*/i
|
||||
dn = $'
|
||||
ds[dn] = Hash.new {|k,v| k[v] = []}
|
||||
elsif line.length == 0
|
||||
dn = nil
|
||||
elsif line =~ /^([^:]+):([\:]?)[\s]*/
|
||||
# $1 is the attribute name
|
||||
# $2 is a colon iff the attr-value is base-64 encoded
|
||||
# $' is the attr-value
|
||||
# Avoid the Base64 class because not all Ruby versions have it.
|
||||
attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
|
||||
ds[dn][$1.downcase.intern] << attrvalue
|
||||
end
|
||||
|
||||
line = nextline
|
||||
end
|
||||
end
|
||||
|
||||
ds
|
||||
end
|
||||
|
||||
|
||||
def initialize
|
||||
@comments = []
|
||||
end
|
||||
|
||||
|
||||
def to_ldif
|
||||
ary = []
|
||||
ary += (@comments || [])
|
||||
|
||||
keys.sort.each {|dn|
|
||||
ary << "dn: #{dn}"
|
||||
|
||||
self[dn].keys.map {|sym| sym.to_s}.sort.each {|attr|
|
||||
self[dn][attr.intern].each {|val|
|
||||
ary << "#{attr}: #{val}"
|
||||
}
|
||||
}
|
||||
|
||||
ary << ""
|
||||
}
|
||||
|
||||
block_given? and ary.each {|line| yield line}
|
||||
|
||||
ary
|
||||
end
|
||||
|
||||
|
||||
end # Dataset
|
||||
|
||||
end # LDAP
|
||||
end # Net
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
# $Id: entry.rb 123 2006-05-18 03:52:38Z blackhedd $
|
||||
#
|
||||
# LDAP Entry (search-result) support classes
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
module Net
|
||||
class LDAP
|
||||
|
||||
|
||||
# Objects of this class represent individual entries in an LDAP
|
||||
# directory. User code generally does not instantiate this class.
|
||||
# Net::LDAP#search provides objects of this class to user code,
|
||||
# either as block parameters or as return values.
|
||||
#
|
||||
# In LDAP-land, an "entry" is a collection of attributes that are
|
||||
# uniquely and globally identified by a DN ("Distinguished Name").
|
||||
# Attributes are identified by short, descriptive words or phrases.
|
||||
# Although a directory is
|
||||
# free to implement any attribute name, most of them follow rigorous
|
||||
# standards so that the range of commonly-encountered attribute
|
||||
# names is not large.
|
||||
#
|
||||
# An attribute name is case-insensitive. Most directories also
|
||||
# restrict the range of characters allowed in attribute names.
|
||||
# To simplify handling attribute names, Net::LDAP::Entry
|
||||
# internally converts them to a standard format. Therefore, the
|
||||
# methods which take attribute names can take Strings or Symbols,
|
||||
# and work correctly regardless of case or capitalization.
|
||||
#
|
||||
# An attribute consists of zero or more data items called
|
||||
# <i>values.</i> An entry is the combination of a unique DN, a set of attribute
|
||||
# names, and a (possibly-empty) array of values for each attribute.
|
||||
#
|
||||
# Class Net::LDAP::Entry provides convenience methods for dealing
|
||||
# with LDAP entries.
|
||||
# In addition to the methods documented below, you may access individual
|
||||
# attributes of an entry simply by giving the attribute name as
|
||||
# the name of a method call. For example:
|
||||
# ldap.search( ... ) do |entry|
|
||||
# puts "Common name: #{entry.cn}"
|
||||
# puts "Email addresses:"
|
||||
# entry.mail.each {|ma| puts ma}
|
||||
# end
|
||||
# If you use this technique to access an attribute that is not present
|
||||
# in a particular Entry object, a NoMethodError exception will be raised.
|
||||
#
|
||||
#--
|
||||
# Ugly problem to fix someday: We key off the internal hash with
|
||||
# a canonical form of the attribute name: convert to a string,
|
||||
# downcase, then take the symbol. Unfortunately we do this in
|
||||
# at least three places. Should do it in ONE place.
|
||||
class Entry
|
||||
|
||||
# This constructor is not generally called by user code.
|
||||
def initialize dn = nil # :nodoc:
|
||||
@myhash = Hash.new {|k,v| k[v] = [] }
|
||||
@myhash[:dn] = [dn]
|
||||
end
|
||||
|
||||
|
||||
def []= name, value # :nodoc:
|
||||
sym = name.to_s.downcase.intern
|
||||
@myhash[sym] = value
|
||||
end
|
||||
|
||||
|
||||
#--
|
||||
# We have to deal with this one as we do with []=
|
||||
# because this one and not the other one gets called
|
||||
# in formulations like entry["CN"] << cn.
|
||||
#
|
||||
def [] name # :nodoc:
|
||||
name = name.to_s.downcase.intern unless name.is_a?(Symbol)
|
||||
@myhash[name]
|
||||
end
|
||||
|
||||
# Returns the dn of the Entry as a String.
|
||||
def dn
|
||||
self[:dn][0]
|
||||
end
|
||||
|
||||
# Returns an array of the attribute names present in the Entry.
|
||||
def attribute_names
|
||||
@myhash.keys
|
||||
end
|
||||
|
||||
# Accesses each of the attributes present in the Entry.
|
||||
# Calls a user-supplied block with each attribute in turn,
|
||||
# passing two arguments to the block: a Symbol giving
|
||||
# the name of the attribute, and a (possibly empty)
|
||||
# Array of data values.
|
||||
#
|
||||
def each
|
||||
if block_given?
|
||||
attribute_names.each {|a|
|
||||
attr_name,values = a,self[a]
|
||||
yield attr_name, values
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :each_attribute, :each
|
||||
|
||||
|
||||
#--
|
||||
# Convenience method to convert unknown method names
|
||||
# to attribute references. Of course the method name
|
||||
# comes to us as a symbol, so let's save a little time
|
||||
# and not bother with the to_s.downcase two-step.
|
||||
# Of course that means that a method name like mAIL
|
||||
# won't work, but we shouldn't be encouraging that
|
||||
# kind of bad behavior in the first place.
|
||||
# Maybe we should thow something if the caller sends
|
||||
# arguments or a block...
|
||||
#
|
||||
def method_missing *args, &block # :nodoc:
|
||||
s = args[0].to_s.downcase.intern
|
||||
if attribute_names.include?(s)
|
||||
self[s]
|
||||
elsif s.to_s[-1] == 61 and s.to_s.length > 1
|
||||
value = args[1] or raise RuntimeError.new( "unable to set value" )
|
||||
value = [value] unless value.is_a?(Array)
|
||||
name = s.to_s[0..-2].intern
|
||||
self[name] = value
|
||||
else
|
||||
raise NoMethodError.new( "undefined method '#{s}'" )
|
||||
end
|
||||
end
|
||||
|
||||
def write
|
||||
end
|
||||
|
||||
end # class Entry
|
||||
|
||||
|
||||
end # class LDAP
|
||||
end # module Net
|
||||
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
# $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
module Net
|
||||
class LDAP
|
||||
|
||||
|
||||
# Class Net::LDAP::Filter is used to constrain
|
||||
# LDAP searches. An object of this class is
|
||||
# passed to Net::LDAP#search in the parameter :filter.
|
||||
#
|
||||
# Net::LDAP::Filter supports the complete set of search filters
|
||||
# available in LDAP, including conjunction, disjunction and negation
|
||||
# (AND, OR, and NOT). This class supplants the (infamous) RFC-2254
|
||||
# standard notation for specifying LDAP search filters.
|
||||
#
|
||||
# Here's how to code the familiar "objectclass is present" filter:
|
||||
# f = Net::LDAP::Filter.pres( "objectclass" )
|
||||
# The object returned by this code can be passed directly to
|
||||
# the <tt>:filter</tt> parameter of Net::LDAP#search.
|
||||
#
|
||||
# See the individual class and instance methods below for more examples.
|
||||
#
|
||||
class Filter
|
||||
|
||||
def initialize op, a, b
|
||||
@op = op
|
||||
@left = a
|
||||
@right = b
|
||||
end
|
||||
|
||||
# #eq creates a filter object indicating that the value of
|
||||
# a paticular attribute must be either <i>present</i> or must
|
||||
# match a particular string.
|
||||
#
|
||||
# To specify that an attribute is "present" means that only
|
||||
# directory entries which contain a value for the particular
|
||||
# attribute will be selected by the filter. This is useful
|
||||
# in case of optional attributes such as <tt>mail.</tt>
|
||||
# Presence is indicated by giving the value "*" in the second
|
||||
# parameter to #eq. This example selects only entries that have
|
||||
# one or more values for <tt>sAMAccountName:</tt>
|
||||
# f = Net::LDAP::Filter.eq( "sAMAccountName", "*" )
|
||||
#
|
||||
# To match a particular range of values, pass a string as the
|
||||
# second parameter to #eq. The string may contain one or more
|
||||
# "*" characters as wildcards: these match zero or more occurrences
|
||||
# of any character. Full regular-expressions are <i>not</i> supported
|
||||
# due to limitations in the underlying LDAP protocol.
|
||||
# This example selects any entry with a <tt>mail</tt> value containing
|
||||
# the substring "anderson":
|
||||
# f = Net::LDAP::Filter.eq( "mail", "*anderson*" )
|
||||
#--
|
||||
# Removed gt and lt. They ain't in the standard!
|
||||
#
|
||||
def Filter::eq attribute, value; Filter.new :eq, attribute, value; end
|
||||
def Filter::ne attribute, value; Filter.new :ne, attribute, value; end
|
||||
#def Filter::gt attribute, value; Filter.new :gt, attribute, value; end
|
||||
#def Filter::lt attribute, value; Filter.new :lt, attribute, value; end
|
||||
def Filter::ge attribute, value; Filter.new :ge, attribute, value; end
|
||||
def Filter::le attribute, value; Filter.new :le, attribute, value; end
|
||||
|
||||
# #pres( attribute ) is a synonym for #eq( attribute, "*" )
|
||||
#
|
||||
def Filter::pres attribute; Filter.eq attribute, "*"; end
|
||||
|
||||
# operator & ("AND") is used to conjoin two or more filters.
|
||||
# This expression will select only entries that have an <tt>objectclass</tt>
|
||||
# attribute AND have a <tt>mail</tt> attribute that begins with "George":
|
||||
# f = Net::LDAP::Filter.pres( "objectclass" ) & Net::LDAP::Filter.eq( "mail", "George*" )
|
||||
#
|
||||
def & filter; Filter.new :and, self, filter; end
|
||||
|
||||
# operator | ("OR") is used to disjoin two or more filters.
|
||||
# This expression will select entries that have either an <tt>objectclass</tt>
|
||||
# attribute OR a <tt>mail</tt> attribute that begins with "George":
|
||||
# f = Net::LDAP::Filter.pres( "objectclass" ) | Net::LDAP::Filter.eq( "mail", "George*" )
|
||||
#
|
||||
def | filter; Filter.new :or, self, filter; end
|
||||
|
||||
|
||||
#
|
||||
# operator ~ ("NOT") is used to negate a filter.
|
||||
# This expression will select only entries that <i>do not</i> have an <tt>objectclass</tt>
|
||||
# attribute:
|
||||
# f = ~ Net::LDAP::Filter.pres( "objectclass" )
|
||||
#
|
||||
#--
|
||||
# This operator can't be !, evidently. Try it.
|
||||
# Removed GT and LT. They're not in the RFC.
|
||||
def ~@; Filter.new :not, self, nil; end
|
||||
|
||||
|
||||
def to_s
|
||||
case @op
|
||||
when :ne
|
||||
"(!(#{@left}=#{@right}))"
|
||||
when :eq
|
||||
"(#{@left}=#{@right})"
|
||||
#when :gt
|
||||
# "#{@left}>#{@right}"
|
||||
#when :lt
|
||||
# "#{@left}<#{@right}"
|
||||
when :ge
|
||||
"#{@left}>=#{@right}"
|
||||
when :le
|
||||
"#{@left}<=#{@right}"
|
||||
when :and
|
||||
"(&(#{@left})(#{@right}))"
|
||||
when :or
|
||||
"(|(#{@left})(#{@right}))"
|
||||
when :not
|
||||
"(!(#{@left}))"
|
||||
else
|
||||
raise "invalid or unsupported operator in LDAP Filter"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#--
|
||||
# to_ber
|
||||
# Filter ::=
|
||||
# CHOICE {
|
||||
# and [0] SET OF Filter,
|
||||
# or [1] SET OF Filter,
|
||||
# not [2] Filter,
|
||||
# equalityMatch [3] AttributeValueAssertion,
|
||||
# substrings [4] SubstringFilter,
|
||||
# greaterOrEqual [5] AttributeValueAssertion,
|
||||
# lessOrEqual [6] AttributeValueAssertion,
|
||||
# present [7] AttributeType,
|
||||
# approxMatch [8] AttributeValueAssertion
|
||||
# }
|
||||
#
|
||||
# SubstringFilter
|
||||
# SEQUENCE {
|
||||
# type AttributeType,
|
||||
# SEQUENCE OF CHOICE {
|
||||
# initial [0] LDAPString,
|
||||
# any [1] LDAPString,
|
||||
# final [2] LDAPString
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Parsing substrings is a little tricky.
|
||||
# We use the split method to break a string into substrings
|
||||
# delimited by the * (star) character. But we also need
|
||||
# to know whether there is a star at the head and tail
|
||||
# of the string. A Ruby particularity comes into play here:
|
||||
# if you split on * and the first character of the string is
|
||||
# a star, then split will return an array whose first element
|
||||
# is an _empty_ string. But if the _last_ character of the
|
||||
# string is star, then split will return an array that does
|
||||
# _not_ add an empty string at the end. So we have to deal
|
||||
# with all that specifically.
|
||||
#
|
||||
def to_ber
|
||||
case @op
|
||||
when :eq
|
||||
if @right == "*" # present
|
||||
@left.to_s.to_ber_contextspecific 7
|
||||
elsif @right =~ /[\*]/ #substring
|
||||
ary = @right.split( /[\*]+/ )
|
||||
final_star = @right =~ /[\*]$/
|
||||
initial_star = ary.first == "" and ary.shift
|
||||
|
||||
seq = []
|
||||
unless initial_star
|
||||
seq << ary.shift.to_ber_contextspecific(0)
|
||||
end
|
||||
n_any_strings = ary.length - (final_star ? 0 : 1)
|
||||
#p n_any_strings
|
||||
n_any_strings.times {
|
||||
seq << ary.shift.to_ber_contextspecific(1)
|
||||
}
|
||||
unless final_star
|
||||
seq << ary.shift.to_ber_contextspecific(2)
|
||||
end
|
||||
[@left.to_s.to_ber, seq.to_ber].to_ber_contextspecific 4
|
||||
else #equality
|
||||
[@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 3
|
||||
end
|
||||
when :ge
|
||||
[@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 5
|
||||
when :le
|
||||
[@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 6
|
||||
when :and
|
||||
ary = [@left.coalesce(:and), @right.coalesce(:and)].flatten
|
||||
ary.map {|a| a.to_ber}.to_ber_contextspecific( 0 )
|
||||
when :or
|
||||
ary = [@left.coalesce(:or), @right.coalesce(:or)].flatten
|
||||
ary.map {|a| a.to_ber}.to_ber_contextspecific( 1 )
|
||||
when :not
|
||||
[@left.to_ber].to_ber_contextspecific 2
|
||||
else
|
||||
# ERROR, we'll return objectclass=* to keep things from blowing up,
|
||||
# but that ain't a good answer and we need to kick out an error of some kind.
|
||||
raise "unimplemented search filter"
|
||||
end
|
||||
end
|
||||
|
||||
#--
|
||||
# coalesce
|
||||
# This is a private helper method for dealing with chains of ANDs and ORs
|
||||
# that are longer than two. If BOTH of our branches are of the specified
|
||||
# type of joining operator, then return both of them as an array (calling
|
||||
# coalesce recursively). If they're not, then return an array consisting
|
||||
# only of self.
|
||||
#
|
||||
def coalesce operator
|
||||
if @op == operator
|
||||
[@left.coalesce( operator ), @right.coalesce( operator )]
|
||||
else
|
||||
[self]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#--
|
||||
# We get a Ruby object which comes from parsing an RFC-1777 "Filter"
|
||||
# object. Convert it to a Net::LDAP::Filter.
|
||||
# TODO, we're hardcoding the RFC-1777 BER-encodings of the various
|
||||
# filter types. Could pull them out into a constant.
|
||||
#
|
||||
def Filter::parse_ldap_filter obj
|
||||
case obj.ber_identifier
|
||||
when 0x87 # present. context-specific primitive 7.
|
||||
Filter.eq( obj.to_s, "*" )
|
||||
when 0xa3 # equalityMatch. context-specific constructed 3.
|
||||
Filter.eq( obj[0], obj[1] )
|
||||
else
|
||||
raise LdapError.new( "unknown ldap search-filter type: #{obj.ber_identifier}" )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#--
|
||||
# We got a hash of attribute values.
|
||||
# Do we match the attributes?
|
||||
# Return T/F, and call match recursively as necessary.
|
||||
def match entry
|
||||
case @op
|
||||
when :eq
|
||||
if @right == "*"
|
||||
l = entry[@left] and l.length > 0
|
||||
else
|
||||
l = entry[@left] and l = l.to_a and l.index(@right)
|
||||
end
|
||||
else
|
||||
raise LdapError.new( "unknown filter type in match: #{@op}" )
|
||||
end
|
||||
end
|
||||
|
||||
# Converts an LDAP filter-string (in the prefix syntax specified in RFC-2254)
|
||||
# to a Net::LDAP::Filter.
|
||||
def self.construct ldap_filter_string
|
||||
FilterParser.new(ldap_filter_string).filter
|
||||
end
|
||||
|
||||
# Synonym for #construct.
|
||||
# to a Net::LDAP::Filter.
|
||||
def self.from_rfc2254 ldap_filter_string
|
||||
construct ldap_filter_string
|
||||
end
|
||||
|
||||
end # class Net::LDAP::Filter
|
||||
|
||||
|
||||
|
||||
class FilterParser #:nodoc:
|
||||
|
||||
attr_reader :filter
|
||||
|
||||
def initialize str
|
||||
require 'strscan'
|
||||
@filter = parse( StringScanner.new( str )) or raise Net::LDAP::LdapError.new( "invalid filter syntax" )
|
||||
end
|
||||
|
||||
def parse scanner
|
||||
parse_filter_branch(scanner) or parse_paren_expression(scanner)
|
||||
end
|
||||
|
||||
def parse_paren_expression scanner
|
||||
if scanner.scan /\s*\(\s*/
|
||||
b = if scanner.scan /\s*\&\s*/
|
||||
a = nil
|
||||
branches = []
|
||||
while br = parse_paren_expression(scanner)
|
||||
branches << br
|
||||
end
|
||||
if branches.length >= 2
|
||||
a = branches.shift
|
||||
while branches.length > 0
|
||||
a = a & branches.shift
|
||||
end
|
||||
a
|
||||
end
|
||||
elsif scanner.scan /\s*\|\s*/
|
||||
# TODO: DRY!
|
||||
a = nil
|
||||
branches = []
|
||||
while br = parse_paren_expression(scanner)
|
||||
branches << br
|
||||
end
|
||||
if branches.length >= 2
|
||||
a = branches.shift
|
||||
while branches.length > 0
|
||||
a = a | branches.shift
|
||||
end
|
||||
a
|
||||
end
|
||||
elsif scanner.scan /\s*\!\s*/
|
||||
br = parse_paren_expression(scanner)
|
||||
if br
|
||||
~ br
|
||||
end
|
||||
else
|
||||
parse_filter_branch( scanner )
|
||||
end
|
||||
|
||||
if b and scanner.scan( /\s*\)\s*/ )
|
||||
b
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Added a greatly-augmented filter contributed by Andre Nathan
|
||||
# for detecting special characters in values. (15Aug06)
|
||||
def parse_filter_branch scanner
|
||||
scanner.scan /\s*/
|
||||
if token = scanner.scan( /[\w\-_]+/ )
|
||||
scanner.scan /\s*/
|
||||
if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ )
|
||||
scanner.scan /\s*/
|
||||
#if value = scanner.scan( /[\w\*\.]+/ ) (ORG)
|
||||
if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ )
|
||||
case op
|
||||
when "="
|
||||
Filter.eq( token, value )
|
||||
when "!="
|
||||
Filter.ne( token, value )
|
||||
when "<"
|
||||
Filter.lt( token, value )
|
||||
when "<="
|
||||
Filter.le( token, value )
|
||||
when ">"
|
||||
Filter.gt( token, value )
|
||||
when ">="
|
||||
Filter.ge( token, value )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end # class Net::LDAP::FilterParser
|
||||
|
||||
end # class Net::LDAP
|
||||
end # module Net
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
# $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $
|
||||
#
|
||||
# LDAP PDU support classes
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
|
||||
|
||||
module Net
|
||||
|
||||
|
||||
class LdapPduError < Exception; end
|
||||
|
||||
|
||||
class LdapPdu
|
||||
|
||||
BindResult = 1
|
||||
SearchReturnedData = 4
|
||||
SearchResult = 5
|
||||
ModifyResponse = 7
|
||||
AddResponse = 9
|
||||
DeleteResponse = 11
|
||||
ModifyRDNResponse = 13
|
||||
SearchResultReferral = 19
|
||||
|
||||
attr_reader :msg_id, :app_tag
|
||||
attr_reader :search_dn, :search_attributes, :search_entry
|
||||
attr_reader :search_referrals
|
||||
|
||||
#
|
||||
# initialize
|
||||
# An LDAP PDU always looks like a BerSequence with
|
||||
# at least two elements: an integer (message-id number), and
|
||||
# an application-specific sequence.
|
||||
# Some LDAPv3 packets also include an optional
|
||||
# third element, which is a sequence of "controls"
|
||||
# (See RFC 2251, section 4.1.12).
|
||||
# The application-specific tag in the sequence tells
|
||||
# us what kind of packet it is, and each kind has its
|
||||
# own format, defined in RFC-1777.
|
||||
# Observe that many clients (such as ldapsearch)
|
||||
# do not necessarily enforce the expected application
|
||||
# tags on received protocol packets. This implementation
|
||||
# does interpret the RFC strictly in this regard, and
|
||||
# it remains to be seen whether there are servers out
|
||||
# there that will not work well with our approach.
|
||||
#
|
||||
# Added a controls-processor to SearchResult.
|
||||
# Didn't add it everywhere because it just _feels_
|
||||
# like it will need to be refactored.
|
||||
#
|
||||
def initialize ber_object
|
||||
begin
|
||||
@msg_id = ber_object[0].to_i
|
||||
@app_tag = ber_object[1].ber_identifier - 0x60
|
||||
rescue
|
||||
# any error becomes a data-format error
|
||||
raise LdapPduError.new( "ldap-pdu format error" )
|
||||
end
|
||||
|
||||
case @app_tag
|
||||
when BindResult
|
||||
parse_ldap_result ber_object[1]
|
||||
when SearchReturnedData
|
||||
parse_search_return ber_object[1]
|
||||
when SearchResultReferral
|
||||
parse_search_referral ber_object[1]
|
||||
when SearchResult
|
||||
parse_ldap_result ber_object[1]
|
||||
parse_controls(ber_object[2]) if ber_object[2]
|
||||
when ModifyResponse
|
||||
parse_ldap_result ber_object[1]
|
||||
when AddResponse
|
||||
parse_ldap_result ber_object[1]
|
||||
when DeleteResponse
|
||||
parse_ldap_result ber_object[1]
|
||||
when ModifyRDNResponse
|
||||
parse_ldap_result ber_object[1]
|
||||
else
|
||||
raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" )
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# result_code
|
||||
# This returns an LDAP result code taken from the PDU,
|
||||
# but it will be nil if there wasn't a result code.
|
||||
# That can easily happen depending on the type of packet.
|
||||
#
|
||||
def result_code code = :resultCode
|
||||
@ldap_result and @ldap_result[code]
|
||||
end
|
||||
|
||||
# Return RFC-2251 Controls if any.
|
||||
# Messy. Does this functionality belong somewhere else?
|
||||
def result_controls
|
||||
@ldap_controls || []
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# parse_ldap_result
|
||||
#
|
||||
def parse_ldap_result sequence
|
||||
sequence.length >= 3 or raise LdapPduError
|
||||
@ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]}
|
||||
end
|
||||
private :parse_ldap_result
|
||||
|
||||
#
|
||||
# parse_search_return
|
||||
# Definition from RFC 1777 (we're handling application-4 here)
|
||||
#
|
||||
# Search Response ::=
|
||||
# CHOICE {
|
||||
# entry [APPLICATION 4] SEQUENCE {
|
||||
# objectName LDAPDN,
|
||||
# attributes SEQUENCE OF SEQUENCE {
|
||||
# AttributeType,
|
||||
# SET OF AttributeValue
|
||||
# }
|
||||
# },
|
||||
# resultCode [APPLICATION 5] LDAPResult
|
||||
# }
|
||||
#
|
||||
# We concoct a search response that is a hash of the returned attribute values.
|
||||
# NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES.
|
||||
# This is to make them more predictable for user programs, but it
|
||||
# may not be a good idea. Maybe this should be configurable.
|
||||
# ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes,
|
||||
# we also return @search_entry, which is an LDAP::Entry object.
|
||||
# If that works out well, then we'll remove the first two.
|
||||
#
|
||||
# Provisionally removed obsolete search_attributes and search_dn, 04May06.
|
||||
#
|
||||
def parse_search_return sequence
|
||||
sequence.length >= 2 or raise LdapPduError
|
||||
@search_entry = LDAP::Entry.new( sequence[0] )
|
||||
#@search_dn = sequence[0]
|
||||
#@search_attributes = {}
|
||||
sequence[1].each {|seq|
|
||||
@search_entry[seq[0]] = seq[1]
|
||||
#@search_attributes[seq[0].downcase.intern] = seq[1]
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# A search referral is a sequence of one or more LDAP URIs.
|
||||
# Any number of search-referral replies can be returned by the server, interspersed
|
||||
# with normal replies in any order.
|
||||
# Until I can think of a better way to do this, we'll return the referrals as an array.
|
||||
# It'll be up to higher-level handlers to expose something reasonable to the client.
|
||||
def parse_search_referral uris
|
||||
@search_referrals = uris
|
||||
end
|
||||
|
||||
|
||||
# Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting
|
||||
# of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL
|
||||
# Octet String. If only two fields are given, the second one may be
|
||||
# either criticality or data, since criticality has a default value.
|
||||
# Someday we may want to come back here and add support for some of
|
||||
# more-widely used controls. RFC-2696 is a good example.
|
||||
#
|
||||
def parse_controls sequence
|
||||
@ldap_controls = sequence.map do |control|
|
||||
o = OpenStruct.new
|
||||
o.oid,o.criticality,o.value = control[0],control[1],control[2]
|
||||
if o.criticality and o.criticality.is_a?(String)
|
||||
o.value = o.criticality
|
||||
o.criticality = false
|
||||
end
|
||||
o
|
||||
end
|
||||
end
|
||||
private :parse_controls
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end # module Net
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# $Id: psw.rb 73 2006-04-24 21:59:35Z blackhedd $
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
module Net
|
||||
class LDAP
|
||||
|
||||
|
||||
class Password
|
||||
class << self
|
||||
|
||||
# Generate a password-hash suitable for inclusion in an LDAP attribute.
|
||||
# Pass a hash type (currently supported: :md5 and :sha) and a plaintext
|
||||
# password. This function will return a hashed representation.
|
||||
# STUB: This is here to fulfill the requirements of an RFC, which one?
|
||||
# TODO, gotta do salted-sha and (maybe) salted-md5.
|
||||
# Should we provide sha1 as a synonym for sha1? I vote no because then
|
||||
# should you also provide ssha1 for symmetry?
|
||||
def generate( type, str )
|
||||
case type
|
||||
when :md5
|
||||
require 'md5'
|
||||
"{MD5}#{ [MD5.new( str.to_s ).digest].pack("m").chomp }"
|
||||
when :sha
|
||||
require 'sha1'
|
||||
"{SHA}#{ [SHA1.new( str.to_s ).digest].pack("m").chomp }"
|
||||
# when ssha
|
||||
else
|
||||
raise Net::LDAP::LdapError.new( "unsupported password-hash type (#{type})" )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end # class LDAP
|
||||
end # module Net
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# $Id: ldif.rb 78 2006-04-26 02:57:34Z blackhedd $
|
||||
#
|
||||
# Net::LDIF for Ruby
|
||||
#
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
||||
#
|
||||
# Gmail: garbagecat10
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
#
|
||||
|
||||
# THIS FILE IS A STUB.
|
||||
|
||||
module Net
|
||||
|
||||
class LDIF
|
||||
|
||||
|
||||
end # class LDIF
|
||||
|
||||
|
||||
end # module Net
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# $Id: testber.rb 57 2006-04-18 00:18:48Z blackhedd $
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
$:.unshift "lib"
|
||||
|
||||
require 'net/ldap'
|
||||
require 'stringio'
|
||||
|
||||
|
||||
class TestBer < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
# TODO: Add some much bigger numbers
|
||||
# 5000000000 is a Bignum, which hits different code.
|
||||
def test_ber_integers
|
||||
assert_equal( "\002\001\005", 5.to_ber )
|
||||
assert_equal( "\002\002\203t", 500.to_ber )
|
||||
assert_equal( "\002\003\203\206P", 50000.to_ber )
|
||||
assert_equal( "\002\005\222\320\227\344\000", 5000000000.to_ber )
|
||||
end
|
||||
|
||||
def test_ber_parsing
|
||||
assert_equal( 6, "\002\001\006".read_ber( Net::LDAP::AsnSyntax ))
|
||||
assert_equal( "testing", "\004\007testing".read_ber( Net::LDAP::AsnSyntax ))
|
||||
end
|
||||
|
||||
|
||||
def test_ber_parser_on_ldap_bind_request
|
||||
s = StringIO.new "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus"
|
||||
assert_equal( [1, [3, "Administrator", "ad_is_bogus"]], s.read_ber( Net::LDAP::AsnSyntax ))
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
# $Id: testdata.ldif 50 2006-04-17 17:57:33Z blackhedd $
|
||||
#
|
||||
# This is test-data for an LDAP server in LDIF format.
|
||||
#
|
||||
dn: dc=bayshorenetworks,dc=com
|
||||
objectClass: dcObject
|
||||
objectClass: organization
|
||||
o: Bayshore Networks LLC
|
||||
dc: bayshorenetworks
|
||||
|
||||
dn: cn=Manager,dc=bayshorenetworks,dc=com
|
||||
objectClass: organizationalrole
|
||||
cn: Manager
|
||||
|
||||
dn: ou=people,dc=bayshorenetworks,dc=com
|
||||
objectClass: organizationalunit
|
||||
ou: people
|
||||
|
||||
dn: ou=privileges,dc=bayshorenetworks,dc=com
|
||||
objectClass: organizationalunit
|
||||
ou: privileges
|
||||
|
||||
dn: ou=roles,dc=bayshorenetworks,dc=com
|
||||
objectClass: organizationalunit
|
||||
ou: roles
|
||||
|
||||
dn: ou=office,dc=bayshorenetworks,dc=com
|
||||
objectClass: organizationalunit
|
||||
ou: office
|
||||
|
||||
dn: mail=nogoodnik@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
|
||||
cn: Bob Fosse
|
||||
mail: nogoodnik@steamheat.net
|
||||
sn: Fosse
|
||||
ou: people
|
||||
objectClass: top
|
||||
objectClass: inetorgperson
|
||||
objectClass: authorizedperson
|
||||
hasAccessRole: uniqueIdentifier=engineer,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=brandplace_logging_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=workorder_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=bayshore_eagle_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=bayshore_eagle_superuser,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=kledaras_user,ou=roles
|
||||
|
||||
dn: mail=elephant@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
|
||||
cn: Gwen Verdon
|
||||
mail: elephant@steamheat.net
|
||||
sn: Verdon
|
||||
ou: people
|
||||
objectClass: top
|
||||
objectClass: inetorgperson
|
||||
objectClass: authorizedperson
|
||||
hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=engineer,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles
|
||||
|
||||
dn: uniqueIdentifier=engineering,ou=privileges,dc=bayshorenetworks,dc=com
|
||||
uniqueIdentifier: engineering
|
||||
ou: privileges
|
||||
objectClass: accessPrivilege
|
||||
|
||||
dn: uniqueIdentifier=engineer,ou=roles,dc=bayshorenetworks,dc=com
|
||||
uniqueIdentifier: engineer
|
||||
ou: roles
|
||||
objectClass: accessRole
|
||||
hasAccessPrivilege: uniqueIdentifier=engineering,ou=privileges
|
||||
|
||||
dn: uniqueIdentifier=ldapadmin,ou=roles,dc=bayshorenetworks,dc=com
|
||||
uniqueIdentifier: ldapadmin
|
||||
ou: roles
|
||||
objectClass: accessRole
|
||||
|
||||
dn: uniqueIdentifier=ldapsuperadmin,ou=roles,dc=bayshorenetworks,dc=com
|
||||
uniqueIdentifier: ldapsuperadmin
|
||||
ou: roles
|
||||
objectClass: accessRole
|
||||
|
||||
dn: mail=catperson@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
|
||||
cn: Sid Sorokin
|
||||
mail: catperson@steamheat.net
|
||||
sn: Sorokin
|
||||
ou: people
|
||||
objectClass: top
|
||||
objectClass: inetorgperson
|
||||
objectClass: authorizedperson
|
||||
hasAccessRole: uniqueIdentifier=engineer,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles
|
||||
hasAccessRole: uniqueIdentifier=workorder_user,ou=roles
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# $Id: testem.rb 121 2006-05-15 18:36:24Z blackhedd $
|
||||
#
|
||||
#
|
||||
|
||||
require 'test/unit'
|
||||
require 'tests/testber'
|
||||
require 'tests/testldif'
|
||||
require 'tests/testldap'
|
||||
require 'tests/testpsw'
|
||||
require 'tests/testfilter'
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# $Id: testfilter.rb 122 2006-05-15 20:03:56Z blackhedd $
|
||||
#
|
||||
#
|
||||
|
||||
require 'test/unit'
|
||||
|
||||
$:.unshift "lib"
|
||||
|
||||
require 'net/ldap'
|
||||
|
||||
|
||||
class TestFilter < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
|
||||
def teardown
|
||||
end
|
||||
|
||||
def test_rfc_2254
|
||||
p Net::LDAP::Filter.from_rfc2254( " ( uid=george* ) " )
|
||||
p Net::LDAP::Filter.from_rfc2254( "uid!=george*" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "uid<george*" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "uid <= george*" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "uid>george*" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "uid>=george*" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "uid!=george*" )
|
||||
|
||||
p Net::LDAP::Filter.from_rfc2254( "(& (uid!=george* ) (mail=*))" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "(| (uid!=george* ) (mail=*))" )
|
||||
p Net::LDAP::Filter.from_rfc2254( "(! (mail=*))" )
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
# $Id: testldap.rb 65 2006-04-23 01:17:49Z blackhedd $
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
$:.unshift "lib"
|
||||
|
||||
require 'test/unit'
|
||||
|
||||
require 'net/ldap'
|
||||
require 'stringio'
|
||||
|
||||
|
||||
class TestLdapClient < Test::Unit::TestCase
|
||||
|
||||
# TODO: these tests crash and burn if the associated
|
||||
# LDAP testserver isn't up and running.
|
||||
# We rely on being able to read a file with test data
|
||||
# in LDIF format.
|
||||
# TODO, WARNING: for the moment, this data is in a file
|
||||
# whose name and location are HARDCODED into the
|
||||
# instance method load_test_data.
|
||||
|
||||
def setup
|
||||
@host = "127.0.0.1"
|
||||
@port = 3890
|
||||
@auth = {
|
||||
:method => :simple,
|
||||
:username => "cn=bigshot,dc=bayshorenetworks,dc=com",
|
||||
:password => "opensesame"
|
||||
}
|
||||
|
||||
@ldif = load_test_data
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Get some test data which will be used to validate
|
||||
# the responses from the test LDAP server we will
|
||||
# connect to.
|
||||
# TODO, Bogus: we are HARDCODING the location of the file for now.
|
||||
#
|
||||
def load_test_data
|
||||
ary = File.readlines( "tests/testdata.ldif" )
|
||||
hash = {}
|
||||
while line = ary.shift and line.chomp!
|
||||
if line =~ /^dn:[\s]*/i
|
||||
dn = $'
|
||||
hash[dn] = {}
|
||||
while attr = ary.shift and attr.chomp! and attr =~ /^([\w]+)[\s]*:[\s]*/
|
||||
hash[dn][$1.downcase.intern] ||= []
|
||||
hash[dn][$1.downcase.intern] << $'
|
||||
end
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Binding tests.
|
||||
# Need tests for all kinds of network failures and incorrect auth.
|
||||
# TODO: Implement a class-level timeout for operations like bind.
|
||||
# Search has a timeout defined at the protocol level, other ops do not.
|
||||
# TODO, use constants for the LDAP result codes, rather than hardcoding them.
|
||||
def test_bind
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
|
||||
assert_equal( true, ldap.bind )
|
||||
assert_equal( 0, ldap.get_operation_result.code )
|
||||
assert_equal( "Success", ldap.get_operation_result.message )
|
||||
|
||||
bad_username = @auth.merge( {:username => "cn=badguy,dc=imposters,dc=com"} )
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_username
|
||||
assert_equal( false, ldap.bind )
|
||||
assert_equal( 48, ldap.get_operation_result.code )
|
||||
assert_equal( "Inappropriate Authentication", ldap.get_operation_result.message )
|
||||
|
||||
bad_password = @auth.merge( {:password => "cornhusk"} )
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_password
|
||||
assert_equal( false, ldap.bind )
|
||||
assert_equal( 49, ldap.get_operation_result.code )
|
||||
assert_equal( "Invalid Credentials", ldap.get_operation_result.message )
|
||||
end
|
||||
|
||||
|
||||
|
||||
def test_search
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
|
||||
|
||||
search = {:base => "dc=smalldomain,dc=com"}
|
||||
assert_equal( false, ldap.search( search ))
|
||||
assert_equal( 32, ldap.get_operation_result.code )
|
||||
|
||||
search = {:base => "dc=bayshorenetworks,dc=com"}
|
||||
assert_equal( true, ldap.search( search ))
|
||||
assert_equal( 0, ldap.get_operation_result.code )
|
||||
|
||||
ldap.search( search ) {|res|
|
||||
assert_equal( res, @ldif )
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
# This is a helper routine for test_search_attributes.
|
||||
def internal_test_search_attributes attrs_to_search
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
|
||||
assert( ldap.bind )
|
||||
|
||||
search = {
|
||||
:base => "dc=bayshorenetworks,dc=com",
|
||||
:attributes => attrs_to_search
|
||||
}
|
||||
|
||||
ldif = @ldif
|
||||
ldif.each {|dn,entry|
|
||||
entry.delete_if {|attr,value|
|
||||
! attrs_to_search.include?(attr)
|
||||
}
|
||||
}
|
||||
|
||||
assert_equal( true, ldap.search( search ))
|
||||
ldap.search( search ) {|res|
|
||||
res_keys = res.keys.sort
|
||||
ldif_keys = ldif.keys.sort
|
||||
assert( res_keys, ldif_keys )
|
||||
res.keys.each {|rk|
|
||||
assert( res[rk], ldif[rk] )
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
def test_search_attributes
|
||||
internal_test_search_attributes [:mail]
|
||||
internal_test_search_attributes [:cn]
|
||||
internal_test_search_attributes [:ou]
|
||||
internal_test_search_attributes [:hasaccessprivilege]
|
||||
internal_test_search_attributes ["mail"]
|
||||
internal_test_search_attributes ["cn"]
|
||||
internal_test_search_attributes ["ou"]
|
||||
internal_test_search_attributes ["hasaccessrole"]
|
||||
|
||||
internal_test_search_attributes [:mail, :cn, :ou, :hasaccessrole]
|
||||
internal_test_search_attributes [:mail, "cn", :ou, "hasaccessrole"]
|
||||
end
|
||||
|
||||
|
||||
def test_search_filters
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
|
||||
search = {
|
||||
:base => "dc=bayshorenetworks,dc=com",
|
||||
:filter => Net::LDAP::Filter.eq( "sn", "Fosse" )
|
||||
}
|
||||
|
||||
ldap.search( search ) {|res|
|
||||
p res
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
def test_open
|
||||
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
|
||||
ldap.open {|ldap|
|
||||
10.times {
|
||||
rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" )
|
||||
assert_equal( true, rc )
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
def test_ldap_open
|
||||
Net::LDAP.open( :host => @host, :port => @port, :auth => @auth ) {|ldap|
|
||||
10.times {
|
||||
rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" )
|
||||
assert_equal( true, rc )
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
# $Id: testldif.rb 61 2006-04-18 20:55:55Z blackhedd $
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
$:.unshift "lib"
|
||||
|
||||
require 'test/unit'
|
||||
|
||||
require 'net/ldap'
|
||||
require 'net/ldif'
|
||||
|
||||
require 'sha1'
|
||||
require 'base64'
|
||||
|
||||
class TestLdif < Test::Unit::TestCase
|
||||
|
||||
TestLdifFilename = "tests/testdata.ldif"
|
||||
|
||||
def test_empty_ldif
|
||||
ds = Net::LDAP::Dataset::read_ldif( StringIO.new )
|
||||
assert_equal( true, ds.empty? )
|
||||
end
|
||||
|
||||
def test_ldif_with_comments
|
||||
str = ["# Hello from LDIF-land", "# This is an unterminated comment"]
|
||||
io = StringIO.new( str[0] + "\r\n" + str[1] )
|
||||
ds = Net::LDAP::Dataset::read_ldif( io )
|
||||
assert_equal( str, ds.comments )
|
||||
end
|
||||
|
||||
def test_ldif_with_password
|
||||
psw = "goldbricks"
|
||||
hashed_psw = "{SHA}" + Base64::encode64( SHA1.new(psw).digest ).chomp
|
||||
|
||||
ldif_encoded = Base64::encode64( hashed_psw ).chomp
|
||||
ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: Goldbrick\r\nuserPassword:: #{ldif_encoded}\r\n\r\n" ))
|
||||
recovered_psw = ds["Goldbrick"][:userpassword].shift
|
||||
assert_equal( hashed_psw, recovered_psw )
|
||||
end
|
||||
|
||||
def test_ldif_with_continuation_lines
|
||||
ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: abcdefg\r\n hijklmn\r\n\r\n" ))
|
||||
assert_equal( true, ds.has_key?( "abcdefg hijklmn" ))
|
||||
end
|
||||
|
||||
# TODO, INADEQUATE. We need some more tests
|
||||
# to verify the content.
|
||||
def test_ldif
|
||||
File.open( TestLdifFilename, "r" ) {|f|
|
||||
ds = Net::LDAP::Dataset::read_ldif( f )
|
||||
assert_equal( 13, ds.length )
|
||||
}
|
||||
end
|
||||
|
||||
# TODO, need some tests.
|
||||
# Must test folded lines and base64-encoded lines as well as normal ones.
|
||||
def test_to_ldif
|
||||
File.open( TestLdifFilename, "r" ) {|f|
|
||||
ds = Net::LDAP::Dataset::read_ldif( f )
|
||||
ds.to_ldif
|
||||
assert_equal( true, false ) # REMOVE WHEN WE HAVE SOME TESTS HERE.
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# $Id: testpsw.rb 72 2006-04-24 21:58:14Z blackhedd $
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
$:.unshift "lib"
|
||||
|
||||
require 'net/ldap'
|
||||
require 'stringio'
|
||||
|
||||
|
||||
class TestPassword < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
|
||||
def test_psw
|
||||
assert_equal( "{MD5}xq8jwrcfibi0sZdZYNkSng==", Net::LDAP::Password.generate( :md5, "cashflow" ))
|
||||
assert_equal( "{SHA}YE4eGkN4BvwNN1f5R7CZz0kFn14=", Net::LDAP::Password.generate( :sha, "cashflow" ))
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user