How to Count Line Feeds

edited July 2015 in Programming Questions

Here is what I need to fix:

String fact = "blah blah blah blah blah blah blah blah blah blah blah blah"; String[] flines; text(fact, 500, 315, 440, 140); flines = split(fact, "\n"); println(flines.length);

How can I count the number of line feeds in my string?

Answers

  • Your example string doesn't contain any line breaks; so this question at first appears confusing. Perhaps the problem is that whatever String you're really trying to process doesn't contain \n but instead contains \r. This appears to be a common problem.

    Since different systems define line breaks in different ways you have to check for both types. The accepted answer on the above link gives a solution for Java's split() method. I expect you can do something similar using Processing's splitTokens. Untested but perhaps this will work (not sure if you have to escape the backslash as in pure Java):

    splitTokens(fact, "\n\r");
    
  • edited July 2015

    Sorry, this doesn't work. For some reason, it always prints that there's only one line. :( To specify, the string has x and y boundaries, so I don't know at what point to put the split().

  • _vk_vk
    edited July 2015

    I think you have 'spaces' not line breaks. Not '\n' nor '\r', but' '.

    Anyway, Processing has this handy constant: WHITESPACE.

    Also as @blindfish said splitTokens. check the link he posted.

    try this:

    String fact = "blah blah blah blah blah blah blah blah blah blah blah blah"; 
    String[] flines; 
    text(fact, 500, 315, 440, 140); 
    flines = splitTokens(fact, WHITESPACE); 
    println(flines.length);
    
  • edited July 2015

    Just an extra trick: splitTokens() already take care for any char considered WHITESPACE by default:
    https://Processing.org/reference/splitTokens_.html

    So flines = splitTokens(fact); is enough! ;)

  • Text with 5 params makes line breaks.

    But it never tells us where

    It is a blackbox

  • So although the string doesn't have any returns in it, it automatically returns because of the x boundary. I'm trying to count the automatic returns.

  • _vk_vk
    edited July 2015

    You can then calc them manually... I've made an attempt to make a twitter text box.

    This here, is not the complete code ( won't compile as it is), just the part splitting and creating lines. There is a lot more as I was working to make links and mention clickable.

    Also there is a lot of code to deal with words bigger than the box width, if you are creating the words, you don't need this.

    Although they are very commented and should be easy to follow, I hope.

    disclosure: I don't really know what I'm doing... :)

    /**__________________________| ++++  PARSE TWEET TEXT  ++++ |_______________________________**/
      /**|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||**/
      /**VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV**/
    
      // Here We will split each word in an object(not yet), TO DO !
      // Each word obj will have a position and eventually links.
      // Twitter provides indexes of the words that are to be linked
      // To provide mousse integration at the word level, I have to split and rebuild.
    
      void parseTwText() {
    
    
        // create words  array
        words = split(rawText, splitter);
    
        // create Array list of lines and create line1
        // each Line it self is an ArrayList os strings (words obj should be) TO DO!!
        lines = new ArrayList<ArrayList<String>>();
        lines.add(new ArrayList<String>()); 
    
    
    
        // add spaces to the end of words so they get counted in width calculated indexes
        // now each word BUT THE LAST have an space after it
        for (int i = 0; i < words.length; i++) 
        {  
          // font and size are crucial to calcualtions even not drawing  !! TO DO !! << humm here???
          textFont(font, fontSize);
    
          // condition is to don't add to space to last word  
          if (i < words.length -1) {      
            String spacedWord  = words[i] + " ";    
            words[i] = spacedWord;
          }
        }
    
    
    
        // Care for words bigger than lineMax, spliting them at lineMax without adding space
        // who the fuck would write this shit : - )
        while (areThereBigWords (words))
        {
    
          // check each word
          for (int i = 0; i < words.length; i++) 
          { 
            // the word to char array
            char[] bigWord = words[i].toCharArray();
    
            //to hold split position
            int lastIndex = 0;
    
            // builder 
            StringBuilder toMesure = new StringBuilder();
    
            // walk the big word char array adding each char at a time to builder
            // after each adition check to see if is already bigger than limit
            for (int inLoopIterator = 0; inLoopIterator < bigWord.length; inLoopIterator++)
            {   
              // test to keep it in linemax size i'm adding one more char to test to assure some buffer space
              // but it stays out of the line displayed to ensure stay in boundaries. unless it is the last char of text.
              float nextCharWidth = textWidth(bigWord[min( bigWord.length - 1, inLoopIterator + 1)]);
    
    
              //do mesure and conditionally add
              // else is sign that a line is full
              if (textWidth (toMesure.toString ()) + nextCharWidth   <  lineMax )
              {
                toMesure.append(bigWord[inLoopIterator]);
                lastIndex = inLoopIterator;
              } else // one line is full..
              {
                // holds this piece of word[i] that is also this line as a String
                String newWord = toMesure.toString();
                //println("newWord is " + newWord);
    
                // i is outside words array index not the  "inLoopIterator"!
                // get reminder of the big word to work with in next pass
                // last index will contain the last char +1 index of original word
                String remainderWord =  words[i].substring(lastIndex, words[i].length());
                //println(lastIndex + "   " + words[i].length());
    
                //overwrite the newlly formed word (big as a line) back to words array
                // this is overwriting the original word in words array
                // like: 1234567890abcdefghijklmn is the original word at index [3]
                // 1234567890abcdef fitted in one line aka newWord
                // ghijklmn is the remainder
                // insert 1234567890abcdef in words[3]
                words[i] = newWord;
    
                // creates a new word in words array to be checked for fittnes
                // splice it at proper position
                // ghijklm is inserted at 4 shifting everything else   
                words = splice(words, remainderWord, i+1);
    
    
                //println(words);
                lineLength = x + LEFTMARGIN;
                i= 0; 
                break;
              }
            }
          }
        }// end of while
    
    
    
        // ok done with bigger than line words, let's get back to the positioning and linking stuff
        // so far we have words[] that holds the text splited in words that are samller than line size
    
        //join words[] in Lines
        for (int i = 0; i < words.length; i++) 
        {  
          // if line still fitting in the box..
          // else creates a new line
          if (lineLength + textWidth(words[i]) < lineMax)
          {
    
            //add to line arraylist and add to line length
            lines.get(workingLine).add(words[i]);
            lineLength += textWidth(words[i]);
            //println("line "+ workingLine);
            //println(lines.get(workingLine).toArray());
          } else 
          {   // add a new line
            lines.add( new ArrayList<String>());  
    
            // hold this as the line to fill up
            workingLine++;
    
            // reset (line length)
            lineLength = x + LEFTMARGIN;
    
            // add words[i], the word was being mesured and did not fit to the beggining of this new line.
            // and count it in line length just reseted
            //
            lines.get(workingLine).add(words[i]);
            lineLength = lineLength + textWidth(words[i]);
          }
          //}
        }
        /**^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^**/
    
        // So far we have an arrayList of arrays of words representing the the lines of the text
    
    boolean areThereBigWords(String[] words) 
      {
        for (String word : words) 
        {
          if (textWidth(word) > lineMax)
          {
            return true;
          }
        }
        return false;
      }
    
  • edited July 2015

    Guys, thanks for all the help, but it still doesn't work. I need to know how to count the automatic line breaks in my string.

Sign In or Register to comment.