Engee documentation
Notebook

Column alignment algorithm

This example shows the implementation of an algorithm for text alignment across columns with different types of alignment (left, right, center) in the Julia programming language.

Introduction

The column alignment algorithm is used to format text data organized into a tabular structure. It allows you to create beautifully formatted tables where the columns are aligned relative to each other. This approach is used when outputting reports, logs, tables, and other structured data to improve readability. In this example, the input data is presented as text, where the fields are separated by a dollar symbol ($), а строки разделены символом новой строки.

Основная часть

Подготовка данных и вспомогательные функции

Исходный текст с разделителями в виде знака доллара

In [ ]:
txt = """Given\$a\$txt\$file\$of\$many\$lines,\$where\$fields\$within\$a\$line\$
are\$delineated\$by\$a\$single\$'dollar'\$character,\$write\$a\$program
that\$aligns\$each\$column\$of\$fields\$by\$ensuring\$that\$words\$in\$each\$
column\$are\$separated\$by\$at\$least\$one\$space.
Further,\$allow\$for\$each\$word\$in\$a\$column\$to\$be\$either\$left\$
justified,\$right\$justified,\$or\$center\$justified\$within\$its\$column.""";

Функции для выравнивания текста разных типов:

In [ ]:
# Left alignment: add spaces on the right
ljust(s, width) = s * " "^max(0, width - length(s))

# Right alignment: add spaces on the left
rjust(s, width) = " "^max(0, width - length(s)) * s

# Center alignment: add spaces on both sides
function center(s, width)
  pad = width - length(s)  # number of spaces to fill in
  if pad <= 0              # if the text is already wider than the required width
    return s               # we return it as it is
  else
    pad2 = div(pad, 2)     # number of spaces on the left (half)
    # we return a string with spaces on the left and right
    return " "^pad2 * s * " "^(pad - pad2)
  end
end
Out[0]:
center (generic function with 1 method)

Разбор входных данных

Разделяем текст на строки по символу новой строки \n.

Затем каждую строку разделяем по символу $ by first deleting the final $

In [ ]:
parts = [split(rstrip(line, '$'), '$') for line in split(txt, '\n')]
# parts now contains an array of arrays of words (rows -> columns)
Out[0]:
6-element Vector{Vector{SubString{String}}}:
 ["Given", "a", "txt", "file", "of", "many", "lines,", "where", "fields", "within", "a", "line"]
 ["are", "delineated", "by", "a", "single", "'dollar'", "character,", "write", "a", "program"]
 ["that", "aligns", "each", "column", "of", "fields", "by", "ensuring", "that", "words", "in", "each"]
 ["column", "are", "separated", "by", "at", "least", "one", "space."]
 ["Further,", "allow", "for", "each", "word", "in", "a", "column", "to", "be", "either", "left"]
 ["justified,", "right", "justified,", "or", "center", "justified", "within", "its", "column."]

Determining the maximum column width

Creating an array to store the maximum width of each column

The maximum number of columns is defined as the maximum row length.

In [ ]:
max_widths = zeros(Int, maximum(length, parts));

We go through all the rows and determine the maximum width for each column.

In [ ]:
for line in parts
  for (i, word) in enumerate(line)
    # Updating the maximum width for column i
    max_widths[i] = max(max_widths[i], length(word))
  end
end   

Add 1 to each column width to ensure at least one space between the columns.

In [ ]:
max_widths .+= 1;

Formation and output of the result with different types of alignment

In [ ]:
# We go through each type of alignment
for (label, justify) in (("to the left edge", ljust), ("to the right edge",rjust), ("the center",center))
  # Output the header for the current alignment type
  println("Alignment by ", label, ":\n")
  
  # We go through each row of the source data
  for line in parts
    # We go through each word (column) in the row
    for (j, word) in enumerate(line)
      # Applying the alignment function to a word with a given column width
      print(justify(word, max_widths[j]))
    end
    # Switching to a new line after the end of the data line
    println()
  end
  
  # We draw a dividing line from hyphens
  println("-"^sum(max_widths),"\n")
end
Выравнивание по левому краю:

Given      a          txt        file   of     many      lines,     where    fields  within  a      line 
are        delineated by         a      single 'dollar'  character, write    a       program 
that       aligns     each       column of     fields    by         ensuring that    words   in     each 
column     are        separated  by     at     least     one        space.   
Further,   allow      for        each   word   in        a          column   to      be      either left 
justified, right      justified, or     center justified within     its      column. 
---------------------------------------------------------------------------------------------------------

Выравнивание по правому краю:

      Given          a        txt   file     of      many     lines,    where  fields  within      a line
        are delineated         by      a single  'dollar' character,    write       a program
       that     aligns       each column     of    fields         by ensuring    that   words     in each
     column        are  separated     by     at     least        one   space.
   Further,      allow        for   each   word        in          a   column      to      be either left
 justified,      right justified,     or center justified     within      its column.
---------------------------------------------------------------------------------------------------------

Выравнивание по центру:

   Given        a         txt     file    of      many     lines,     where   fields  within    a   line 
    are    delineated     by        a   single  'dollar' character,   write     a    program 
   that      aligns      each    column   of     fields      by     ensuring   that   words    in   each 
  column       are     separated   by     at     least       one     space.  
 Further,     allow       for     each   word      in         a      column     to      be   either left 
justified,    right   justified,   or   center justified   within      its   column. 
---------------------------------------------------------------------------------------------------------

Conclusion

In this example, we looked at the implementation of the text column alignment algorithm in Julia. We have managed to create a program that accepts delimited text, splits it into columns, determines the required width of each column, and outputs formatted text with three types of alignment: left, right, and center. It is useful for creating readable tables and reports in text format, and also demonstrates the basics of working with text data and string formatting in Julia.

The example was developed using materials from Rosetta Code