Formatted Text in PROGMEM [SOLVED]

has anyone a method for putting formatted text into PROGMEM:

// I want text in PROGMEM
const char* text = R"(
  Some formatted text here
  makes life easy for HTML
  servers, for example.
  )";

void setup() {
  Serial.begin(9600);
  Serial.print(R"(  
  Hello world! It 
  is nice to meet
  you)");
  Serial.println();
  Serial.print(text);
}

void loop() {

}

How about this:

// I want text in PROGMEM
// - multiline string needs '\' continuation character
// - \n is newline character
//
const char text[] PROGMEM = "\
  Some formatted text here\n\
  makes life easy for HTML\n\
  servers, for example.\n\
  ";

#define PMTXT(textarray) (reinterpret_cast<const __FlashStringHelper*>(textarray))

Serial.print( PMTXT(text) );

Yours,
TonyWilk

Edit: if it's HTML, just replace the \n with

TonyWilk:
How about this:

not really what I was hoping to . I'd like plain formatted text in PROGMEM.

BulldogLowell:
not really what I was hoping to . I'd like plain formatted text in PROGMEM.

Sorry, you'll have to explain exactly what you mean by 'formatted text'

Can you give an example ?

Yours,
TonyWilk

TonyWilk:
Can you give an example ?

there are two examples in my example

Just use the R macro like you did before then...

const char text[] PROGMEM = R"(
  Some formatted text here !
  makes life easy for HTML
  servers, for example.
  )";

Yours,
TonyWilk

TonyWilk:
Just use the R macro like you did before then...

const char text[] PROGMEM = R"(

Some formatted text here !
  makes life easy for HTML
  servers, for example.
  )";




Yours,
TonyWilk

Right!

I always seem to come back to that... forgetting and not using the pointer to the literal...

thanks!

BTW, I'm not sure about raw text (R" "), but the construct:

const char* const text PROGMEM = "Hello World";

Does NOT put the string into Flash only. It seem to also put the copy that's actually used into RAM (at least on an Uno-type board).

This puts it into Flash only:

const char text[] PROGMEM = "Hello World";

See my post here.

gfvalvo:
This puts it into Flash only:

const char text[] PROGMEM = "Hello World";

That's right, but then a simple Serial.print(text) does not work any more.

Whereas in my example using Serial.print(PMTXT(text)) does work.

I don't know if there is a standard macro that does the same thing as my PMTXT().

Yours,
TonyWilk

You can also cast a pointer:

const char text[] PROGMEM = "Hello World";
__FlashStringHelper *textPtr = (__FlashStringHelper *) text;

and then:

Serial.println(textPtr);

Same thing really. The __FlashStringHelper type allows selection of the correct (overloaded) version of println.

Note that the Raw string macro embeds newlines and leading spaces.

void setup() {
  Serial.begin(9600);

  Serial.println(F("Regular F macro"));

  Serial.println(F(R"( 
  Hello world! It
  is nice to meet
  you.
  )"));

  Serial.println(F(
  R"(Some formatted text here
  makes life easy for HTML
  servers, for example.
  Unlimited quantity of anonymous strings.
  )"));

  Serial.println(F("David Prentice"));
}

void loop() {

}

I suggest that you choose the style that is most convenient for you to maintain HTML text.

But combining the F() and R"() macros keeps your anonymous text safely in Flash.

David.

david_prentice:
Note that the Raw string macro embeds newlines and leading spaces.

exactly the reason to use them.

david_prentice:
Note that the Raw string macro embeds newlines and leading spaces.

BulldogLowell:
exactly the reason to use them.

Just dawned on me...

Having newlines embedded might not make much sense for HTML content (unless it's

)
but IF you meant to use the formatted text for protocol strings, you should explicitly end lines with "\r\n"

Note: HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all protocol elements

Using the Arduino IDE editor, the lines will only be terminated by LF.
(this will be editor-dependent)

Yours,
TonyWilk

BulldogLowell:
exactly the reason to use them.

And the wrb browser will happily strip them off :slight_smile:

sterretje:
And the wrb browser will happily strip them off :slight_smile:

guys, it was just an example of formatted text, you're running off the reservation here.

so F (R (" is the solution?

Juraj:
so F (R (" is the solution?

Depends. The 'F' macro can't be used outside of a function (i.e. global land). So, it works fine a print statement. But, if you want to print that same Flash string from more than one place, you need a pointer to a __FlashStringHelper object. Here's two ways I found to do it:

const char text1[] PROGMEM = R"(   // can't use 'F' macro here
  Some formatted text here !
  makes life easy for HTML
  servers, for example.
  )";

__FlashStringHelper *textPtr1 = (__FlashStringHelper *) text1;

__FlashStringHelper *textPtr2;

void setup() {
  Serial.begin(9600);
  textPtr2 = F(R"(           // can use 'F' macro inside a function
  Some formatted text here !
  makes life easy for HTML
  servers, for example.
  )");
}

void loop() {
  Serial.println(textPtr1);
  Serial.println(textPtr2);
  delay(5000);
}