tags:

views:

320

answers:

2

I have an two dimension array that contains strings and want to create a LaTeX table with them. The problem is that they could be longer and there has to be line breakes after 15 characters. The

Say it's a 2x2 array with contains {{"String11.......String11", "String21"}, {"String12.......String12.......String12.......", "String22......String22......"}} then the result should look like:

\begin{tabular}{cc}
String11.......& String21//
String11       &//
\hline
String12.......&String22......//
String12.......&String22......//
String12.......&  
\end{tabular}

Is there a smart way to do such conversion in Java?

+1  A: 

I have to admit this solution looks ugly to me. I think there are lots of languages where this task could have been done with far less code and blundering around. I suspect it would come to about 10 lines in Perl, or 2 lines in J. Still, here's the best I was able to come up with:

import java.util.ArrayList;
import java.util.List;

public class Christian {

   private static final int COLUMNS = 2, CELL_WIDTH = 15;

   private static final String[][] array = {
      {"I have an two dimension array that contains strings and want to create a LaTeX table with them. T",
       "roblem is that they could be longer and there has to be line breakes after 15 characters. Th"},
       {"Say it's a 2x2 array with contains {{'String11.......String11', 'String21'}",
          "{'String12.......String12.......String12.......', 'String22......String22......'}} then the result should look like"}
       };

   public static void main(String[] args) {
      ArrayList<String> lines = new ArrayList<String>();
      lines.add("\\begin{tabular}{cc}");
      for (String[] row : array) {
         lines.addAll(convertRow(row));
         lines.add("\\hline");
      }
      lines.remove(lines.size() - 1);
      lines.add("\\end{tabular}");
      for (String line : lines) {
         System.out.println(line);
      }
   }

   private static List<String> convertRow(String[] row) {
      ArrayList<ArrayList<String>> rearranged = new ArrayList<ArrayList<String>>();
      int deepest = 0;
      for (int col=0; col<row.length; col++) {
         boolean last = (col == row.length - 1);
         String marker = (last) ? "//" : "&";
         String text = row[col];
         ArrayList<String> cell = new ArrayList<String>();
         for (int z=0; z<text.length(); z+=15) {
            String cc = (z+CELL_WIDTH < text.length()) ? text.substring(z, z+CELL_WIDTH) : text.substring(z);
            cell.add(cc + marker);
            deepest = Math.max(deepest, cell.size());
         }
         rearranged.add(cell);
      }
      for (int col=0; col<row.length; col++) {
         ArrayList<String> cell = rearranged.get(col);
         boolean last = (col == row.length - 1);
         String marker = (last) ? "//" : "&";
         while (cell.size() < deepest) cell.add(marker);
      }
      ArrayList<String> lines = new ArrayList<String>();
      for (int line=0; line<deepest; line++) {
         StringBuilder sb = new StringBuilder();
         for (int col=0; col<row.length; col++) {
            sb.append(rearranged.get(col).get(line));
         }
         boolean last = (line == deepest - 1);
         if (last) sb.delete(sb.length() - 2, sb.length());
         lines.add(sb.toString());
      }
      return lines;
   }

}
Carl Smotricz
+3  A: 

The quickest way is to just set up 15em text wrapping in your table's cells, which is probably the solution you're ultimately looking for:

\begin{tabular}{p{15em} p{15em}}
String11 & String21 \\
\hline
String12 & String22 \\
\end{tabular}
Alternatively, you could probably find a way to make something like this work:
// regex to place a new line delimiter (eg. \newline) after every 15 characters
string11.replaceAll(".{15}", "$0" + someNewLineDelimiter);
Doing some Google searches on the subject, I see that \newline within a LaTeX table doesn't work as easily as we might want it to, but you should be able to find something that works. The alternative of spanning a string across multiple rows seems like a poor solution.

Gunslinger47