fortio-namelist
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.
Features
- 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)
Installation
gem install fortio-namelist
To use the library in your Ruby script,
require "fortio-namelist"
Usage
Useful methods
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, **)
Reading namelist
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}}
Generating namelist string from Hash object with namelist structure
To generate a namelist string from a Hash object with a namelist structure, use the following method.
FortIO::Namelist.dump(root, **)
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
/
Format options for FortIO::Namelist.dump
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
array_style
specifies the notation for array elements
- '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'
# /
logical_format
specifies boolean literals
- '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
# /
float_format
specifies the notation for floating point numbers
- '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
# /
alignment
specifies how variable identifiers are aligned
- '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.,
# /
uppercase
specifies whether variable names, etc. should be uppercase or lowercase.
- 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'
# /
separator
specifies the separator between variable definitions
- "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.
# /
group_end
specifies the group terminator
- "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
indent
specifies the indentation for variable definition
- ' '*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.
# /