4
$\begingroup$

Suppose I have a very long string

x=2*g*o*p*s*v-2*B*g*o*p*s*v*w+2*a*c*g*m*o*p*s*v+2*c*g*m*o*p*s*v*B-2*a*c*g*m*o*p*s*v*B+3*g*m*o*p*s*v*B-3*B*g*m*o*p*s*v*w*B+m*w**2*B +5*a*c*g*m**2 +o*p*s*v*B -a*c*m**2*w**2*B +c*g*m**2*o*p*s*v*B* - 3*a*c*g*m*o*p*s*v*+c*m**2-w**2*B-a*c*m**2-w**2*B....)

etc that goes on for almost 1000 lines. When exported to a .txt file, the file is >100MB. I want to use the expression in Fortan and Fortan will not accept lines greater than 100 characters or so.

To the string x, is it possible to insert a linebreak every 100 characters and insert && at the end of each line and at the beginning of the next line?

$\endgroup$
9
  • 3
    $\begingroup$ StringInsert[str, "&&\n&&", #] &@Range[100, StringLength@str, 100] $\endgroup$
    – Öskå
    Mar 10, 2014 at 16:51
  • 1
    $\begingroup$ @Öskå Why, in the name of God, why do you not put that up as an answer? It really does not require any more elaboration than an intro line to make up for the minimum amount of characters. This is a perfectly acceptable solution! $\endgroup$ Mar 10, 2014 at 17:05
  • 1
    $\begingroup$ @IstvánZachar Because it's in the documentation and can easily be found? I don't know :( $\endgroup$
    – Öskå
    Mar 10, 2014 at 17:10
  • 1
    $\begingroup$ @Öskå Thanks and pardon me for my zeal! Do not forget: each reputation point brings you closer to the 3K privilege of voting to close as "answer can be easily found in the documentation". It's worth fighting for! :) $\endgroup$ Mar 10, 2014 at 18:55
  • $\begingroup$ @IstvánZachar My answering rate is so low that I plan to reach the 3K in about 2 years B-) $\endgroup$
    – Öskå
    Mar 10, 2014 at 18:59

3 Answers 3

5
$\begingroup$
x = "2*g*o*p*s*v-2*B*g*o*p*s*v*w+2*a*c*g*m*o*p*s*v+2*c*g*m*o*p*s*v*B-2*a*c*g
     *m*o*p*s*v*B+3*g*m*o*p*s*v*B-3*B*g*m*o*p*s*v*w*B+m*w**2*B+5*a*c*g*m**2+o
     *p*s*v*B-a*c*m**2*w**2*B+c*g*m**2*o*p*s*v*B*-3*a*c*g*m*o*p*s*v*+c*m**2-w**2
     *B-a*c*m**2-w**2*B....)"

StringInsert[x, "&&\n&&", #] &@Range[100, StringLength@x, 100]

giving you what you want.

$\endgroup$
3
  • 2
    $\begingroup$ Take my +1 and conquer 1k ... now! $\endgroup$
    – Yves Klett
    Mar 10, 2014 at 20:16
  • 1
    $\begingroup$ @YvesKlett: I see your +1 and raise you +1... good of you to prompt this as a proper answer! $\endgroup$
    – ciao
    Mar 10, 2014 at 22:52
  • $\begingroup$ @YvesKlett thank you thank you :D Too many upvotes for today, I'm not used to it :D $\endgroup$
    – Öskå
    Mar 10, 2014 at 22:56
3
$\begingroup$

An adaptation from the documentation for PageWidth. It has the advantage of breaking between words, so you don't accidentally split a symbol name.

SeedRandom[1];
expression = 
 RandomInteger[{1, 3}, Length@#].ToExpression[#] &@ CharacterRange["a", "k"]
(*
  2 a + b + 2 c + 2 d + e + f + g + 2 h + i + j + k
*)

string = "x = " <> ToString@FortranForm[Expand[expression^3]];

file1 = $TemporaryPrefix <> "test1.txt";
stream = OpenWrite[file1, PageWidth -> 80];
Write[stream, TraditionalForm@string];
Close[stream];

StringReplace[Import[file1], "\\\n" -> "&&\n&&"]
(*
  x = 8*a**3 + 12*a**2*b + 6*a*b**2 + b**3 + 24*a**2*c + 24*a*b*c + 6*b**2*c + &&
  &&24*a*c**2 + 12*b*c**2 + 8*c**3 + 24*a**2*d + 24*a*b*d + 6*b**2*d + 48*a*c*d + &&
  &&24*b*c*d + 24*c**2*d + 24*a*d**2 + 12*b*d**2 + 24*c*d**2 + 8*d**3 + 12*a**2*e + &&
  ...
*)

For some reason, using FortranForm as the output format does not produce the OP's desired formatting. (I don't know Fortran.) Otherwise, one might be able to use

stream = OpenWrite[file1, PageWidth -> 80, FormatType -> FortranForm];
$\endgroup$
4
  • 1
    $\begingroup$ I just checked the double &'s are not legal, should be: "&\n" or "&\n&". Fortran would not mind if you broke in the middle of a symbol name by the way, but it is much more readable if you avoid it. $\endgroup$
    – george2079
    Mar 14, 2014 at 21:35
  • $\begingroup$ @george2079 Thanks. I would change it, but the OP asked for &&. FortranForm puts several spaces, followed by a hyphen -, followed by more spaces at the beginning of the line. No & at the end of the lines. That looks wrong to me, based on what I skimmed from the web. $\endgroup$
    – Michael E2
    Mar 14, 2014 at 21:41
  • $\begingroup$ FortranForm is giving you old f77 format : nothing at the end of the line then 5 spaces and "any" character in the 6th col. An ampersand is a better choice than a hyphen IMO.. "\n &" $\endgroup$
    – george2079
    Mar 14, 2014 at 21:49
  • $\begingroup$ @george2079 Yes, my mistake it should be a single &. $\endgroup$ Mar 27, 2014 at 15:51
2
$\begingroup$

Another solution but could be slower for such a big string. Worth to try:

StringJoin @@ Riffle[Characters@longstring, "&&\n&&", 100]
$\endgroup$
3
  • 1
    $\begingroup$ Actually quite a bit faster... $\endgroup$
    – ciao
    Mar 10, 2014 at 23:38
  • $\begingroup$ @rasher Have not checked :) good to know :) $\endgroup$
    – Kuba
    Mar 11, 2014 at 6:04
  • 1
    $\begingroup$ rasher is right; this is magnitudes faster than StringInsert. FYI: there is no need to Apply StringJoin because it natively works on lists. Using StringJoin @ Riffle[. . . is 30% faster here. $\endgroup$
    – Mr.Wizard
    Mar 16, 2014 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.