Sublime Forum

Tabularize

#1

First of all - sorry, I’m not a native python speaker :smile:

Actually I just wanted to quickly dump this tiny thing, I’m confident some of you might find a use for this.

Tabularize will turn this:

Course Name | Course Tutor | Summary | Code | Fee After the Civil ... | Dr. John Wroughton | The course will ... | H27 | 32€ An Introduction to ... | Mark Cottle | One day course ... | H28 | 18€ The Glory that ... | Valerie Lorenz | Birthplace of democracy, ... | H30 | 18€

into this:

+------------------------+--------------------+------------------------------+------+-----+ | Course Name | Course Tutor | Summary | Code | Fee | +------------------------+--------------------+------------------------------+------+-----+ | After the Civil ... | Dr. John Wroughton | The course will ... | H27 | 32€ | +------------------------+--------------------+------------------------------+------+-----+ | An Introduction to ... | Mark Cottle | One day course ... | H28 | 18€ | +------------------------+--------------------+------------------------------+------+-----+ | The Glory that ... | Valerie Lorenz | Birthplace of democracy, ... | H30 | 18€ | +------------------------+--------------------+------------------------------+------+-----+

Feel free to improve the code. Actually, really, please do! (and post results back here :smile:)

[code]import sublime, sublime_plugin
import array, string

class TabularizeCommand(sublime_plugin.TextCommand):
def run(self, edit):
sels = self.view.sel()
for sel in sels:
if sel.empty():
continue

		old = self.view.substr(sel)
		new = self.tabularize(old)

		edit = self.view.begin_edit();
		self.view.replace(edit, sel, new)
		self.view.end_edit(edit)

def tabularize(self, old):
	rawRows = string.split(old, "\n")

	# spaltenanzahl validieren
	colCount = string.count(rawRows[0], "|") + 1
	for row in rawRows[1:]:
		if string.count(row, "|") != colCount - 1:
			sublime.error_message("column count does not match")
			return old

	# spaltenbreiten ermitteln
	print colCount
	widths = ]
	for col in xrange(0, colCount):
		max = 0
		for row in rawRows:
			val = string.split(row, "|")[col].strip()
			vLen = len(val)
			if vLen > max:
				max = vLen
		widths.append(max)

	new = self.empty_table_line(widths)
	
	# inhaltszeilen zusammenbauen
	for row in rawRows:
		vals = string.split(row, "|")
		line = "|"
		for col in xrange(0, len(vals)):
			val = vals[col].strip()
			vLen = widths[col]
			line += " " + string.ljust(val, vLen + 1) + "|"
		new += line + "\n"
		new += self.empty_table_line(widths)

	return new

# baut eine header-, footer- oder trennzeile
def empty_table_line(self, widths):
	s = "+"
	for width in widths:
		s += string.replace(string.ljust("", width + 2), " ", "-")
		s += "+"
	return s + "\n"[/code]

Edit: Ignore those localized comments, I’m in a rush - sorry!

0 Likes

#2

Seems lovely, how do I use this? It doesn’t show up as an option in the context or any other menu.

0 Likes

#3

i’ll find use for it too.
@kyprios1
save the command under your User folder.
and add keybinding inside your keymap file.
i placed this inside Default (OSX).sublime-keymap

{ "keys": "ctrl+alt+t"], "command": "tabularize" }
0 Likes

#4

quite good! thanks!

0 Likes

#5

Thanks vitaLee, got it working.

[size=150]Idea for the developer: **How about a reverse command? **[/size]

There may be times we need to make adjustments after the tabularization and patching the “table” borders manually could be a lot of work.
If it was possible to revert the data back to serial formatting it’d make life easier.

0 Likes

#6

Hi,

I improved the code to support Chinese characters. Thanks!

import sublime, sublime_plugin
import array, string

class TabularizeCommand(sublime_plugin.TextCommand):
   def run(self, edit):
      sels = self.view.sel()
      for sel in sels:
         if sel.empty():
            continue

         old = self.view.substr(sel)
         new = self.tabularize(old)

         edit = self.view.begin_edit();
         self.view.replace(edit, sel, new)
         self.view.end_edit(edit)

   def tabularize(self, old):
      rawRows = string.split(old, "\n")

      # validate number of columns
      colCount = string.count(rawRows[0], "|") + 1
      for row in rawRows[1:]:
         if string.count(row, "|") != colCount - 1:
            sublime.error_message("column count does not match")
            return old

      # determine split width/
      widths = ]
      for col in xrange(0, colCount):
         max = 0
         for row in rawRows:
            val = string.split(row, "|")[col].strip()
            ch_count = self.get_chs_count(val)
            vLen = len(val) + ch_count
            if vLen > max:
               max = vLen
         widths.append(max)

      new = self.empty_table_line(widths)
      
      # assemble content line by line.
      for row in rawRows:
         vals = string.split(row, "|")
         line = "|"
         for col in xrange(0, len(vals)):
            val = vals[col].strip()
            vLen = widths[col]
            ch_count = self.get_chs_count(val)
            line += " " + string.ljust(val, vLen + 1 - ch_count) + "|"
         new += line + "\n"
         new += self.empty_table_line(widths)

      return new

   # build header, footer with separation line
   def empty_table_line(self, widths):
      s = "+"
      for width in widths:
         s += string.replace(string.ljust("", width + 2), " ", "-")
         s += "+"
      return s + "\n"

   # detect the count of chs chars
   def get_chs_count(self, s):
      l = 0
      for c in s:
         if self.is_chinese(c):
            l += 1
      return l

   # determine whether a char is chs
   def is_chinese(self, uchar):
      if uchar >= u'\u4e00' and uchar<=u'\u9fa5':
         return True
      else:
         return False
0 Likes

#7

[quote=“kyprios1”]Thanks vitaLee, got it working.

[size=150]Idea for the developer: **How about a reverse command? **[/size]

There may be times we need to make adjustments after the tabularization and patching the “table” borders manually could be a lot of work.
If it was possible to revert the data back to serial formatting it’d make life easier.[/quote]

You may do a replacement with regex:
replace

((\-]|\+])+(\n)?)|(^\|)|(\|$)

with empty, then tabularize again :smile:

0 Likes