1

When I enter the command:

/give @a minecraft:written_book 1 0 {title:a,author:a,pages:["Hello world!\n1234567890","\"Hello\"\n\\Test q"]}`

The books everyone get should have two pages, the first one being:

Hello world!
1234567890

and the second one being:

"Hello!"
\Test q

But instead both pages just say:

Hello

What's going on and how can I fix it? I'm using MC 1.11.2.

2 Answers 2

0

If you want to use newlines in the pages (or any other formatting for that matter), the page text needs to be a json object with a text tag.

Building this require that you 'escape' some symbols:

  • double quotes " by adding and backslash before them: \"
  • backslash \ by adding another backslash before it: \\
  • replacing linebreaks with \n

For example if you want the literal string:

Hello world
embedded back\slash
"quoted" string

You need to turn it into this json object:

{ text: "Hello world\nembedded back\\slash\n\"quoted\" string" }

Then, to embed this in the pages array, you need to treat the whole json object as string and escape it once again using the same rules:

pages:["{ text: \"Hello world\\nembedded back\\\\slash\\n\\\"quoted\\\" string\" }", ...]

Notice how in \" we need to escape both the backslash and the double quote so the slash becomes \\ and the double quote becomes \" and the whole \" becomes \\\". Notice also how for the embedded backslash we need to escape each of the two backslashes \\ individually, so they become four \\\\

Armed with that knowledge, your two pages:

Hello world!
1234567890

and

"Hello!"
\Test q

become as json tags:

{ text: "Hello world!\n1234567890" }
{ text: "\"Hello!\"\n\\Test q" }

and then embedding this in the pages array and escaping once again:

pages: ["{ text: \"Hello world!\\n1234567890\" }",
        "{ text: \"\\\"Hello!\\\"\\n\\\\Test q\" }"]

The whole command:

/give @a minecraft:written_book 1 0 {title:a,author:a,pages: ["{ text: \"Hello world!\\n1234567890\" }", "{ text: \"\\\"Hello!\\\"\\n\\\\Test q\" }"]}

Also, there is a little trick that can simplify handling of quotes (it still works on 1.11.2 but is destined to be removed in future versions: source) - the inner json object can use single quotes for the text tag and then you don't need to escape the double quotes!

For example your second page

"Hello!"
\Test q

can be embedded in json like so:

{ text: '"Hello!"\n\\Test q' }

Notice how the double quotes are not escaped, only the backslash is. this means when putting it in the pages array we need to escape less things:

pages: [..., "{ text: '\"Hello!\"\\n\\\\Test q' }"]

But with this method, if you have single quotes inside the string it becomes worse:

ain't doin' nuthin'

{ text: 'ain\'t doin\' nuthin\'' }

pages: ["{ text: 'ain\\'t doin\\' nuthin\\'' }"]

vs

pages: ["{ text: \"ain't doin' nuthin'\" }"]
3
  • As of 1.9, lenient JSON is no longer supported. Doubles quotes must be applied to all keys and string values; single quotes will not suffice.
    – Skylinerw
    Dec 30, 2016 at 15:40
  • This is true for the command itself, i.e. you can't use single quotes in pages: ['...'], but you can still use single quotes in the inner string - all of the above examples are working on 1.11.2.
    – Kcats
    Jan 1, 2017 at 17:04
  • pages:['...'] is NBT, not JSON, and has a completely different parser. While technically the JSON input for pages strings is currently lenient, that does not mean it's supported. It will not be that way in the future so you should not be relying on it. Source.
    – Skylinerw
    Jan 1, 2017 at 22:26
0

It's essentially done by stringifying your strings:

  • Open with "\"
  • Close with \""
  • \" becomes \\\"
  • \n stays as \n (\\\n is a literal \n in the book)
  • \\ becomes \\\\

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .