@blankdotpage/cake 0.1.48 → 0.1.49

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.
@@ -1 +1 @@
1
- {"version":3,"file":"heading.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/heading/heading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAC;AAmU5B,eAAO,MAAM,gBAAgB,EAAE,aA2M9B,CAAC"}
1
+ {"version":3,"file":"heading.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/heading/heading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAC;AAiV5B,eAAO,MAAM,gBAAgB,EAAE,aA2M9B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { CursorSourceBuilder } from "../../core/mapping/cursor-source-map";
2
2
  import { mergeInlineForRender } from "../../dom/render";
3
+ import { getLineBlockContent } from "../shared/line-content";
3
4
  const HEADING_KIND = "heading";
4
5
  const HEADING_PATTERN = /^(#{1,3}) /;
5
6
  function findLineStartInSource(source, sourceOffset) {
@@ -233,13 +234,18 @@ function handleToggleHeading(state, targetLevel) {
233
234
  else {
234
235
  // Line is not a heading - add the heading marker
235
236
  const newMarker = "#".repeat(targetLevel) + " ";
237
+ const lineContentWithoutBlockMarkers = getLineBlockContent(lineContent, runtime);
236
238
  newSource =
237
239
  source.slice(0, lineStart) +
238
240
  newMarker +
239
- lineContent +
241
+ lineContentWithoutBlockMarkers +
240
242
  source.slice(lineEnd);
241
- // Cursor moves forward by marker length
242
- newCursorOffset = sourcePos + newMarker.length;
243
+ const removedPrefixLength = lineContent.endsWith(lineContentWithoutBlockMarkers)
244
+ ? lineContent.length - lineContentWithoutBlockMarkers.length
245
+ : 0;
246
+ const cursorLineOffset = sourcePos - lineStart;
247
+ const adjustedLineOffset = Math.max(0, cursorLineOffset - Math.min(cursorLineOffset, removedPrefixLength));
248
+ newCursorOffset = lineStart + newMarker.length + adjustedLineOffset;
243
249
  }
244
250
  // Create new state and map cursor through it
245
251
  const next = runtime.createState(newSource);
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/list/list.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,oBAAoB,CAAC;AA4mC5B,+CAA+C;AAC/C,MAAM,MAAM,uBAAuB,GAAG;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAErE,iDAAiD;AACjD,MAAM,MAAM,yBAAyB,GAAG;IAAE,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAEzE,kCAAkC;AAClC,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG,yBAAyB,CAAC;AAE9E,eAAO,MAAM,sBAAsB,EAAE,aA8HpC,CAAC"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/list/list.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,oBAAoB,CAAC;AAknC5B,+CAA+C;AAC/C,MAAM,MAAM,uBAAuB,GAAG;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAErE,iDAAiD;AACjD,MAAM,MAAM,yBAAyB,GAAG;IAAE,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAEzE,kCAAkC;AAClC,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG,yBAAyB,CAAC;AAE9E,eAAO,MAAM,sBAAsB,EAAE,aA8HpC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { mergeInlineForRender } from "../../dom/render";
2
2
  import { parseListRange, serializeListRange, convertToPlainText, getLineInfo, getListPrefixLength, isListLine, parseListItem, countNumberedItemsBefore, } from "./list-ast";
3
+ import { getLineBlockContent } from "../shared/line-content";
3
4
  // Match list lines - capture exactly one space after marker, rest goes to content
4
5
  const LIST_LINE_REGEX = /^(\s*)([-*+]|\d+\.)( )(.*)$/;
5
6
  function matchListLine(line) {
@@ -627,10 +628,16 @@ function handleToggleList(state, isBullet) {
627
628
  const indentLevel = Math.floor(baseIndent.length / 2);
628
629
  let content;
629
630
  if (listItem) {
630
- content = listItem.content;
631
+ content = getLineBlockContent(line, runtime);
631
632
  }
632
633
  else {
633
- content = line.slice(baseIndent.length);
634
+ const lineContent = getLineBlockContent(line, runtime);
635
+ if (baseIndent.length > 0 && lineContent.startsWith(baseIndent)) {
636
+ content = lineContent.slice(baseIndent.length);
637
+ }
638
+ else {
639
+ content = lineContent;
640
+ }
634
641
  }
635
642
  let newPrefix;
636
643
  if (isBullet) {
@@ -0,0 +1,10 @@
1
+ import type { Runtime } from "../../core/runtime";
2
+ /**
3
+ * Extract editable block content from a single source line.
4
+ *
5
+ * This strips structural wrappers (headings, blockquotes, etc.) and list
6
+ * markers so command toggles can convert between block types without leaking
7
+ * source-only marker syntax into the next block.
8
+ */
9
+ export declare function getLineBlockContent(lineSource: string, runtime: Runtime): string;
10
+ //# sourceMappingURL=line-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-content.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/shared/line-content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAmBlD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAkBhF"}
@@ -0,0 +1,36 @@
1
+ import { parseListItem } from "../list/list-ast";
2
+ function serializeBlockContent(block, runtime) {
3
+ if (block.type === "paragraph") {
4
+ const doc = { type: "doc", blocks: [block] };
5
+ return runtime.serialize(doc).source;
6
+ }
7
+ if (block.type === "block-wrapper") {
8
+ return block.blocks
9
+ .map((child) => serializeBlockContent(child, runtime))
10
+ .join("\n");
11
+ }
12
+ return "";
13
+ }
14
+ /**
15
+ * Extract editable block content from a single source line.
16
+ *
17
+ * This strips structural wrappers (headings, blockquotes, etc.) and list
18
+ * markers so command toggles can convert between block types without leaking
19
+ * source-only marker syntax into the next block.
20
+ */
21
+ export function getLineBlockContent(lineSource, runtime) {
22
+ if (lineSource === "") {
23
+ return "";
24
+ }
25
+ const doc = runtime.parse(lineSource);
26
+ const firstBlock = doc.blocks[0];
27
+ if (!firstBlock) {
28
+ return "";
29
+ }
30
+ const wrapperFreeContent = serializeBlockContent(firstBlock, runtime);
31
+ const listItem = parseListItem(wrapperFreeContent);
32
+ if (listItem) {
33
+ return listItem.content;
34
+ }
35
+ return wrapperFreeContent;
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blankdotpage/cake",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",