PBText keeps supported formatting when you paste a prepared post into LinkedIn, Facebook, YouTube, or X.
Write in your favorite text editor. Copy. Paste in LinkedIn, YouTube, Facebook, or X (Twitter). Keep the formatting. PBText handles the conversion automatically.
PBText works with bold, italic, underline, strikethrough, headings, paragraphs, lists, links, code, and common Markdown formatting. It also keeps supported line breaks and intentional blank lines.
PBText outputs plain text using Unicode characters, combining marks, and simple text frames so the visible formatting can be used in supported publishing fields.
DEVELOPMENT.md— local development setup and unpacked-extension workflow.INSTALL.md— installation instructions for users and developers.PRIVACY.md— PBText privacy policy and clipboard-data handling.PUBLISH.md— technical preparation sequence for building a publication-ready update.RELEASE.md— release ZIP contents, packaging rules, and archive inspection.SOLUTION.md— high-level architecture, runtime flow, module boundaries, and Mermaid diagrams.TEST.md— development test cycle, automated checks, browser harnesses, Test Show, and live-platform verification.
PBText officially supports:
- LinkedIn:
linkedin.com,www.linkedin.com - X/Twitter:
x.com,www.x.com,twitter.com,www.twitter.com - Facebook:
facebook.com,www.facebook.com - YouTube:
youtube.com,www.youtube.com
All behavior documented as supported in this README and TEST.md is part of the contract on each of these sites. If it fails in a supported site's editor, that is a PBText bug rather than an accepted site-specific limitation.
Test Show and the browser harnesses load the shared scripts directly. The production content script runs only on the supported publishing platforms listed above.
PBText reads clipboard data and produces plain text for insertion.
- Rich HTML containing a hyperlink takes priority so PBText can preserve and expose its URL.
- Otherwise, detected Markdown in
text/plainis treated as the source of truth and rich styling is discarded. - If no Markdown is detected, PBText parses clipboard HTML when available and falls back to plain text.
- Output is inserted as text and line breaks, not as styled HTML.
- Plain text that PBText cannot visibly transform is left to the site's normal paste handling.
- When PBText makes at least one visible supported transformation, it appends the punchline once, after one empty line:
I made the post pretty with PBText. You can do the same.
The punchline is not added merely because PBText handled the paste or detected Markdown. Plain
text that stays visually unchanged receives no punchline. For example, Hello stays Hello,
while Hello **world** becomes Hello 𝐰𝐨𝐫𝐥𝐝 and receives the punchline. Supported list, heading,
code, link, and inline-style transformations also count as visible changes.
Supported inline formatting:
- Bold:
**text**or rich<strong>/<b> - Italic:
*text*/_text_or rich<em>/<i> - Underline:
__text__or rich underline - Strikethrough:
~~text~~or rich strike/delete - Inline code:
`npm run build` - Combinations of bold, italic, underline, and strikethrough
Supported block formatting:
- Paragraphs and intentional blank lines
- Single line breaks inside a paragraph
- Rich HTML lists: unordered items use
•; ordered items use1.,2.,3.and always restart from1. - HTML headings and Markdown ATX headings (
#through######), rendered in bold - Markdown checkboxes, bracket markers, and unordered-list lines
- Rich HTML hyperlinks are expanded as
link text (original URL); the URL is kept literal and is not Unicode-formatted - Fenced Markdown code blocks with or without a language label
- Standalone
---lines rendered as twelve em dashes:————————————
Example code block output:
⎡ 𝚓𝚜
⎢ 𝚌𝚘𝚗𝚜𝚝 𝚡 = 𝟷;
⎢ 𝚌𝚘𝚗𝚜𝚘𝚕𝚎.𝚕𝚘𝚐(𝚡);
⎣
Tabs inside code blocks are expanded to four spaces.
Default bracket-marker replacements:
| Input | Output |
|---|---|
[ ] |
▢ (U+25A2) |
[x] |
☑︎ (U+2611 U+FE0E) |
[*], [star] |
🌟 |
[f], [fire] |
🔥 |
- Markers are case-sensitive and work anywhere in ordinary text, but are not replaced inside inline code or fenced code blocks.
- At the start of a list item, a configured marker replaces the complete
- [marker]prefix and acts as the bullet:- [fire] Hotbecomes🔥 Hot. - Other lines beginning with
-become—list items. Leading spaces and tabs are accepted and discarded, so nesting is flattened. - Unknown markers fall through to the ordinary-list rule:
- [X] Taskbecomes— [X] Task. - Add one- or multi-character mappings in
src/bracketMarkerConfig.js, then reload the extension and page.
PBText uses Unicode characters rather than real CSS styles:
- Latin letters and digits can be converted to mathematical bold, italic, bold italic, or monospace forms.
- Decomposable Latin letters with diacritics are handled by styling the base letter and preserving combining marks.
- Underline and strikethrough are rendered with combining marks.
- Non-decomposable letters such as
ß,ẞ,æ,œ,ø,ł,đ,ð,þ,ħ, andıare preserved as-is. - Cyrillic text has a separate Unicode-rendering strategy. Bold Cyrillic runs are separated and surrounded with spaced bullets around each letter.
- Italic Cyrillic runs use spaced hyphenation points between each letter.
- For a fully styled Cyrillic word inside a line, an adjacent interword space is reinforced with two non-breaking spaces while retaining the original regular space. Each side is evaluated independently: line boundaries and attached punctuation receive nothing, while an existing space on the other side is still reinforced. Styled fragments inside a word do not receive extra boundary spacing.
- Other unsupported Cyrillic styles preserve the original letters rather than substituting visually similar Latin characters.
src/lineBreaks.js: newline normalization and visible text layout helpers.src/bracketMarkerConfig.js: one- or multi-character bracket-marker replacements.src/lineTransforms.js: headings, line rules, lists, and bracket-marker transformations.src/cyrillicStyleConfig.js: declarative separators and spacing for Cyrillic styles.src/markdownParser.js: Markdown inline and fenced-code parsing.src/htmlParser.js: clipboard HTML parsing, hyperlinks, effective styles, and indentation hints.src/clipboardParser.js: clipboard source selection and plain-text parsing.src/rules.js: Unicode formatting rules.src/renderer.js: rendering internal blocks into final plain text.src/pastePipeline.js: high-level formatting flow and punchline append.src/textInsertion.js: shared insertion into editable targets through explicit generic, model-native, and model-literal modes.src/content.js: runtime paste interception on supported domains.tests/smoke.js: dependency-free pipeline smoke tests.tests/project-structure.js: script-order contract checks for the production manifest and Test Show pages.
The parsers and renderer exchange a small internal model:
- A segment contains
text, boolean formattingmarks, and an optional hyperlink address. - A block contains
type,segments, andnewlinesAfter. - List and code blocks add only the data they need, such as
listorlanguage.
The files are loaded as plain scripts, so their order in manifest.json and the Test Show pages is part of the runtime contract.
node tests/smoke.js
node tests/project-structure.js
for f in src/*.js tests/*.js; do node --check "$f" || exit 1; done
node -e "JSON.parse(require('fs').readFileSync('manifest.json','utf8')); console.log('manifest ok')"- Formatting is plain-text Unicode, not real rich text.
- Punctuation generally has no separate mathematical monospace/bold/italic variant and is preserved.
- Code block frames are text characters; their visual alignment depends on the target editor font.
- The extension does not try to syntax-highlight code.
- Hyperlink expansion requires rich HTML with an actual link; Markdown
[text](URL)syntax is not parsed. - The current domain list is hardcoded in
manifest.json. - Clipboard payloads larger than 1,000,000 characters are left to the site's normal paste handling.
