[RUBY] I checked the specification of how to specify cell attributes of AsciiDoc table & internal implementation of Asciidoctor

Cell version of I checked the specification of cols attribute of AsciiDoc table & internal implementation of Asciidoctor.

Reference site 1 Asciidoctor User Manual #cell seems to have a relatively detailed description.

Description example of cell merging

Specify immediately before the cell (starting with |). In the example below, the .2 + ^. ^ And 3 + ^ parts.

AsciiDoc



[options="header"]
|===
      |Date          |Duration | Location | Plan
.2+^.^|2021.01.04    |08:00    | XXX      | game
                     |09:00    | YYY      | coding
      |2021.01.05    |08:00    | XXX      | no plan
      |2021.01.06 3+^| work
|===

The output is as follows. image.png

Follow internal implementation

The parse_cellspec method called from the self.parse_table method in parser.rb

parser.rb (excerpt & line number supplement)



# Internal: Parse the cell specs for the current cell.
#
# The cell specs dictate the cell's alignments, styles or filters,
# colspan, rowspan and/or repeating content.
#
# The default spec when pos == :end is {} since we already know we're at a
# delimiter. When pos == :start, we *may* be at a delimiter, nil indicates
# we're not.
#
# returns the Hash of attributes that indicate how to layout
# and style this cell in the table.
def self.parse_cellspec(line, pos = :end, delimiter = nil)             #  1
  m, rest = nil, ''                                                    #  2
                                                                       #  3
  if pos == :start                                                     #  4
    if line.include? delimiter                                         #  5
      spec_part, delimiter, rest = line.partition delimiter            #  6
      if (m = CellSpecStartRx.match spec_part)                         #  7
        return [{}, rest] if m[0].empty?                               #  8
      else                                                             #  9
        return [nil, line]                                             # 10
      end                                                              # 11
    else                                                               # 12
      return [nil, line]                                               # 13
    end                                                                # 14
  else # pos == :end                                                   # 15
    if (m = CellSpecEndRx.match line)                                  # 16
      # NOTE return the line stripped of trailing whitespace if no cellspec is found in this case # 17
      return [{}, line.rstrip] if m[0].lstrip.empty?                   # 18
      rest = m.pre_match                                               # 19
    else                                                               # 20
      return [{}, line]                                                # 21
    end                                                                # 22
  end                                                                  # 23
                                                                       # 24
  spec = {}                                                            # 25
  if m[1]                                                              # 26
    colspec, rowspec = m[1].split '.'                                  # 27
    colspec = colspec.nil_or_empty? ? 1 : colspec.to_i                 # 28
    rowspec = rowspec.nil_or_empty? ? 1 : rowspec.to_i                 # 29
    if m[2] == '+'                                                     # 30
      spec['colspan'] = colspec unless colspec == 1                    # 31
      spec['rowspan'] = rowspec unless rowspec == 1                    # 32
    elsif m[2] == '*'                                                  # 33
      spec['repeatcol'] = colspec unless colspec == 1                  # 34
    end                                                                # 35
  end                                                                  # 36
                                                                       # 37
  if m[3]                                                              # 38
    colspec, rowspec = m[3].split '.'                                  # 39
    if !colspec.nil_or_empty? && TableCellHorzAlignments.key?(colspec) # 40
      spec['halign'] = TableCellHorzAlignments[colspec]                # 41
    end                                                                # 42
    if !rowspec.nil_or_empty? && TableCellVertAlignments.key?(rowspec) # 43
      spec['valign'] = TableCellVertAlignments[rowspec]                # 44
    end                                                                # 45
  end                                                                  # 46
                                                                       # 47
  if m[4] && TableCellStyles.key?(m[4])                                # 48
    spec['style'] = TableCellStyles[m[4]]                              # 49
  end                                                                  # 50
                                                                       # 51
  [spec, rest]                                                         # 52
end                                                                    # 53

Matching processing is performed on the 7th and 16th lines. The regular expressions used are as follows.

rx.rb (excerpt & comment omitted & supplement)



# Examples
#   2.3+<.>m
#                            m[1]                         m[2]    m[3]                                    m[4]
#                            <---------------------------><---->  <-------------------------------------> <----->
CellSpecStartRx = /^[ \t]*(?:(\d+(?:\.\d*)?|(?:\d*\.)?\d+)([*+]))?([<^>](?:\.[<^>]?)?|(?:[<^>]?\.)?[<^>])?([a-z])?$/
CellSpecEndRx   =  /[ \t]+(?:(\d+(?:\.\d*)?|(?:\d*\.)?\d+)([*+]))?([<^>](?:\.[<^>]?)?|(?:[<^>]?\.)?[<^>])?([a-z])?$/

CellSpecStartRx seems to be for the beginning of a line, and CellSpecEndRx seems to be for other purposes.

--m [1] m [2]: In the case of integer`` . integer` `+` ... The number of columns to join (horizontal direction) and the number of rows to join (vertical direction). <br> `.` and later can be omitted. Alternatively, you can omit the part before `.`. --m [1] m [2]: For `integer * ... Repeat the same cell for the specified number of columns (see Reference Site 1). --m [3]: Horizontal direction (< or ^ or>) . Vertical direction (< or ^ or>) ・ ・ ・ Alignment Horizontal (left justified, center justified, Right-justified) and vertical (top-justified, center-justified, bottom-justified). <br> .and later can be omitted. Alternatively, you can omit the part before.. --m [4]: ​​Character` ・ ・ ・ Format specification

Reference site

  1. Asciidoctor User Manual #cell

Recommended Posts

I checked the specification of how to specify cell attributes of AsciiDoc table & internal implementation of Asciidoctor
I checked the specification of cols attribute of AsciiDoc table & internal implementation of Asciidoctor
[Rails] How to change the column name of the table
[SwiftUI] How to specify the abbreviated position of Text
[Ruby] I want to reverse the order of the hash table
I examined the concept of the process to understand how Docker works
How to set the indent to 2 single-byte spaces in the JAXB implementation of the JDK
[Spring Boot] I investigated how to implement post-processing of the received request.
I investigated the internal processing of Retrofit
How to determine the number of parallels
How to sort the List of SelectItem
I want to get the value of Cell transparently regardless of CellType (Apache POI)
How to make a unique combination of data in the rails intermediate table
How to find the cause of the Ruby error
I want to output the day of the week
I checked the place of concern of java.net.URL # getPath
Customize how to divide the contents of Recyclerview
I want to var_dump the contents of the intent
How to get today's day of the week
Output of how to use the slice method
How to display the result of form input
[Java] How to get the authority of the folder
How to specify index of JavaScript for statement
I checked the number of taxis with Ruby
Offline real-time how to write Implementation example of the problem in E05 (ruby, C11)
[Active Admin] I want to specify the scope of the collection to be displayed in select_box