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 [ ]:
# Выравнивание по левому краю: добавляем пробелы справа
ljust(s, width) = s * " "^max(0, width - length(s))

# Выравнивание по правому краю: добавляем пробелы слева
rjust(s, width) = " "^max(0, width - length(s)) * s

# Выравнивание по центру: добавляем пробелы с обеих сторон
function center(s, width)
  pad = width - length(s)  # количество пробелов для заполнения
  if pad <= 0              # если текст уже шире нужной ширины
    return s               # возвращаем как есть
  else
    pad2 = div(pad, 2)     # количество пробелов слева (половина)
    # возвращаем строку с пробелами слева и справа
    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 теперь содержит массив массивов слов (строки -> столбцы)
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)
    # Обновляем максимальную ширину для столбца 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 [ ]:
# Проходим по каждому типу выравнивания
for (label, justify) in (("левому краю", ljust), ("правому краю",rjust), ("центру",center))
  # Выводим заголовок для текущего типа выравнивания
  println("Выравнивание по ", label, ":\n")
  
  # Проходим по каждой строке исходных данных
  for line in parts
    # Проходим по каждому слову (столбцу) в строке
    for (j, word) in enumerate(line)
      # Применяем функцию выравнивания к слову с заданной шириной столбца
      print(justify(word, max_widths[j]))
    end
    # Переходим на новую строку после окончания строки данных
    println()
  end
  
  # Выводим разделительную линию из дефисов
  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 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