Text Templates in Fortran

Fortran offers string manipulation capabilities that can be used to create dynamic content or show customized output to the user. While it doesn’t have a built-in templating system like some modern languages, we can implement a simple templating mechanism using string operations.

program text_templates
    implicit none
    
    character(len=100) :: template
    character(len=100) :: result
    
    ! Simple template with a placeholder
    template = "Value is {}"
    
    ! Replace placeholder with a string
    call replace_placeholder(template, "some text", result)
    print *, result
    
    ! Replace placeholder with a number
    call replace_placeholder(template, "5", result)
    print *, result
    
    ! Template with a named placeholder
    template = "Name: {name}"
    
    ! Replace named placeholder
    call replace_named_placeholder(template, "name", "Jane Doe", result)
    print *, result
    
    ! Conditional template
    template = "{% if .nonempty %}yes{% else %}no{% endif %}"
    
    ! Execute conditional template
    call execute_conditional(template, .true., result)
    print *, result
    call execute_conditional(template, .false., result)
    print *, result
    
    ! Range template
    template = "Range: {% for item in items %}{item} {% endfor %}"
    
    ! Execute range template
    call execute_range(template, ["Go", "Rust", "C++", "C#"], result)
    print *, result

contains

    subroutine replace_placeholder(tmpl, value, output)
        character(len=*), intent(in) :: tmpl, value
        character(len=*), intent(out) :: output
        integer :: pos
        
        output = tmpl
        pos = index(output, "{}")
        if (pos > 0) then
            output = output(1:pos-1) // trim(value) // output(pos+2:)
        end if
    end subroutine replace_placeholder
    
    subroutine replace_named_placeholder(tmpl, name, value, output)
        character(len=*), intent(in) :: tmpl, name, value
        character(len=*), intent(out) :: output
        integer :: pos
        character(len=100) :: placeholder
        
        output = tmpl
        write(placeholder, '(A,A,A)') "{", trim(name), "}"
        pos = index(output, trim(placeholder))
        if (pos > 0) then
            output = output(1:pos-1) // trim(value) // output(pos+len_trim(placeholder):)
        end if
    end subroutine replace_named_placeholder
    
    subroutine execute_conditional(tmpl, condition, output)
        character(len=*), intent(in) :: tmpl
        logical, intent(in) :: condition
        character(len=*), intent(out) :: output
        integer :: if_pos, else_pos, endif_pos
        
        if_pos = index(tmpl, "{% if")
        else_pos = index(tmpl, "{% else")
        endif_pos = index(tmpl, "{% endif")
        
        if (condition) then
            output = tmpl(if_pos+13:else_pos-1)
        else
            output = tmpl(else_pos+8:endif_pos-1)
        end if
    end subroutine execute_conditional
    
    subroutine execute_range(tmpl, items, output)
        character(len=*), intent(in) :: tmpl
        character(len=*), dimension(:), intent(in) :: items
        character(len=*), intent(out) :: output
        integer :: i, start_pos, end_pos
        character(len=100) :: item_template, item_result
        
        start_pos = index(tmpl, "{% for") + 19
        end_pos = index(tmpl, "{% endfor") - 1
        item_template = tmpl(start_pos:end_pos)
        
        output = ""
        do i = 1, size(items)
            call replace_placeholder(item_template, trim(items(i)), item_result)
            output = trim(output) // " " // trim(item_result)
        end do
    end subroutine execute_range

end program text_templates

This Fortran program demonstrates a basic templating system using string manipulation. While it’s not as sophisticated as the text/template package in some other languages, it provides similar functionality:

  1. We define a simple template with placeholders and use the replace_placeholder subroutine to replace them with values.

  2. We implement a named placeholder system using the replace_named_placeholder subroutine.

  3. We create a basic conditional templating system with the execute_conditional subroutine, which selects different parts of the template based on a condition.

  4. We implement a simple loop construct with the execute_range subroutine, which repeats a part of the template for each item in an array.

To run this program, save it to a file (e.g., text_templates.f90) and compile it using a Fortran compiler:

$ gfortran text_templates.f90 -o text_templates
$ ./text_templates

This will output:

Value is some text
Value is 5
Name: Jane Doe
yes
no
Range: Go Rust C++ C#

While this implementation is basic, it demonstrates how you can create a simple templating system in Fortran. For more complex use cases, you might want to consider using external libraries or implementing a more robust parsing system.