rapier-markdown-kit 1.1.88 → 1.1.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -238,7 +238,10 @@ console.log('lines:', plan.lines.length, 'height:', plan.height); // lines: 4 he
238
238
 
239
239
  A heading, which the style pack balances, takes its font size as an eighth argument
240
240
  (`flowLines(flow, width, top, obstacles, lineHeight, minSlot, direction, fontSize)`): its lines come out as
241
- Chromium lays `text-wrap: balance`, and greedy wherever an obstacle narrows a line.
241
+ Chromium lays `text-wrap: balance`, and greedy wherever an obstacle narrows a line. The block's `text-align` is the ninth
242
+ argument (`'start'` by default). A picture moves a block's words only where its outline meets them: when no line of the
243
+ block, laid and aligned in the whole column as with no picture, meets an obstacle, the plan is that layout (`x` 0, the
244
+ column's width); otherwise every line flows around the obstacles.
242
245
 
243
246
  ## What the host supplies
244
247
 
@@ -1118,7 +1118,7 @@ function _rapierProjectArtifactLayout(root, metadata, geometry, pretext) {
1118
1118
 
1119
1119
  function project(record, width, top, obstacles) {
1120
1120
  const plan = geometry.flowLines(record.flow, width, top, obstacles, record.lineHeight,
1121
- metadata.wrapColumnFloor(record.fontSize), record.direction, record.balance);
1121
+ metadata.wrapColumnFloor(record.fontSize), record.direction, record.balance, record.align);
1122
1122
  if (!plan) return false;
1123
1123
  const output = doc.createDocumentFragment();
1124
1124
  let previous = null;
@@ -373,8 +373,25 @@ export function slotsForBand(width, obstacles, top, height, minWidth = 40) {
373
373
  return slots;
374
374
  }
375
375
 
376
- export function flowLines(flow, width, top, obstacles, lineHeight, minWidth, direction = 'ltr', balance = 0) {
377
- return linePlan(flow, width, top, obstacles, lineHeight, minWidth, direction, balance, slotsForBand, layoutNextRichInlineLineRange, materializeRichInlineLineRange);
376
+ // A picture moves a block's words only where its outline (with its standoff) meets them. The block is laid as it lies with no
377
+ // picture beside it, balanced and aligned in the whole column; when no line of words there meets an obstacle, that is its
378
+ // layout. Otherwise its lines flow around the outline. A block set from the side its lines start on, and not balanced, lies
379
+ // the same both ways whenever the outline misses its words, so it is laid once.
380
+ export function flowLines(flow, width, top, obstacles, lineHeight, minWidth, direction = 'ltr', balance = 0, align = 'start') {
381
+ const plan = linePlan(flow, width, top, obstacles, lineHeight, minWidth, direction, balance, slotsForBand, layoutNextRichInlineLineRange, materializeRichInlineLineRange);
382
+ const side = align === 'center' ? 'center' : align === 'left' || align === 'right' ? align
383
+ : (align === 'end') === (direction === 'rtl') ? 'left' : 'right';
384
+ if (!plan || !obstacles?.length || !balance && side === (direction === 'rtl' ? 'right' : 'left')) return plan;
385
+ const free = linePlan(flow, width, top, [], lineHeight, minWidth, direction, balance, slotsForBand, layoutNextRichInlineLineRange, materializeRichInlineLineRange);
386
+ if (!free) return plan;
387
+ const meets = free.lines.some(line => {
388
+ const words = line.fragments.reduce((sum, fragment) => sum + (fragment.gapBefore || 0) + (fragment.occupiedWidth || 0), 0);
389
+ const left = side === 'left' ? 0 : side === 'right' ? width - words : (width - words) / 2;
390
+ const lineTop = top + line.y;
391
+ return obstacles.some(obstacle => obstacle.width > 0 && obstacle.height > 0 &&
392
+ obstacle.x < left + words && obstacle.x + obstacle.width > left && obstacle.y < lineTop + lineHeight && obstacle.y + obstacle.height > lineTop);
393
+ });
394
+ return meets ? plan : free;
378
395
  }
379
396
 
380
397
  // ---- The one wrap shape (live: globalThis.RapierImageLayout; export: modules["layout/model.mjs"]) ----
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rapier-markdown-kit",
3
- "version": "1.1.88",
3
+ "version": "1.1.89",
4
4
  "description": "Read, render and write Self-contained Markdown: one .md file that carries its pictures, drawings and layout, and that any Markdown app can read. HTML renderer, stylesheet, text layout, Will/1 agent permissions, and an edit history with authorship and offline merge. MIT, no dependencies.",
5
5
  "keywords": [
6
6
  "markdown",