@vishu1301/script-writing 0.5.0 → 0.5.2

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/dist/index.cjs CHANGED
@@ -331,6 +331,16 @@ function ScreenplayEditorView({
331
331
  handleSceneNumberChange
332
332
  }) {
333
333
  const [isRulesOpen, setIsRulesOpen] = react.useState(false);
334
+ react.useEffect(() => {
335
+ const fontId = "google-font-courier-prime";
336
+ if (!document.getElementById(fontId)) {
337
+ const link = document.createElement("link");
338
+ link.id = fontId;
339
+ link.rel = "stylesheet";
340
+ link.href = "https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=swap";
341
+ document.head.appendChild(link);
342
+ }
343
+ }, []);
334
344
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
335
345
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-6 z-50 bg-white backdrop-blur-xl border border-white/10 rounded-full shadow-2xl flex gap-1 max-w-fit p-1.5 mb-12 select-none overflow-x-auto custom-scrollbar", children: blockTypes.map((type) => {
336
346
  var _a;
@@ -375,7 +385,7 @@ function ScreenplayEditorView({
375
385
  {
376
386
  className: "relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 border border-zinc-100 rounded-sm md:rounded-md pl-[1.5in] py-[1in] pr-[1in] flex flex-col w-[210mm] min-h-[297mm] shrink-0",
377
387
  style: {
378
- fontFamily: "'Courier Prime', 'Courier New', Courier, monospace",
388
+ fontFamily: "var(--font-courier-prime, 'Courier Prime', 'Courier New', Courier, monospace)",
379
389
  paddingLeft: "1.5in",
380
390
  paddingRight: "1in",
381
391
  paddingTop: "1in",
@@ -939,7 +949,7 @@ function setCaretPosition(element, offset) {
939
949
  sel.removeAllRanges();
940
950
  sel.addRange(range);
941
951
  }
942
- function useScreenplayEditor() {
952
+ function useScreenplayEditor(options) {
943
953
  const [blocks, setBlocks] = react.useState(initialBlocks);
944
954
  const refs = react.useRef({});
945
955
  const [focusedBlockId, setFocusedBlockId] = react.useState(
@@ -949,6 +959,7 @@ function useScreenplayEditor() {
949
959
  const [showSuggestions, setShowSuggestions] = react.useState(false);
950
960
  const [showExtensionSuggestions, setShowExtensionSuggestions] = react.useState(false);
951
961
  const blurTimeout = react.useRef(null);
962
+ const loadedUrlRef = react.useRef(null);
952
963
  const characterExtensions = react.useMemo(
953
964
  () => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
954
965
  []
@@ -1378,6 +1389,92 @@ function useScreenplayEditor() {
1378
1389
  setShowExtensionSuggestions(false);
1379
1390
  }, 200);
1380
1391
  }, []);
1392
+ const loadFromUrl = react.useCallback(
1393
+ async (url, fetchOptions = {}) => {
1394
+ var _a;
1395
+ try {
1396
+ const response = await fetch(url, fetchOptions);
1397
+ if (!response.ok) {
1398
+ throw new Error(
1399
+ `[useScreenplayEditor] Failed to fetch script. HTTP Status: ${response.status}`
1400
+ );
1401
+ }
1402
+ let text = await response.text();
1403
+ let preParsedBlocks = void 0;
1404
+ let scriptContent = text;
1405
+ if (text.includes('class="divtype') || url.toLowerCase().includes(".sbx")) {
1406
+ if (text.includes("<div")) {
1407
+ const textarea = document.createElement("textarea");
1408
+ textarea.innerHTML = text;
1409
+ text = textarea.value;
1410
+ }
1411
+ const parser = new DOMParser();
1412
+ const doc = parser.parseFromString(text, "text/html");
1413
+ const divs = Array.from(doc.querySelectorAll("div"));
1414
+ const parsed = [];
1415
+ const typeMap = {
1416
+ divtype0: "SCENE_HEADING",
1417
+ divtype2: "ACTION",
1418
+ divtype3: "CHARACTER",
1419
+ divtype4: "PARENTHETICAL",
1420
+ divtype5: "DIALOGUE",
1421
+ divtype6: "TRANSITION"
1422
+ };
1423
+ divs.forEach((div) => {
1424
+ var _a2;
1425
+ let divText = ((_a2 = div.textContent) == null ? void 0 : _a2.trim()) || "";
1426
+ if (!divText) return;
1427
+ let type = "ACTION";
1428
+ for (const className of Array.from(div.classList)) {
1429
+ if (typeMap[className]) {
1430
+ type = typeMap[className];
1431
+ break;
1432
+ }
1433
+ }
1434
+ const block = { type, text: divText };
1435
+ if (type === "SCENE_HEADING") {
1436
+ const sceneNum = div.getAttribute("data-scene");
1437
+ if (sceneNum) block.sceneNumber = sceneNum;
1438
+ let parsedText = divText;
1439
+ const typeMatch = parsedText.match(/^(INT\/EXT|INT|EXT)\.?\s+/i);
1440
+ if (typeMatch) {
1441
+ let sType = typeMatch[1].toUpperCase();
1442
+ if (!sType.endsWith(".")) sType += ".";
1443
+ block.sceneType = sType;
1444
+ parsedText = parsedText.substring(typeMatch[0].length).trim();
1445
+ }
1446
+ const timeMatch = parsedText.match(/\s+-\s+([^-]+)$/);
1447
+ if (timeMatch) {
1448
+ block.timeOfDay = timeMatch[1].trim().toUpperCase();
1449
+ parsedText = parsedText.substring(0, timeMatch.index).trim();
1450
+ }
1451
+ block.text = parsedText;
1452
+ }
1453
+ parsed.push(block);
1454
+ });
1455
+ if (parsed.length > 0) {
1456
+ preParsedBlocks = parsed;
1457
+ scriptContent = "";
1458
+ }
1459
+ }
1460
+ const filename = ((_a = url.split("/").pop()) == null ? void 0 : _a.replace(/\.sbx$/i, "")) || "Imported from URL";
1461
+ handleScriptImport(filename, scriptContent, preParsedBlocks);
1462
+ } catch (error) {
1463
+ console.error(
1464
+ "[useScreenplayEditor] Error loading script from URL:",
1465
+ error
1466
+ );
1467
+ throw error;
1468
+ }
1469
+ },
1470
+ [handleScriptImport]
1471
+ );
1472
+ react.useEffect(() => {
1473
+ if ((options == null ? void 0 : options.initialUrl) && options.initialUrl !== loadedUrlRef.current) {
1474
+ loadedUrlRef.current = options.initialUrl;
1475
+ loadFromUrl(options.initialUrl, options.fetchOptions);
1476
+ }
1477
+ }, [options == null ? void 0 : options.initialUrl, options == null ? void 0 : options.fetchOptions, loadFromUrl]);
1381
1478
  return {
1382
1479
  blocks,
1383
1480
  refs,
@@ -1397,7 +1494,8 @@ function useScreenplayEditor() {
1397
1494
  handleScriptImport,
1398
1495
  handleSceneNumberChange,
1399
1496
  handleFocus,
1400
- handleBlur
1497
+ handleBlur,
1498
+ loadFromUrl
1401
1499
  };
1402
1500
  }
1403
1501
  var handleSaveAsPdf = (blocks, sceneNumbers) => {