This is a Ruby library for reading and writing Fortran's namelist. This library allows you to read a namelist string as a Hash object, or dump a Hash object to a namelist string.
- Flexible parsing of (too free) namelist format using Racc
- Reading namelist string as a Ruby's Hash object
- Converting a Hash object to a namelist string (specifying the format)
gem install fortio-namelist
To use the library in your Ruby script,
require "fortio-namelist"
To read and write a namelist, it is sufficient to use only the following two methods.
FortIO::Namelist.parse(input, group: nil)
FortIO::Namelist.dump(root, **format_options)
To create a Hash object with namelist structure by reading a namelist string, use the following method.
FortIO::Namelist.parse(input, group: nil)
The argument input
is given as a string, but it also accepts objects with a method #read
which returns a string like an IO object ('duck typing').
To read only a specific group, give a group name to the keyword argument group
. If group
is omitted, all namelist groups included in input
will be read. To load multiple groups, give an array of group names to group
.
The Hash object of the return value has a two-level structure as follows.
{
group1: {
var11: value11,
var12: value12,
: :
}
group2: {
var21: value21,
var22: value22,
: :
}
:
:
}
The group and variable names are converted to lowercase Symbol objects and stored as keys in the hash. The value can be Ruby's String, Integer, Float, Complex, TrueClass, or FalseClass objects, depending on the literal in the namelist. In the case that the value is an array, it will be expressed as an Array in Ruby. We chose symbol as the key of the hash object because it is thought to be compatible with the pattern matching introduced in Ruby 2.7.
Example:
require 'fortio-namelist'
input = %{
&group1
var1 = 11
var2 = 12
/
&group2
var1 = 12
var2 = 22
/
&group3
var1 = 31
var2 = 32
/
}
### read all groups
root = FortIO::Namelist.parse(input)
# => {:group1=>{:var1=>11, :var2=>12},
# :group2=>{:var1=>12, :var2=>22},
# :group3=>{:var1=>31, :var2=>32}}
### read only "group2"
root = FortIO::Namelist.parse(input, group: "group2")
# => {:group2=>{:var1=>12, :var2=>22}}
### read only "group1" and "group3"
root = FortIO::Namelist.parse(input, group: ["group1", "group3"])
# => {:group1=>{:var1=>11, :var2=>12},
# :group3=>{:var1=>31, :var2=>32}}
To generate a namelist string from a Hash object with a namelist structure, use the following method.
FortIO::Namelist.dump(root, **format_options)
The argument root
is given as a Hash object. The return value is a namelist string.
Example:
require 'fortio-namelist'
root = {group1: {var1: 11, var2: 12},
group2: {var1: 12, var2: 22},
group3: {var1: 31, var2: 32}}
puts FortIO::Namelist.dump(root)
This script print a namelist format string to stdout.
&group1
var1 = 11,
var2 = 12
/
&group2
var1 = 12,
var2 = 22
/
&group3
var1 = 31,
var2 = 32
/
You can finely control the output namelist string with the following keyword arguments (the first one is the default).
array_style
: the notation for array elementslogical_format
: boolean literalsfloat_format
: the notation for floating point numbersalignment
: how variable identifiers are aligneduppercase
: whether variable names, etc. should be uppercase or lowercase.separator
: the separator between variable definitionsgroup_end
: the group terminatorindent
: the indentation for variable definition
- 'stream' : (default)
- 'index' :
Example:
root = {group: {var1: [1,2,3], var2: ["a","b","c"]}}
puts FortIO::Namelist.dump(root, array_style: 'stream')
# =>
# &group
# var1 = 1, 2, 3,
# var2 = 'a', 'b', 'c'
# /
puts FortIO::Namelist.dump(root, array_style: 'index')
# =>
# &group
# var1(1) = 1,
# var1(2) = 2,
# var1(3) = 3,
# var2(1) = 'a',
# var2(2) = 'b',
# var2(3) = 'c'
# /
- 'normal' : normal notation like
.true.
,.false
(default) - 'short' : short notation like
t
,f
root = {group: {var1: true, var2: false}}
puts FortIO::Namelist.dump(root, logical_format: 'normal')
# =>
# &group
# var1 = .true.,
# var2 = .false.
# /
puts FortIO::Namelist.dump(root, logical_format: 'short')
# =>
# &group
# var1 = t,
# var2 = f
# /
- 'normal' : format with "%g" (default)
- 'd0' : format with "%g" followed by 'd0'
- 'exp' : exponential notation
root = {group: {var1: 1.0, var2: 12.75, var3: 50.0e-8}}
puts FortIO::Namelist.dump(root, float_format: 'normal')
# =>
# &group
# var1 = 1,
# var2 = 12.75,
# var3 = 5d-07
# /
puts FortIO::Namelist.dump(root, float_format: 'd0')
# =>
# &group
# var1 = 1d0,
# var2 = 12.75d0,
# var3 = 5d-07
# /
puts FortIO::Namelist.dump(root, float_format: 'exp')
# =>
# &group
# var1 = 1d+00,
# var2 = 1.275d+01,
# var3 = 5d-07
# /
- 'left' : aligned, left-justified, position of '=' can be specified by number eg. 'left:7' (default)
- 'right' : aligned, right-justified, position of '=' can be specified by number eg. 'right:7'
- 'none' : not aligned
- 'stream' : not aligned, stream style, length of each line can be specified by number eg. 'stream:70'
root = {group: {var1: 1, variable2: [1,2,3], v3: true}}
puts FortIO::Namelist.dump(root, alignment: 'left')
# =>
# &group
# var1 = 1,
# variable2 = 1, 2, 3,
# v3 = .true.
# /
puts FortIO::Namelist.dump(root, alignment: 'left:7')
# =>
# &group
# var1 = 1,
# variable2 = 1, 2, 3,
# v3 = .true.
# /
puts FortIO::Namelist.dump(root, alignment: 'right')
# =>
# &group
# var1 = 1,
# variable2 = 1, 2, 3,
# v3 = .true.
# /
puts FortIO::Namelist.dump(root, alignment: 'right:7')
# =>
# &group
# var1 = 1,
# variable2 = 1, 2, 3,
# v3 = .true.
# /
puts FortIO::Namelist.dump(root, alignment: 'none')
# =>
# &group
# var1 = 1,
# variable2 = 1, 2, 3,
# v3 = .true.
# /
puts FortIO::Namelist.dump(root, alignment: 'stream')
# =>
# &group
# var1 = 1, variable2 = 1, 2, 3, v3 = .true.,
# /
- false : (default)
- true :
root = {group: {var1: 1, var2: "a"}}
puts FortIO::Namelist.dump(root, uppercase: false)
# =>
# &group
# var1 = 1,
# val2 = 'a'
# /
puts FortIO::Namelist.dump(root, uppercase: true)
# =>
# &GROUP
# VAR1 = 1,
# VAL2 = 'a'
# /
- "comma", "," : comma + NL separeted (default)
- "nl", "\n" : NL separated
root = {group1: {var1: 1, var2: "a", var3: true},
group2: {var1: 2, var2: "b", var3: false}}
puts FortIO::Namelist.dump(root, separator: "comma")
# =>
# &group1
# var1 = 1,
# var2 = 'a',
# var3 = .true.
# /
# &group2
# var1 = 2,
# var2 = 'b',
# var3 = .false.
# /
puts FortIO::Namelist.dump(root, separator: "nl")
# =>
# &group1
# var1 = 1
# var2 = 'a'
# var3 = .true.
# /
# &group2
# var1 = 2
# var2 = 'b'
# var3 = .false.
# /
- "slash", "/" : end with
/
(default) - "end" : end with
&end
root = {group: {var1: true, var2: false}}
puts FortIO::Namelist.dump(root, group_end: 'slash')
# =>
# &group
# var1 = .true.,
# var2 = .false.
# /
puts FortIO::Namelist.dump(root, group_end: 'end')
# =>
# &group
# var1 = .true.,
# var2 = .false.
# &end
- ' '*2 : two spaces (default)
root = {group: {var1: true, var2: false}}
puts FortIO::Namelist.dump(root, indent: ' '*2)
# =>
# &group
# var1 = .true.,
# var2 = .false.
# /
puts FortIO::Namelist.dump(root, indent: ' '*4)
# =>
# &group
# var1 = .true.,
# var2 = .false.
# /