Minecraft – Written books from command blocks not working

minecraft-commandsminecraft-java-edition

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.

Best Answer

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'\" }"]