Convertor PRO — Manual
Complete reference for Convertor PRO: every encoding field, every data-format mode, the libraries used, and all the limits of each conversion.
Back to the overview: Convertor PRO · Open the live tool: www.jpkc.com/tools/convertor/
This manual describes Convertor PRO in full: both tabs, every input field, every mode, the libraries used, and the limits of each conversion. Field, button, and option names are given exactly as they appear in the tool's interface, so you can find your way around the real UI.
Convertor PRO is split into two tabs: Encoding (character and encoding conversion) and Data Formats (conversion between JSON, YAML, TOML, XML, and INI). Both run entirely in the browser — there is no server call, no API, no upload, and your input is not stored anywhere.
Tab 1: Encoding
The core principle matters: there is one central pivot — the actual characters (the Characters field) — surrounded by twelve more fields, each of which is a different textual representation of those characters, plus the catch-all Mixed input field. The conversion works on whole Unicode code points: an emoji like 😀 is one unit, even though JavaScript stores it internally as two UTF-16 code units.
How it works: Convert fills everything
Each field has its own Convert button and a copy button. You don't actually have to press the button, though: as soon as you type in a field, its content is decoded to actual characters 200 milliseconds after your last keystroke, and all other fields are recomputed from those characters. Convert does the same immediately. So if you type é into Characters, the other fields show é, %C3%A9, U+00E9, C3 A9, and so on. Conversely, if you type é into Hexadecimal NCRs, é appears in Characters and everything else fills in too.
Conversion therefore works in both directions, always through the characters as the common center — and it is lossless: every notation converts back to exactly your original text, character for character, even with spaces, digits right after a notation, or text that happens to look like U+… itself. Two cases are the exception: the Bidi to markup option in the HTML/XML field is a one-way street — the markup it produces does not turn back into control characters when decoded. And the null character U+0000 cannot be represented in CSS escapes, in HTML/XML with Escape invisibles, or in the NCR fields when neither Keep ASCII nor Keep Latin-1 is on. In HTML/XML, a reference like � stands for U+FFFD under HTML rules, and CSS escapes writes NUL straight away as \FFFD .
Further details:
- Convert on an empty field reports "Please enter text to convert."; the copy button on an empty field reports "Nothing to copy."
- When you change an option (checkbox or dropdown), all fields are recomputed from the content of Characters. The exception is Decode \n, \t, \xHH: this checkbox re-decodes the content of Mixed input — and does nothing while that field is empty.
- Notice line: only Percent encoding (URIs), Hex code points, Decimal code points, UTF-8 code units, and UTF-16 code units report decoding problems in a line beneath the field — "Not understood: …" with the first five unrecognized tokens, or "Invalid UTF-8 byte sequence — shown as U+FFFD (�)." for broken UTF-8 bytes. The other fields have no notice line: there, invalid values either stay as text (
U+110000, an unknown entity like&foo;) or become U+FFFD (�) without a message (�). The same goes for Mixed input: anything it doesn't recognize stays there as text, and invalid percent or UTF-8 byte sequences show up as U+FFFD (�) without a message. - On narrow screens (below 992 pixels wide), the fields are stacked instead of sitting side by side in pairs.
Keep ASCII and Keep Latin-1 options
Four fields — Hexadecimal NCRs, Decimal NCRs, Unicode U+hex, and 0x... notation — have two checkboxes, Keep ASCII and Keep Latin-1. They control which characters get converted into the notation at all:
- Keep ASCII (default: on) — ASCII characters (U+0000–U+007F) are left as they are; only everything above is converted.
- Keep Latin-1 — the Latin-1 range (up to U+00FF, so including
ä,ö,ü,ß,é) is left alone as well. Latin-1 includes ASCII; with this box ticked, Keep ASCII makes no difference. - With neither, every character is converted.
One exception keeps the result unambiguous: if a kept character would merge with the notation in front of it — a hex digit (0–9, A–F, a–f) or a space directly after U+00DC or 0xDC — the tool writes that character as a notation too. That is why Über with Keep ASCII turns into U+00DC U+0062 U+0065r in Unicode U+hex, but into Über in Hexadecimal NCRs, where the semicolon closes the reference cleanly. The same applies to kept text that itself starts like a notation.
The Hex code points and Decimal code points fields do not have these options — in a pure list of numbers, a leftover letter would be ambiguous.
Mixed input
The topmost field, Mixed input, is a catch-all: you may throw in mixed escapes of different notations together, and the tool resolves them to characters in a single pass. Text that has already been decoded is not read again: & becomes &, not &. It recognizes:
U+00E9and0xE9(1 to 6 hex digits),- numeric references
éandé, plus named entities with a semicolon (ü,—, …), - JavaScript escapes
\u00E9,\u{1F600}, and\U0001F600, - percent sequences such as
%C3%BC(read as UTF-8).
The Decode \n, \t, \xHH checkbox (default: off) decides how a backslash is read:
- on — instead of CSS escapes,
\xHHand the short escapes\b,\f,\n,\r,\t,\v,\0,\',\", and\\are decoded as in JavaScript;\E9then stays as it is. - off — a backslash followed by 1 to 6 hex digits counts as a CSS escape (
\E9→é); everything else is left alone. One exception: a\b,\f, or\0followed by neither another hex digit nor whitespace is read as in JavaScript, as backspace, form feed, or NUL. That way a Windows path likeC:\tempsurvives unchanged — with the option on, it would contain a tab character. But only as long as no path segment after a backslash starts with0–9ora–f: inC:\data\file,\dabecomesÚas a CSS escape and\fa form feed.
The field's buttons:
- Convert — resolves the recognized notations (this also happens live as you type).
- Hex CP, Dec CP, UTF-8, UTF-16 — additionally decode bare number sequences in the remaining text: hexadecimal code points (1 to 6 digits), decimal code points (1 to 7 digits), UTF-8 bytes (two hex digits each), or UTF-16 code units (four hex digits each), separated by spaces or commas. With Hex CP,
Code: 48 65 6C 6C 6FbecomesCode: Hello; with UTF-8,C3 BC 20 E2 82 ACbecomesü €. Numbers attached to letters or digits are left untouched — socafédoes not accidentally turn into U+0CAF.
The result lands in Characters and from there in every other field. Mixed input is the all-rounder for "I have some escaped mess here and want the plain text."
HTML/XML
HTML/XML field: text as it may appear in HTML or XML markup. When generating from characters, &, <, >, and " always become &, <, >, and "; everything else stays readable. There are two options:
- Escape invisibles (default: on) — writes invisible or easily confused characters as
&#x…;so they don't vanish without a trace in the markup: control characters (except tab, line feed, and carriage return), the non-breaking space and every other special space except the regular space, the soft hyphen, zero-width characters, directional marks, variation selectors, the BOM, and tag characters. - Bidi to markup — replaces bidi control characters with markup: embeddings (LRE/RLE) with
<span dir="ltr|rtl">, overrides (LRO/RLO) with<bdo dir="…">, isolates (LRI/RLI/FSI) with<bdi>; PDF and PDI close the respective element, and any element still open at the end is closed by the tool. The directional marks LRM/RLM become‎and‏.
When decoding, the field understands numeric references (hexadecimal and decimal) and all 2125 named HTML5 entities — resolved by your browser's HTML parser, including the legacy forms without a semicolon such as ©. �, surrogates, and values above U+10FFFF become the replacement character U+FFFD, as in the HTML standard. The tool deliberately reads € through Ÿ as the C1 control characters they are in Unicode — not as the Windows-1252 characters such as € that a browser renders them as.
Percent encoding (URIs)
Percent encoding (URIs) field: the %XX notation for URLs. Every character except A–Z, a–z, 0–9, -, ., _, and ~ is percent-encoded as UTF-8 bytes — ü becomes %C3%BC, a space becomes %20, and /, ?, and & are encoded too. In the other direction, the field decodes %XX sequences as UTF-8; a % not followed by two hex digits is left alone. If the bytes are not valid UTF-8, U+FFFD (�) appears, plus a notice below the field.
Hexadecimal NCRs / Decimal NCRs
Two fields for Numeric Character References as HTML and XML know them:
- Hexadecimal NCRs — form
&#xHHHH;with at least four hex digits (é,😀for 😀). - Decimal NCRs — form
&#NNNN;(é,😀).
Both have the Keep ASCII and Keep Latin-1 options. When decoding, both fields read hexadecimal and decimal references, and the semicolon is optional; �, surrogates, and values above U+10FFFF become U+FFFD. NCRs work in any HTML and XML context and are the most robust way to write an arbitrary character into markup.
Unicode U+hex / 0x… notation
Two fields for code-point notations as they appear in specs and source code:
- Unicode U+hex — the standard notation with at least four hex digits:
U+00E9,U+1F600. - 0x... notation — the
0xstyle without leading zeros (0xE9,0x1F600), as many programming languages use it for hex literals.
Consecutive notations are separated by a space, which the decoder removes again; a real space right after a notation (or when neither Keep ASCII nor Keep Latin-1 is on) appears as U+0020 or 0x20. Decoding reads 1 to 6 hex digits. Both fields have Keep ASCII and Keep Latin-1.
Hex code points / Decimal code points
The bare code-point values without a prefix, separated by spaces:
- Hex code points — hexadecimal with at least four digits (
00E9 1F600). - Decimal code points — the same values in decimal (
233 128512).
The decoder is forgiving: separators may be spaces, commas, or semicolons, and the hex field also accepts values prefixed with U+, 0x, \u, \u{…}, \x, or &#x (the decimal field accepts &#). Tokens that aren't numbers stay in place as text and are named in the notice line; values above U+10FFFF become U+FFFD and are reported as well. Handy when you take code points from a table or a program, or hand them on to one.
UTF-8 code units / UTF-16 code units
The actual encoding bytes or code units:
- UTF-8 code units — the UTF-8 byte sequence, two hex digits per byte (
é→C3 A9,😀→F0 9F 98 80). - UTF-16 code units — the UTF-16 code units with four digits each, including surrogate pairs for characters beyond the Basic Multilingual Plane (
😀→D83D DE00).
When decoding, the UTF-8 field also accepts the bytes run together (C3A9) or prefixed with 0x, \x, or %; invalid byte sequences become U+FFFD plus a notice. The UTF-16 field reports values above FFFF. Here you see how a character is really stored at the byte level — important when debugging encoding problems.
JavaScript escapes / CSS escapes
Two fields for the escape syntax of two specific languages:
- JavaScript escapes — printable ASCII stays as it is;
\b,\t,\n,\v,\f,\r,\",\', and\\appear in short form, NUL as\0(as\x00before a digit), other control characters as\xHH, and everything from U+0080 to U+FFFF as\uXXXX. For characters above U+FFFF, the Above U+FFFF dropdown picks the notation:\uD83D\uDE00 (pair)— the surrogate pair, the default and valid everywhere —,\u{1F600} (ES6), or\U0001F600 (C, Python). When decoding, the field understands the full JavaScript escape grammar including\u{…},\xHH, and line continuations, plus the C/Python form\UXXXXXXXX. - CSS escapes — backslash,
", and'get a backslash in front, printable ASCII stays as it is, and everything else becomes\HEXfollowed by a space (é→\E9). The space terminates the escape and is swallowed by the CSS parser — so copy it along. When decoding, the field reads 1 to 6 hex digits plus optional whitespace after them; invalid values become U+FFFD.
Tab 2: Data Formats
The second tab converts between JSON, YAML, TOML, XML, and INI. The interaction model is source → target: you enter data on the left, pick a target format on the right — and the output appears while you type.
Layout and controls
On the left, the Source panel with a format selector (Auto-detect by default, plus JSON, YAML, TOML, XML, INI); on the right, the Output panel with its own selector (YAML, JSON, TOML, XML, INI; default JSON). With the source on Auto-detect, a badge next to the selector shows the detected format — or a red "unknown" when no parser accepts the input. Both panels are syntax-highlighting ACE editors (theme "Dracula", word wrap on, two-space indentation); the Output field is read-only. A line above the editors reminds you that everything runs in your browser.
The buttons are icons only; their names appear as tooltips. In the Source panel:
- Paste from clipboard — reads the clipboard (your browser may ask for permission) and puts the content in as the source. If that fails, the tool reports "Failed to read clipboard. Please paste manually." — then paste straight into the editor with Ctrl+V or Cmd+V.
- Open file — loads a local file (
.json,.yaml,.yml,.toml,.xml,.htm,.html,.ini,.cfg,.conf). For.json,.yaml/.yml,.toml,.xml, and.ini, the extension sets the source format; for.htm/.html,.cfg, and.confthe selector switches to Auto-detect, because those extensions say nothing definite. - Clear — empties source, output, and the messages.
In the Output panel: Copy to clipboard and Save as file — the download is named converted.json, converted.yaml, converted.toml, converted.xml, or converted.ini. With an empty output they report "Nothing to copy." and "Nothing to save." respectively.
Below the editors:
- Convert — converts immediately and confirms the result with a short message.
- Swap — the output becomes the new source, the former target format becomes the source format, and the source format actually used (including an auto-detected one) becomes the new target.
Live conversion
Every change in the Source editor triggers a conversion 350 milliseconds after your last keystroke; switching the source or target format converts immediately. Above 400,000 characters of input, live conversion switches off — then you convert with Convert, so the browser doesn't stutter while you type.
How conversion works
Every conversion runs in two steps through a shared intermediate stage: the source format is parsed into an object tree, and that tree is serialized into the target format. That is why any direction between the five formats is possible — there are no fixed pairs, but five parsers and five serializers around one common center.
Building blocks used:
- JSON — the lossless-json (opens in a new tab) library for reading (duplicate keys with different values count as an error; a duplicate with the same value is accepted without a message); output with two-space indentation.
- YAML — the js-yaml (opens in a new tab) library (
load/dump, indent 2, no automatic line wrapping, no anchors/references — nodes used more than once are written out in full). - TOML — the smol-toml (opens in a new tab) library, a complete TOML 1.0 parser and serializer; invalid TOML is rejected with a line number.
- XML — the browser's
DOMParserfor reading, a custom serializer for writing. - INI — a custom parser and serializer.
Exact numbers
When the tool reads JSON, large integers beyond 2^53 (such as 20-digit IDs) and whole-number floats like 1.0 do not travel through the conversion as JavaScript numbers but as a digit-exact string of characters. 12345678901234567890 stays exactly that in JSON, YAML, XML, and INI instead of turning into 12345678901234567000, and 1.0 stays 1.0 instead of 1. The exception is INI: lists that INI writes as a JSON string (see Errors and notices) contain such numbers as JavaScript numbers again — [[1.0, 12345678901234567890]] becomes [[1,12345678901234567000]]. TOML only knows 64-bit integers: larger values are written there as strings, with a notice.
This protection depends on the source format:
- JSON: as described. Other floats, however, are read as JavaScript numbers, so a trailing zero as in
1.10is dropped (1.1). - TOML: integers up to 64 bits stay exact, floats are read as JavaScript numbers —
1.0becomes1, even for TOML → TOML. - YAML: every number is read as a JavaScript number. Large integers lose their last digits,
1.0becomes1. - XML and INI: such values stay strings (see Limits and edge cases), so the digits are kept.
None of these losses — 1.10 from JSON, numbers from YAML and TOML, numbers in INI's JSON strings — comes with a notice of its own. Date and time values from TOML keep their form (local date, local time, or timestamp with offset) and are written as ISO strings in the other formats, likewise without a notice.
Automatic format detection
Auto-detect doesn't guess from patterns; it test-parses the input — strict formats first:
- If the text starts with
<, it counts as XML. - If it starts with
{or[and is valid JSON: JSON. - If it reads as TOML (with at least one key): TOML.
- If it yields an object or a list as YAML (not just a single value): YAML.
- If it reads as INI: INI.
- If it is otherwise valid JSON of any shape, such as a single value like
42or"text": JSON.
So a = 1 is TOML, [server] with host = localhost is INI (unquoted strings are invalid in TOML), and name: x is YAML. If nothing fits, the tool reports "The format was not recognized" and suggests choosing the format on the left by hand — that way you see the exact error message of that parser.
Errors and notices
Two kinds of messages appear below the editors:
- Errors (red) — the input could not be read. Where possible, the parser's message names line and column; the Go to line … button puts the cursor right there, and an error marker flags the line in the Source editor. If writing to the target format fails, you get "Writing … failed".
- Notices (yellow) under the heading "Not everything fits the target format:" — the adjustments the tool makes because the target format cannot express something, each with the path to the affected spot. This list is not complete: some changes happen without a notice (see below).
The possible notices:
- TOML: there is no
null— keys withnullare left out, andnullentries are removed from lists. Integers beyond 64 bits become strings. If the top level isn't an object (but a list or a single value), it lands under the keyitems. - JSON: there is no
infornan(from TOML, for instance) — they becomenull. - XML: invalid element or attribute names are renamed (disallowed characters become
_, and a name that doesn't start with a letter or_gets a leading_). Control characters that XML 1.0 doesn't allow even as a reference are removed. A list at the top level is wrapped in<root>with one<item>per entry. On reading: XML comments are not carried over, and text between child elements (mixed content) is joined into#text— its position is lost. - INI: lists that contain objects or other lists (such as a TOML array
[[servers]]) are written as a JSON string,nullas an empty value, and keys containing=,[, or]are renamed; if the top level isn't an object, it lands underitems. On reading: if a key occurs twice, the last value wins.
These, on the other hand, happen without a notice:
- comments and formatting (only discarded XML comments are reported),
- the dot notation that flattens deeply nested objects when writing INI,
- the
<root>wrapper that appears when writing XML if the object doesn't have exactly one suitable key, - numbers from YAML and TOML sources that lose digits or the
1.0form, and the trailing zero of JSON floats such as1.10(see Exact numbers), - the loss of exact digits and of the
1.0form inside lists that INI writes as a JSON string (only the JSON string itself is reported), - date and time values from TOML that become strings in the other formats.
So an empty notice box does not mean nothing was changed.
Limits and edge cases
Because everything runs through a generic intermediate stage, some quirks are unavoidable — good to know before you puzzle over an output:
- Comments are lost. Comments from YAML, TOML, INI, or XML do not survive the conversion, because the intermediate stage has no notion of comments (for XML the tool points this out).
- Typing only where it is unambiguous. XML text and attributes and unquoted INI values only become booleans or numbers when they are exactly
true/falseor a canonically written number (42,-3.5).0123,+49,0755,1e3,yes, andonstay strings — a postal code with a leading zero or a file mode comes out unchanged. - XML → object: the name of the root element is kept as the top-level key (
<book>…</book>→{"book": {…}}). Attributes land as keys with an@prefix, text next to attributes or child elements as#text. Repeated same-named elements become an array, an empty element an empty string. Names with a namespace prefix (dc:title) stay as they are. - Object → XML: an XML declaration
<?xml version="1.0" encoding="UTF-8"?>is produced. If the object has exactly one key (not an@/#key, not an array), that key becomes the root element; otherwise the root is namedroot— when read back,rootthen shows up as an extra top-level key.@keys become attributes,#textthe text content, arrays repeated same-named elements (arrays inside arrays get a wrapper element with<item>entries), andnullan empty element. A namespace prefix is only kept when a matching@xmlns:prefixis in scope — otherwise the colon becomes_so the result stays well-formed. - Reading INI: lines starting with
;or#are comments, and;or#after an unquoted value starts an inline comment.[section]opens a section — one level only;[a.b]gives a key nameda.b, not nesting.key[] = valuecollects several lines into a list. Values in double quotes understand\n,\t,\r,\", and\\; values in single quotes are taken literally. A line without=is an error with a line number. - Writing INI: top-level values come first (without a section header), sub-objects become
[section]blocks, more deeply nested objects are flattened with dot notation (db.host = …) without a notice, lists of plain values becomekey[] = …lines, and lists containing objects or lists become a JSON string (with a notice). Strings that would come back as a different type ("true","42"), are empty, have leading or trailing whitespace, or contain special characters such as;,#, or line breaks are quoted and escaped. The INI reader does not undo the dot notation when converting back:db.hoststays a key with a dot in it.
For sensible ordering, round-trips, and how to read the notices, see Tips & Tricks; concrete runs are in the Examples.