@vishu1301/script-writing 0.5.1 → 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.d.cts CHANGED
@@ -21,7 +21,11 @@ declare const blockStyles: Record<BlockType, {
21
21
  inputStyle: React.CSSProperties;
22
22
  }>;
23
23
 
24
- declare function useScreenplayEditor(): {
24
+ interface UseScreenplayEditorOptions {
25
+ initialUrl?: string;
26
+ fetchOptions?: RequestInit;
27
+ }
28
+ declare function useScreenplayEditor(options?: UseScreenplayEditorOptions): {
25
29
  blocks: Block[];
26
30
  refs: React.RefObject<Record<string, HTMLDivElement | null>>;
27
31
  focusedBlockId: string;
@@ -41,6 +45,7 @@ declare function useScreenplayEditor(): {
41
45
  handleSceneNumberChange: (id: string, newNumber: string) => void;
42
46
  handleFocus: (id: string) => void;
43
47
  handleBlur: (id: string) => void;
48
+ loadFromUrl: (url: string, fetchOptions?: RequestInit) => Promise<void>;
44
49
  };
45
50
 
46
51
  type ScreenplayEditorViewProps = ReturnType<typeof useScreenplayEditor> & {
package/dist/index.d.ts CHANGED
@@ -21,7 +21,11 @@ declare const blockStyles: Record<BlockType, {
21
21
  inputStyle: React.CSSProperties;
22
22
  }>;
23
23
 
24
- declare function useScreenplayEditor(): {
24
+ interface UseScreenplayEditorOptions {
25
+ initialUrl?: string;
26
+ fetchOptions?: RequestInit;
27
+ }
28
+ declare function useScreenplayEditor(options?: UseScreenplayEditorOptions): {
25
29
  blocks: Block[];
26
30
  refs: React.RefObject<Record<string, HTMLDivElement | null>>;
27
31
  focusedBlockId: string;
@@ -41,6 +45,7 @@ declare function useScreenplayEditor(): {
41
45
  handleSceneNumberChange: (id: string, newNumber: string) => void;
42
46
  handleFocus: (id: string) => void;
43
47
  handleBlur: (id: string) => void;
48
+ loadFromUrl: (url: string, fetchOptions?: RequestInit) => Promise<void>;
44
49
  };
45
50
 
46
51
  type ScreenplayEditorViewProps = ReturnType<typeof useScreenplayEditor> & {
package/dist/index.js CHANGED
@@ -312,7 +312,7 @@ function ScreenplayEditorView({
312
312
  const link = document.createElement("link");
313
313
  link.id = fontId;
314
314
  link.rel = "stylesheet";
315
- link.href = "https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap";
315
+ link.href = "https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=swap";
316
316
  document.head.appendChild(link);
317
317
  }
318
318
  }, []);
@@ -360,7 +360,7 @@ function ScreenplayEditorView({
360
360
  {
361
361
  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",
362
362
  style: {
363
- fontFamily: "'Courier Prime', 'Courier New', Courier, monospace",
363
+ fontFamily: "var(--font-courier-prime, 'Courier Prime', 'Courier New', Courier, monospace)",
364
364
  paddingLeft: "1.5in",
365
365
  paddingRight: "1in",
366
366
  paddingTop: "1in",
@@ -924,7 +924,7 @@ function setCaretPosition(element, offset) {
924
924
  sel.removeAllRanges();
925
925
  sel.addRange(range);
926
926
  }
927
- function useScreenplayEditor() {
927
+ function useScreenplayEditor(options) {
928
928
  const [blocks, setBlocks] = useState(initialBlocks);
929
929
  const refs = useRef({});
930
930
  const [focusedBlockId, setFocusedBlockId] = useState(
@@ -934,6 +934,7 @@ function useScreenplayEditor() {
934
934
  const [showSuggestions, setShowSuggestions] = useState(false);
935
935
  const [showExtensionSuggestions, setShowExtensionSuggestions] = useState(false);
936
936
  const blurTimeout = useRef(null);
937
+ const loadedUrlRef = useRef(null);
937
938
  const characterExtensions = useMemo(
938
939
  () => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
939
940
  []
@@ -1363,6 +1364,92 @@ function useScreenplayEditor() {
1363
1364
  setShowExtensionSuggestions(false);
1364
1365
  }, 200);
1365
1366
  }, []);
1367
+ const loadFromUrl = useCallback(
1368
+ async (url, fetchOptions = {}) => {
1369
+ var _a;
1370
+ try {
1371
+ const response = await fetch(url, fetchOptions);
1372
+ if (!response.ok) {
1373
+ throw new Error(
1374
+ `[useScreenplayEditor] Failed to fetch script. HTTP Status: ${response.status}`
1375
+ );
1376
+ }
1377
+ let text = await response.text();
1378
+ let preParsedBlocks = void 0;
1379
+ let scriptContent = text;
1380
+ if (text.includes('class="divtype') || url.toLowerCase().includes(".sbx")) {
1381
+ if (text.includes("&lt;div")) {
1382
+ const textarea = document.createElement("textarea");
1383
+ textarea.innerHTML = text;
1384
+ text = textarea.value;
1385
+ }
1386
+ const parser = new DOMParser();
1387
+ const doc = parser.parseFromString(text, "text/html");
1388
+ const divs = Array.from(doc.querySelectorAll("div"));
1389
+ const parsed = [];
1390
+ const typeMap = {
1391
+ divtype0: "SCENE_HEADING",
1392
+ divtype2: "ACTION",
1393
+ divtype3: "CHARACTER",
1394
+ divtype4: "PARENTHETICAL",
1395
+ divtype5: "DIALOGUE",
1396
+ divtype6: "TRANSITION"
1397
+ };
1398
+ divs.forEach((div) => {
1399
+ var _a2;
1400
+ let divText = ((_a2 = div.textContent) == null ? void 0 : _a2.trim()) || "";
1401
+ if (!divText) return;
1402
+ let type = "ACTION";
1403
+ for (const className of Array.from(div.classList)) {
1404
+ if (typeMap[className]) {
1405
+ type = typeMap[className];
1406
+ break;
1407
+ }
1408
+ }
1409
+ const block = { type, text: divText };
1410
+ if (type === "SCENE_HEADING") {
1411
+ const sceneNum = div.getAttribute("data-scene");
1412
+ if (sceneNum) block.sceneNumber = sceneNum;
1413
+ let parsedText = divText;
1414
+ const typeMatch = parsedText.match(/^(INT\/EXT|INT|EXT)\.?\s+/i);
1415
+ if (typeMatch) {
1416
+ let sType = typeMatch[1].toUpperCase();
1417
+ if (!sType.endsWith(".")) sType += ".";
1418
+ block.sceneType = sType;
1419
+ parsedText = parsedText.substring(typeMatch[0].length).trim();
1420
+ }
1421
+ const timeMatch = parsedText.match(/\s+-\s+([^-]+)$/);
1422
+ if (timeMatch) {
1423
+ block.timeOfDay = timeMatch[1].trim().toUpperCase();
1424
+ parsedText = parsedText.substring(0, timeMatch.index).trim();
1425
+ }
1426
+ block.text = parsedText;
1427
+ }
1428
+ parsed.push(block);
1429
+ });
1430
+ if (parsed.length > 0) {
1431
+ preParsedBlocks = parsed;
1432
+ scriptContent = "";
1433
+ }
1434
+ }
1435
+ const filename = ((_a = url.split("/").pop()) == null ? void 0 : _a.replace(/\.sbx$/i, "")) || "Imported from URL";
1436
+ handleScriptImport(filename, scriptContent, preParsedBlocks);
1437
+ } catch (error) {
1438
+ console.error(
1439
+ "[useScreenplayEditor] Error loading script from URL:",
1440
+ error
1441
+ );
1442
+ throw error;
1443
+ }
1444
+ },
1445
+ [handleScriptImport]
1446
+ );
1447
+ useEffect(() => {
1448
+ if ((options == null ? void 0 : options.initialUrl) && options.initialUrl !== loadedUrlRef.current) {
1449
+ loadedUrlRef.current = options.initialUrl;
1450
+ loadFromUrl(options.initialUrl, options.fetchOptions);
1451
+ }
1452
+ }, [options == null ? void 0 : options.initialUrl, options == null ? void 0 : options.fetchOptions, loadFromUrl]);
1366
1453
  return {
1367
1454
  blocks,
1368
1455
  refs,
@@ -1382,7 +1469,8 @@ function useScreenplayEditor() {
1382
1469
  handleScriptImport,
1383
1470
  handleSceneNumberChange,
1384
1471
  handleFocus,
1385
- handleBlur
1472
+ handleBlur,
1473
+ loadFromUrl
1386
1474
  };
1387
1475
  }
1388
1476
  var handleSaveAsPdf = (blocks, sceneNumbers) => {