Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

script mode #24

Open
zhammer opened this issue Dec 14, 2019 · 10 comments
Open

script mode #24

zhammer opened this issue Dec 14, 2019 · 10 comments

Comments

@zhammer
Copy link
Owner

zhammer commented Dec 14, 2019

i want to be able to enable script mode when writing, which converts my textarea into a simple, user-friendly writer with screenplay formatting.

simple ui/ux like:

  • i can see what type of script block i'm writing (scene header, character, dialogue, etc)
  • i can switch between modes by hitting tab, maybe by hitting buttons

ideal requirements:

  • scribly server is entirely unaware of script mode vs non script mode, this is only for local formatting while writing
  • this is entirely optional, should be able to load this script last, not affecting regular functionality

impl:

  • thinking this could be a nice way to try svelte?
@zhammer
Copy link
Owner Author

zhammer commented Dec 15, 2019

@zhammer
Copy link
Owner Author

zhammer commented Dec 16, 2019

formatBlock
Adds an HTML block-level element around the line containing the current selection, replacing the block element containing the line if one exists (in Firefox,

is the exception — it will wrap any containing block element). Requires a tag-name string as a value argument. Virtually all block-level elements can be used. (Internet Explorer and Edge support only heading tags H1–H6, ADDRESS, and PRE, which must be wrapped in angle brackets, such as "

".)

@zhammer
Copy link
Owner Author

zhammer commented Dec 16, 2019

https://glitch.com/~adaptable-linseed

// global createMachine

let clicks = 0;
const script = document.getElementById("script");
script.onkeydown = event => {
  if (event.key !== "Tab") {
    return;
  }
  event.preventDefault();
  document.execCommand("formatBlock", false, "div");
  let myClass;
  if (clicks % 2 === 0) {
    myClass = "character";
  }
  else {
    myClass = "title";
  }
  const quote = window.getSelection().focusNode.parentNode;
  quote.classList = myClass;
  
  clicks += 1;
};

@zhammer
Copy link
Owner Author

zhammer commented Dec 17, 2019

this seems to cover basic shuffling of components:

// from: http://www.writingroom.com/viewwriting/wr_how_to/How-To-Format-A-Screenplay
const screenplayComponents = [
  "heading",
  "action",
  "character",
  "dialogue",
  "parenthetical",
  "transition"
];

// get the screenplay component after the current
// next("action") -> "character"
function next(screenplayComponent) {
  const index = screenplayComponents.indexOf(screenplayComponent);
  if (index === -1) {
    return screenplayComponents[0];
  }
  return screenplayComponents[(index + 1) % screenplayComponents.length];
}

// get the screenplay component before the current
// previous("action") -> "header"
function previous(screenplayComponent) {
  const index = screenplayComponents.indexOf(screenplayComponent);
  if (index === -1) {
    return screenplayComponents[0];
  }
  return screenplayComponents[(index + screenplayComponents.length - 1) % screenplayComponents.length];
}

function getActiveElement() {
  let focused = window.getSelection().focusNode;
  return focused.nodeName === "#text" ? focused.parentNode : focused;
}

const script = document.getElementById("script");
script.onkeydown = event => {
  if (!event.shiftKey && event.key === "Tab") {
    event.preventDefault();
    nextStyle();
  }
  if (event.shiftKey && event.key == "Tab") {
    event.preventDefault();
    prevStyle();
  }
};

function nextStyle() {
  document.execCommand("formatBlock", false, "p");
  const activeElement = getActiveElement();
  const nextScreenplayComponent = next(activeElement.className); 
  activeElement.classList = nextScreenplayComponent;
}

function prevStyle() {
  document.execCommand("formatBlock", false, "p");
  const activeElement = getActiveElement();
  const nextScreenplayComponent = previous(activeElement.className); 
  activeElement.classList = nextScreenplayComponent;
}

ideally server would deserialize from submit, like:

[
  Line("i am writing a normal text here"),
  Line(""),
  Line("i am about to start my script"),
  Heading("ext. daytime. outside."),
  Action("A person walks down the road. A gust of wind blows by."),
  Character("Narrator"),
  Parenthetical("(dramatically)"),
  Dialogue("Nothing is as it seems...")
]

but would probably? still store in the db as a text blob, maybe adding back some type of

i am writing normal text here

i am about to start my script
<SCRIPT.heading>ext. daytime. outside.</SCRIPT.heading>
<SCRIPT.action>A person walks down the road. A gust of wind blows by.</SCRIPT.action>
...

then when rendering out to html, the array of line/heading/etc would be render to html p tags with classes

@zhammer
Copy link
Owner Author

zhammer commented Dec 17, 2019

the main thing for me is: most of the time we want a turn in the db to just look like:

it was early in the morning.
someone was calling jane.
but she couldn't answer the phone.

and ideally that'd be represented simply like

turn.text_written = "it was early in the morning.\nsomeone was calling jane.\nbut she couldn't answer the phone."

but i want some optional markup to be in there, at first for script writing, in a way that's not a pain in the ass

@zhammer
Copy link
Owner Author

zhammer commented Dec 17, 2019

also, obviously i want to make sure it's not a problem if someone writes in their turn, in plaintext:

<SCRIBLY.action>i'm trying to inject some scribly markup</SCRIBLY.action>

@zhammer
Copy link
Owner Author

zhammer commented Dec 17, 2019

v1

  • desktop only (fine on mobile too but don't know if there's a tab button)
  • enable via some button or maybe even query param
  • tab and shift-tab to cycle styles
  • no UI showing which style is active
  • can save as turn and retrieve looking as was written

@zhammer
Copy link
Owner Author

zhammer commented Dec 17, 2019

need to fix:

  • click enter without ever clicking tab
  • we now have two divs, not two ps
  • i think on load we need to do the tab thing, or start it with a p inside
  • also have to be wary about people editing html in devtools then submitting

@zhammer
Copy link
Owner Author

zhammer commented Dec 17, 2019

s/Line/Text

@zhammer
Copy link
Owner Author

zhammer commented Feb 5, 2020

i'm leaning more towards having each part in the db.

turns
-----
| id  | type       | text                 |
| 1   | text       | this is my turn text |
| 2   | components |                      | # <-- text only exists for plain text turns

turn-components
---------------
| id | turn_id | type   | value                                |
|  1 | 2       | action | jime reaches his hand into the grass |

@zhammer zhammer mentioned this issue Feb 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant