Skip to content

Commit

Permalink
Keep inline elements together even when inside a text (#141)
Browse files Browse the repository at this point in the history
Fixes #139

The real change in the code is having extractOutermostNewlines run on each batched node individually, rather than all of them as a group. This pulls up line nodes one level higher, outside of the flow they'd otherwise be in.
  • Loading branch information
ehrencrona authored Sep 12, 2020
1 parent cc11b6f commit 7583d0a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 26 deletions.
43 changes: 18 additions & 25 deletions src/print/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import {
import {
isLine,
isLineDiscardedIfLonely,
isEmptyGroup,
trim,
trimLeft,
trimRight,
isEmptyDoc,
} from './doc-helpers';

const {
Expand Down Expand Up @@ -540,14 +540,12 @@ function printChildren(path: FastPath, print: PrintFn): Doc[] {

/**
* Add a document to the output.
* @param childDoc null means do not add anything but allow for the possibility of a linebreak here.
* @param childDoc undefined means do not add anything but allow for the possibility of a linebreak here.
* @param fromNode the Node the doc was generated from. undefined if childDoc is undefined.
*/
function outputChildDoc(childDoc: Doc | null, fromNodes: Node[]) {
function outputChildDoc(childDoc?: Doc, fromNode?: Node) {
if (!isPreformat) {
const firstNode = fromNodes[0];
const lastNode = fromNodes[fromNodes.length - 1];

if (!childDoc || canBreakBefore(firstNode)) {
if ((!childDoc || !fromNode || canBreakBefore(fromNode))) {
linebreakPossible();

const lastChild = childDocs[childDocs.length - 1];
Expand All @@ -564,7 +562,7 @@ function printChildren(path: FastPath, print: PrintFn): Doc[] {
}
}

if (lastBreakIndex < 0 && childDoc && !canBreakAfter(lastNode)) {
if (lastBreakIndex < 0 && childDoc && fromNode && !canBreakAfter(fromNode)) {
lastBreakIndex = childDocs.length;
}
}
Expand All @@ -576,7 +574,7 @@ function printChildren(path: FastPath, print: PrintFn): Doc[] {

function lastChildDocProduced() {
// line breaks are ok after last child
outputChildDoc(null, []);
outputChildDoc();
}

/**
Expand All @@ -587,11 +585,10 @@ function printChildren(path: FastPath, print: PrintFn): Doc[] {
* desired to have text directly wrapping a mustache tag without additional whitespace.
*/
function flush() {
let groupDocs = currentGroup.map((item) => item.doc);
const groupNodes = currentGroup.map((item) => item.node);

for (let doc of extractOutermostNewlines(groupDocs)) {
outputChildDoc(doc, groupNodes);
for (let { doc, node } of currentGroup) {
for (const childDoc of extractOutermostNewlines(doc)) {
outputChildDoc(childDoc, node);
}
}

currentGroup = [];
Expand All @@ -607,9 +604,10 @@ function printChildren(path: FastPath, print: PrintFn): Doc[] {
flush();

if (childDoc !== '') {
outputChildDoc(isLine(childDoc) ? childDoc : concat([breakParent, childDoc]), [
outputChildDoc(
isLine(childDoc) ? childDoc : concat([breakParent, childDoc]),
childNode,
]);
);
}
}
}, 'children');
Expand Down Expand Up @@ -680,16 +678,11 @@ function dedentFinalNewline(docs: Doc[]): Doc[] {
/**
* Pull out any nested leading or trailing lines and put them at the top level.
*/
function extractOutermostNewlines(doc: Doc): Doc[] {
const leadingLines: Doc[] = trimLeft([doc], isLine) || [];
const trailingLines: Doc[] = trimRight([doc], isLine) || [];

function extractOutermostNewlines(docs: Doc[]): Doc[] {
const leadingLines: Doc[] = trimLeft(docs, isLine) || [];
const trailingLines: Doc[] = trimRight(docs, isLine) || [];

return [
...leadingLines,
...(!isEmptyGroup(docs) ? [fill(docs)] : ([] as Doc[])),
...trailingLines,
];
return [...leadingLines, ...(!isEmptyDoc(doc) ? [doc] : ([] as Doc[])), ...trailingLines];
}

function printJS(path: FastPath, print: PrintFn, name?: string) {
Expand Down
8 changes: 8 additions & 0 deletions src/print/node-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export function canBreakAfter(node: Node) {
return isWhitespaceChar(node.raw[node.raw.length - 1]);
case 'Element':
return !isInlineElement(node);
case 'IfBlock':
case 'EachBlock':
case 'MustacheTag':
return false;
default:
return true;
}
Expand All @@ -37,6 +41,10 @@ export function canBreakBefore(node: Node) {
return isWhitespaceChar(node.raw[0]);
case 'Element':
return !isInlineElement(node);
case 'IfBlock':
case 'EachBlock':
case 'MustacheTag':
return false;
default:
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<p>
<b>Apples</b>, <b>Orange</b>, <b>Bananas</b>, <b>Pineapples</b>, <b>Grapefruit</b>,
<b>Apples</b>,
<b>Orange</b>,
<b>Bananas</b>,
<b>Pineapples</b>,
<b>Grapefruit</b>,
<b>Kiwi</b>
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div>
<p>
This is line A.
<b>This is B. len(A + B) &gt; 80+ chars. len(b) lt; 80.</b>
</p>
<p>This is line A. <b>This is B. len(A + B) &lt; 80 chars.</b></p>
</div>

0 comments on commit 7583d0a

Please sign in to comment.