@markdy/core 1.1.1 → 1.1.3

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.
Files changed (2) hide show
  1. package/dist/index.js +61 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -559,6 +559,10 @@ var SCOPES = {
559
559
  };
560
560
  var PLAYER_GROUPS = ["playback", "controls", "interaction", "chrome"];
561
561
  var PLAYER_FLAT_KEYS = Object.keys(FLAT);
562
+ function isKnownPlayerSetting(key, scope) {
563
+ if (scope) return Boolean(SCOPES[scope]?.[key]);
564
+ return PLAYER_GROUPS.includes(key) || Object.values(SCOPES).some((scopeMap) => Boolean(scopeMap[key]));
565
+ }
562
566
  function applyPlayerSetting(config, scope, key, rawValue) {
563
567
  const setting = SCOPES[scope][key];
564
568
  if (!setting) return `unknown player property '${key}'`;
@@ -2859,6 +2863,22 @@ function mirrorLegacySceneMeta(meta) {
2859
2863
  else if (chrome?.progressColor !== void 0) meta.progressColor = chrome.progressColor;
2860
2864
  return meta;
2861
2865
  }
2866
+ var NON_PLAYER_TOP_LEVEL_RE = /^(scene|player|layout|pattern|group|annotation|edge|beat|var|style)\b/;
2867
+ function isPlayerBlockLine(line) {
2868
+ if (PLAYER_GROUP_RE.test(line)) return true;
2869
+ const match = line.match(PLAYER_SETTING_RE);
2870
+ if (!match) return false;
2871
+ return isKnownPlayerSetting(match[1]);
2872
+ }
2873
+ function isNonPlayerTopLevelStatement(line) {
2874
+ if (line === "}") return true;
2875
+ if (NON_PLAYER_TOP_LEVEL_RE.test(line)) return true;
2876
+ if (isPlayerBlockLine(line)) return false;
2877
+ const nodeMatch = line.match(/^(\w[\w.-]*)\s+(\w[\w.-]*)/);
2878
+ if (!nodeMatch) return false;
2879
+ const kind = canonicalNodeKind(nodeMatch[1].toLowerCase());
2880
+ return NODE_KINDS.has(kind);
2881
+ }
2862
2882
  function isTopLevelStatement(line) {
2863
2883
  if (line === "}") return true;
2864
2884
  if (TOP_LEVEL_KEYWORDS_RE.test(line)) return true;
@@ -3112,8 +3132,32 @@ function parse(source, opts = {}) {
3112
3132
  const unsupportedMessage = unsupportedSyntaxMessage(line);
3113
3133
  if (unsupportedMessage) throw new ParseError(unsupportedMessage, lineNo);
3114
3134
  if (/^player\s*:\s*$/.test(line)) {
3115
- const { body, nextIdx } = readIndentedBody(blocks, i + 1, block.indent);
3116
- if (body.length === 0) throw new ParseError("player block requires at least one setting", lineNo);
3135
+ let { body, nextIdx } = readIndentedBody(blocks, i + 1, block.indent);
3136
+ if (body.length === 0 && i + 1 < blocks.length) {
3137
+ const unindented = [];
3138
+ let j = i + 1;
3139
+ while (j < blocks.length) {
3140
+ const nextBlock = blocks[j];
3141
+ if (nextBlock.indent < block.indent) break;
3142
+ if (nextBlock.indent === block.indent && isNonPlayerTopLevelStatement(nextBlock.text)) break;
3143
+ if (isNonPlayerTopLevelStatement(nextBlock.text)) break;
3144
+ unindented.push(nextBlock);
3145
+ j++;
3146
+ }
3147
+ if (unindented.length > 0) {
3148
+ body = unindented;
3149
+ nextIdx = j;
3150
+ }
3151
+ }
3152
+ if (body.length === 0) {
3153
+ if (i + 1 < blocks.length && isNonPlayerTopLevelStatement(blocks[i + 1].text)) {
3154
+ throw new ParseError(
3155
+ `player block requires at least one setting (found '${blocks[i + 1].text}' immediately following 'player:')`,
3156
+ lineNo
3157
+ );
3158
+ }
3159
+ throw new ParseError("player block requires at least one setting", lineNo);
3160
+ }
3117
3161
  const player = meta.player ??= {};
3118
3162
  const applySetting = (scope, setting) => {
3119
3163
  const match = setting.text.match(PLAYER_SETTING_RE);
@@ -3126,7 +3170,21 @@ function parse(source, opts = {}) {
3126
3170
  const groupMatch = setting.text.match(PLAYER_GROUP_RE);
3127
3171
  if (groupMatch) {
3128
3172
  const scope = groupMatch[1];
3129
- const { body: childBody, nextIdx: childNextIdx } = readIndentedBody(body, settingIdx + 1, setting.indent);
3173
+ let childBody = [];
3174
+ let childNextIdx = settingIdx + 1;
3175
+ const indented = readIndentedBody(body, settingIdx + 1, setting.indent);
3176
+ if (indented.body.length > 0) {
3177
+ childBody = indented.body;
3178
+ childNextIdx = indented.nextIdx;
3179
+ } else {
3180
+ let k = settingIdx + 1;
3181
+ while (k < body.length) {
3182
+ if (PLAYER_GROUP_RE.test(body[k].text)) break;
3183
+ childBody.push(body[k]);
3184
+ k++;
3185
+ }
3186
+ childNextIdx = k;
3187
+ }
3130
3188
  if (childBody.length === 0) {
3131
3189
  throw new ParseError(`player ${scope} block requires at least one setting`, setting.line);
3132
3190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdy/core",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Diagram-native MarkdyScript parser and compiler (auto-layout, edge routing, cue scheduling) — zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "type": "module",