Giter Club home page Giter Club logo

sketch-n-sketch's Introduction

Sketch-n-Sketch

Direct manipulation interfaces are useful in many domains, but the lack of programmability in a high-level language makes it difficult to develop complex and reusable content. We envision direct manipulation programming systems that allow users to freely mix between programmatic and direct manipulation.

Direct Manipulation Programming = Programmatic + Direct Manipulation
Sketch-n-Sketch = Direct Manipulation Programming for SVG/HTML Documents

Check out the main project page for more details and to try out the latest release.

Quick Syntax Reference

We support a (almost) superset of Elm Syntax.

  program  ::=  x1 = e1; ...; xn = en; e
            |   x1 = e1; ...; xn = en     -- where xi = main for some i

  e  ::=
      |   constant
      |   variable
      |   \p -> e
      |   \p1 ... pn -> e
      |   e1 e2
      |   e1 <| e2                  -- infix application
      |   e2 |> e1                  -- infix reverse application
      |   e1 e2 e3 ... en
      |   opn e1 ... en
      |   Let p = e1 in e2
      |   Let x p1 ... pn = e1 in e2
      |   if e1 then e2 else e3
      |   case e of p1 -> e1; ...; pn -> en
      |   e1 :: e2
      |   []
      |   [e1, ..., en]
      |   (e1, ..., en)
      |   {f1 = e1; ...; fn = en}
      |   e.f
      |   #option:value
          e
      |   (e)
      |   ()

  p  ::= constant
       | variable
       | p as variable
       | [p1, ..., pn]
       | (p1, ..., pn)
       | p1 :: pn
       | {f1 = p1, ... fn = pn}
  opn ::= 

Syntax Guide

Programs

A program is a series of top-level definitions followed by an expression. If the final expression is omitted, it implicitly refers to the variable main. By convention, the main definition is often the last top-level definition.

  program  ::=  x1 = e1; ...; xn = en; e
            |   x1 = e1; ...; main = e

Constants

  e  ::=
      |   n         -- numbers (all are floating point)
      |   s         -- strings (use double- or single-quotes at the outermost level)
      |   b         -- booleans
  n  ::=  123
      |   3.14
      |   -3.14

      |   3.14!     -- frozen constants (may not be changed by sync)
      |   3.14?     -- thawed constants (may be changed by sync)
      |   3.14~     -- assign to at most one zone

      |   3{0-6}          -- auto-generate an integer slider
      |   3.14{0.0-6.28}  -- auto-generate a numeric slider
  b  ::=  True | False
  s  ::=  "hello" | 'world'
      |   "'hello world'"     -- quotation marks can be nested
      |   """S"""             -- long-string literals

Long string literals with interpolation

"""Here @y @x.hello @(let y = "2" in y)
@let t = "third" in
This is on a @t line"""

is roughly equivalent to "Here " + S y + " " + S x.hello + " " + S (let y = "2" in y) + "\n" + (let t = "third" in "This is on a " + t + " line" where S converts its argument to a string if it is not. Note that inline @let always require the space after "in" to be a newline.

Primitive Operators

  e  ::=  ...
      |   op0
      |   op1 e1
      |   op2 e1 e2
      |   e1 opi e2
      |   (op)
      |   (op,...,op)
  op0  ::=  pi
  op1  ::=  cos | sin | arccos | arcsin
        |   floor | ceiling | round
        |   toString
        |   sqrt
        |   explode             : String -> List String

  op2  ::=  mod | pow
        |   arctan2

  opi  ::=  + | - | * | /
        |   == | < | <= | > | >= | /=
        |   && | `||` | `|>` | `<|` | << | >>
        
  e  ::= ...
       | __DictEmpty__ e
       | __DictFromList__ e
       | __DictInsert__ eK eV eD
       | __DictRemove__ eK eD
       | __DictGet__ eK eD

For your convenience, the prelude defines a Dict record exposing empty, fromList, member, contains, remove, get`` and apply`.

Conditionals

  e  ::=  ...
      |   if e1 then e2 else e3

Lists

  e  ::=  ...
      |   e1 :: e2
      |   []
      |   [e1, ..., en]          -- desugars to e1 :: e2 :: ... :: []

Tuples

 e  ::=   ...
      |   ()
      |   (e1, ... en)
      |   (,...,)               -- desugars to \e1 ... en -> (e1,..., en)

Records

 e  ::=   ...
      |   { f1 = e1, ...., fn = en}
      |   e.f1
      |   .f1.f2(...).fn              -- desugars to \x -> x.f1.f2(...).fn

Note that f1 a b = e in a key/value definition of a record is equivalent to f1 = \a b -> e. The comma is optional for defining a new key/value pair if

  1. there are two newlines before or 2) there is one newline before and the column of the key is at most the column of the key before it. We sometimes say "module" to describe a record that begins with a capital letter.

Patterns

  p  ::=  x
      |   n | s | b
      |   p1 :: p2
      |   p as x
      |   []
      |   [p1, ..., pn]
      |   (p1, ..., pn)
      |   {f1 = p1; ..., fn = pn}
      |   {f1, ..., fn}              -- desugars to {f1 = f1, ..., fn = fn}

Case Expressions

  e  ::=  ...
      |   case e of p1 -> e1; ...; pn -> en
      |   case of p1 -> e1; ...; pn -> en     -- desugars to \x -> case x of p1 -> e1; ...; pn -> en

The semicolon is optional for a branch if 1) there is a newline 2) the column of the start of this branch matches the column of the start of the first branch.

Functions

  e  ::=  ...
      |   \p -> e
      |   \p1 ... pn -> e     -- desugars to \p1 -> \p2 -> ... -> \pn -> e

Function Application

  e  ::=  ...
      |   e1 e2
      |   e1 <| e2                  -- infix application
      |   e2 |> e1                  -- infix reverse application
      |   e1 e2 e3 ... en           -- desugars to ((((e1 e2) e3) ...) en)

Let-Bindings

  e  ::=  ...
      |   let p1 = e1, p2 = e2 in e2
      |   let f p1 ... pn = e1 in e2   -- desugars to L f = \p1 ... pn -> e1 in e2

Built-in functions

__evaluate__ environment string

Evaluates the program present in the string under the given environment, which is a list of (string, value). It returns either Ok result or Err String an error message. This function is reversible. You can even push back corrections to the line of the program included in the error message. For the environment, you can use the meta-variable __CurrentEnv__ (without arguments) that returns the current environment. In the prelude, the function evaluate uses the empty environment and directly returns the result, or raises an error.

{ apply = f, update = g}.apply X
Update.lens { apply = f, update = g } x

On evaluation, it returns the result of computing f x. On evaluation update, given a new output value v', it computes g { input = x, outputOld = v, outputNew = v' }`` which should return either a Ok (Inputs [x1, x2...]), Ok (InputsWithDiffs [(x1, Just diff1), (x2, Just diff2)]) orErr "error_message". If the former, propagates the new value x1to the expressionXwith differencesdiff1, then on a second round the value x2 to the expressionXwith differencesdiff2. Note that the second version is a wrapper around the first, but can be used to actually _build lenses_. Update.lens2` helps to build 2-arguments lenses, and so-on.

__updateApp__ {fun=FUNCTION,input=ARGUMENT,output=NEWOUTPUT[,oldOutput=OLD OUTPUT][,outputDiff=OUTPUT DIFF]}

Takes a single record defining fun (a function), an input and an new output. For performance, we can also provide the old output oldOutput and the output difference outputDiff. This solves the evaluation problem fun input <-- output. Returns { values = [x1, x2...]}, { values = [x1, x2...], diffs = [Just diff1, Just diff2 ...]} or {error = "error_message"} (same as lenses for chaining) The values x1, x2, ... are the possible new input. Solutions that modify fun are discarded.

You can still update both function and argument by the following trick: __updateApp__ {fun (f,a) = f a, input = (FUNCTION, ARGUMENT), output = NEWOUTPUT}

If necessary, outputOld and oldOut are all synonyms of oldOutput. diffOutput, diffOut and outDiff are all synonyms of outputDiff.

__merge__ original (listModifiedDiff)

It takes an original value (especially useful for functions and lists) and a list of (modified value, Maybe Diff) where each value is associated to a (possible) difference. To compute such differences, use __diff__. Returns the merge of all modifications. Does not prompt on ambiguity.

__diff__ original modified

Computes a Result String (Maybe Diff) (differences) of the differences between the original and the modified value. If you are sure there is no error, you can convert this result to a single Maybe Diff by using the function .args._1

join__ (list of strings)

Performs a reversible join between strings, deleting strings from the list if necessary.

__mbwraphtmlnode__

Wraps a String, an Int or an HTML Element into a list of HTML Elements. Idempotent on any other values. This function is internally used by the HTML interpolation for children. You should not need it.

__mbstylesplit__

Reversibly explodes a string representing a element's style into a list of key/values. Idempotent on any other values. This function is internally used by the attribute interpolation for children. You should not need it.

error string

As its name indicates, stops the execution by raising the given error as a string. Cannot be recovered. Used by Debug.crash

getCurrentTime ()

Return the current time in milliseconds. This function is not reversible.

toggleGlobalBool ()

Flips a global boolean and returns it. This function is not reversible.

__jsEval__ string

Evaluates arbitrary JavaScript using JavaScript's eval. Converts back the value to an interpretable value in our language, i.e. integers to integers, strings to strings, records to records, arrays to list. Can be useful to execute a program with user-defined values (e.g. let username = __jsEval__ "document.getElementById('username')" in ...). This function is not reversible -- use it mostly for non-visible control flow (settings, appearance, language...) or in the apply or update field of a lens`.

Prevent evaluation update changes (freeze)

All the freeze expressions behave like the identity function in the direction of evaluation. In the direction of update, they each have different ways to prevent changes to be back-propagated to the program.

freeze exp
Update.freeze exp

Prevents any changes to be pushed back to the expression (changes to the values of variables and structural changes).

expressionFreeze exp
Update.expressionFreeze exp

Prevents any structural changes to be made to the expression (but allows changes to the values of variables)

Update.sizeFreeze [expressionc computing a list...]

Prevents any insertions and deletions to be made to the given list, but lets through changes to individual elements themselves.

Update.softFreeze exp

Does not prevent changes to the output of the computation, just ignore them. This is useful for value that should never be updated but should not prevent the update to succeed.

String.update.freezeRight [expressionc computing a string]
String.update.freezeLeft [expressionc computing a string]

Blocks any changes to a string is not an insertion to the left (resp. right) of it.

transient and ignore elements/attributes

If an attribute's name starts with transient, the update algorithm will treat it like it does not even exists. Same for elements whose tagName is transient. If an attribute's name starts with ignore, the update algorithm will not propagate changes made to it.

Therefore, the code should not produce transient elements or attributes, but they should be created either by third-party tools (e.g. toolbar) or scripts inside the generated document. ignore attributes not be created from scripts but be already defined in the code.

If needed in the future, we could add other elements (e.g. ignore) or attributes decribing if the element or some attributes are transient or ignorable.

Comments and Options

Comments are part of whitespace and can be one-line -- Comment or nested multi-line {- This is {-a-} comment -}. Options are one-line comments immediately starting with "#", then a keyword, then a value.

  e  ::=  ...
      |   --single-line-comment; e
      |   --# option: value; e

Options are separated by expressions by a newline (the semicolon above is actually a newline).

Html literals with interpolation

Most HTML and SVG is valid in our language, except for comments (Elm would not allow use to define them) and parameters without quotes (they are considered as variables).

  e ::= node
  
  node  ::= <ident attributes>child*</ident>
          | <ident>                              -- if the indent is a void element (br, img, ...)
          | <ident attributes/>                  -- if the element is auto-closing (svg tags only)
          | <@e attributes>child*</@>
  
  attributes ::= ident1=e1 ... identn=en         -- expressions must not contain spaces.
               | attributes @e attributes        -- in this case, e should return a list of attributes, i.e. [["class", "d"]]
  
  child ~=  @@                                   -- for the @ symbol
          | @i                                   -- inserts a node, a list of nodes, a string or a number.
          | innerHTML text
          | node
  i ::= variable {.identifier}* { (e) | tuple | record | list}* [ '<|'   v | i ]
          -- i is parsed without in-between spaces.
     |  (e)                                      -- If you use top-level parentheses @(e), nothing will be parsed after ')'

Some samples of what kind of interpolation is possible:

Html syntax Code equivalent
<h1 id=x>Hello</h1> ["h1", [["id", x]], [["TEXT", "Hello"]]]
<h1 id=x @attrs>Hello @world</h1> ["h1", [["id", x]] ++ attrs, [["TEXT", "Hello "]] ++ world]
<@(t)>Hi</@> [t, [], [["TEXT", "Hi"]]]
let b t x = <b title=t>@x </b> in <div>@b("h")<|<span></span></div> `let b x = ["b",[],[x]] in ["div", [], [b ("h") <

Note that style attributes support both syntax for their values (array of key/values arrays, and strings). In the innerHTML of a tag, you can interpolate string, integers, nodes and list of nodes (there is an automatic conversion).

Standard Prelude

See preludeLeo.elm for the standard library included by every program.

SVG

The result of a program should be an "HTML node." Nodes are either text elements, HTML nodes or SVG nodes, represented as

  h  ::=  ["TEXT", e]
      |   [tagName, attrs, children]

where

  tagName  ::=  "div" | "span" | "script" .... | "svg" | "circle" | "rect" | "polygon" | "text" | ...
  attrs      ::=  [ ["attr1", e1], ..., ["attrn", e2] ]
  children   ::=  [ h1, ..., hn ]

Each attribute expression should compute a pair value in one of the following forms

  [ "fill"          , colorValue     ]
  [ "stroke"        , colorValue     ]
  [ "stroke-width"  , numValue       ]
  [ "points"        , pointsValue    ]
  [ "d"             , pathValue      ]
  [ "transform"     , transformValue ]
  [ anyStringValue  , anyStringValue ]   -- thin wrapper over full SVG format

where

  colorValue      ::=  n                   -- color number [0, 500)
                   |   [n, n]              -- color number and transparency
                   |   [n, n, n, n]        -- RGBA

  pointsValue     ::=  [[nx_1, ny_1], ... ]     -- list of points

  pathValue       ::=  pcmd_1 ++ ... ++ pcmd_n  -- list of path commands

  transformValue  ::=  [ tcmd_1, ..., tcmd_n ]  -- list of transform commands

  pcmd            ::=  [ "Z" ]                            -- close path
                   |   [ "M", n1, n2, n3 ]                -- move-to
                   |   [ "L", n1, n2, n3 ]                -- line-to
                   |   [ "Q", n1, n2, n3, n4 ]            -- quadratic Bezier
                   |   [ "C", n1, n2, n3, n4, n5, n6 ]    -- cubic Bezier
                   |   [ "H", n1 ]
                   |   [ "V", n1 ]
                   |   [ "T", n1, n2, n3 ]
                   |   [ "S", n1, n2, n3, n4 ]
                   |   [ "A", n1, n2, n3, n4, n5, n6, n7 ]

  tcmd            ::=  [ "rotate", nAngle, nx, ny ]
                   |   [ "scale", n1, n2 ]
                   |   [ "translate", n1, n2 ]

See this and this for more information about SVG paths and transforms. Notice that pathValue is a flat list, whereas transformValue is a list of lists.

See preludeLeo.elm for a small library of SVG-manipulating functions.

The Prelude, the examples that come with the editor, the Tutorial, and the Appendix of this technical report provide more details about the above Little encodings of different SVG attributes. You can also peek at the valToAttr function in LangSvg.elm.

Building the Project

In the following, SKETCH-N-SKETCH stands for the directory of the project clone.

  1. Install Elm v0.18
  2. cd SKETCH-N-SKETCH/src
  3. make
  4. Launch SKETCH-N-SKETCH/build/out/index.html

Note: The parser has a performance issue that we have not yet addressed. If the application runs out of stack space, try this.

Note: If the packages are not installed properly, you might see a message like TYPE MISMATCH and that you are expecting Maybe (Dict a ( b, c )) but a value is Maybe (Dict comparable ( a, b )) If that is the case, look at the makefile, the last two commands of elm-stuff/packages may not have been executed properly. This can happen if another software tries to mix with packages installation, such as Dropbox.

Steps to recompile Elm in Windows

Make sure to run these commands with administrator rights.

  • First install Haskell platform 7.10.3 https://www.haskell.org/platform/prior.html

  • Go to a fresh cloned version of https://github.com/elm-lang/elm-platform.git

  • Go to the folder installers

  • Run runhaskell BuildFromSource.hs 0.18 (note the 0.18)

  • Go to the (newly created) folder installers\Elm-Platform\elm-compiler

  • Use Brianโ€™s branch for elm-compile: https://github.com/brianhempel/elm-compiler/tree/faster_exhaustiveness_checker_0.18
    For that you can execute the following command:
    git remote add brian https://github.com/brianhempel/elm-compiler.git
    git fetch brian
    git checkout faster_exhaustiveness_checker_0.18

  • Comment out line 188 in the file installers\BuildFromSource.hs which should look like -- mapM_ (uncurry (makeRepo root)) repos

  • Re-run the install script again in installers\
    runhaskell BuildFromSource.hs 0.18

  • It will throw some fatal errors but thatโ€™s fine.

  • Last step: copy elm-make.exe from installers\Elm-Platform\0.18\elm-make\dist\dist-sandbox-6fb8af3\build\elm-make to replace the elm-make.exe of a fresh 0.18 Elm installation.

Little "REPL"

 % elm-repl
Elm REPL 0.4 (Elm Platform 0.15)
...
> import Eval exposing (parseAndRun)
> parseAndRun "(+ 'hello ' 'world')"
"'hello world'" : String
> parseAndRun "(list0N 10)"
"[0 1 2 3 4 5 6 7 8 9 10]" : String

Adding Examples

To add a new example to the New menu:

  1. Create a file examples/newExample.little for your newExample.

  2. In ExamplesTemplate.elm, add the lines:

    • LITTLE_TO_ELM newExample
    • , makeExample "New Example Name" newExample
  3. From the src/ directory, run make examples.

  4. Launch Sketch-n-Sketch.

Solver Server

For solving complicated formulae or multi-equation systems, Sketch-n-Sketch relies on an external computer algebra system (REDUCE). A solver server exposes REDUCE over the Websockets protocol.

To use Sketch-n-Sketch locally, you do not need to run the solver serverโ€”it will try to connect to our public solver server.

However, if you want to run the solver server locally:

  1. Download websocketd, e.g. with $ brew install websocketd
  2. Make sure you have any version of Ruby installed, check with e.g. $ ruby --version
  3. $ cd solver_server
  4. $ make test_reduce This will download, build, and test REDUCE.
  5. $ make run_server

If a local server is running, Sketch-n-Sketch will try to connect to it first.

Running Tests

If you hack on Sketch-n-Sketch, there are some tests to run. Writing more tests is, of course, encouraged.

Run once:

$ ./tests/test.sh

Run when files change (requires fswatch):

$ ./watchtest

To run only tests with a certain string in their name, set SNS_TESTS_FILTER:

$ SNS_TESTS_FILTER=unparser ./watchtest

To write a new test, make a function of type () -> String named somethingTest in a tests/myTests.elm file. If the function returns the string "ok" it is considered a passing test, otherwise the returned string will be displayed as a failure message.

You can also return a list of test functions, () -> List (() -> String), and each test will be run individually.

See existing tests for examples.

Adding/Removing Elm Packages

If you add or remove a package from the project, the package list for the tests needs to be updated as well. Simply run node tests/refresh_elm-packages.js to copy over the main elm-packages.json into the tests directory.

sketch-n-sketch's People

Contributors

brianhempel avatar florence avatar gracelu avatar jalberz avatar justinlubin avatar mhspradlin avatar mikaelmayer avatar nickcollins avatar ravichugh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sketch-n-sketch's Issues

Misc Deuce TODOs

  • X button in pop-up windows (deuce, right-click, config panel).

  • Restore Deuce selection state on Undo.

  • Issue with text-selection. Hold Shift and press an arrow key to perform an Ace text selection. A Deuce polygon appears.

  • (let p e1 e2) target positions: The whitespace between p and e1 is treated specially, with all characters up to the first newline (if any) dedicated to after-p, and the rest to before-e1. Instead, each polygon should be mapped to a set of code objects (specifically, white space objects in this case), and selection sets should be interpreted as the Cartesian product of the selected code object sets.

Error while updating

C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:576
throw new Error(
^

Error: Ran into a Debug.crash in module UpdateUtils on line 2109
The message provided by the code author is:

Expected only at most one modification at the end of a list, got (11,11,11,[(11,ListElemInsert 1)],[(11,ListElemInsert 1)])
at C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:576:9
at C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:54811:12
at C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:63:33
at A6 (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:122:25)
at Function.func (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:62332:20)
at A5 (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:115:11)
at Function.func (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:62607:25)
at A8 (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:133:11)
at Function.func (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:62767:10)
at A5 (C:\Users\Mikael\AppData\Roaming\npm\node_modules\http-server-editor\node_modules\sketch-n-sketch\sns.js:115:11)

Strange Loop Milestone

Novel Stuff

  • Basic Replicate
  • Solver
  • Value Locking
  • More constraints (?)

Other Improvements

  • Remove "Edit Code"
  • Bounding box for groups
  • Drag group by dragging parts
  • Group pluck fix
  • Parse Errors
  • Type System
  • Nicer runtime error handling (?)
  • Text box shape
  • Layers (?)
  • Upgrade to Elm 0.17

function names cannot contain "def" as prefix

If we try to define a function whose name contains "def" as a prefix, the parser will throw a
Error while parsing 'top-level non-recursive def binding'

For example, (def defaultId (\x x)) (defaultId 1) causes the parse error mentioned above.

Incorrect parsing of "as" keyword

f assignment = 1
<h1>@(signment)</h1>

displays

1

which is obviously incorrect. The "as" keyword should have never been parsed here.

Swap Expressions Stack Overflow

Swap Expressions times out on this program when selecting the second two points.

(def point3 @ [x3 y3] ([202 389] : Point))

(def point @ [x y] ([65 437] : Point))

(def point2 @ [x2 y2] ([ (+ (/ x 1.5) (/ x3 3)) (+ (/ y 1.5) (/ y3 3))] : Point))

(svg [
])

screen shot 2017-09-16 at 8 14 33 pm

We are trying to define something in terms of itself: the problem is in maybeSatisfyUniqueNamesDependenciesByTwiddlingArithmetic. (Cycle detection in liftDependenciesBasedOnUniqueNames is working correctly.)

Relate menu preview freeze the application

I tried to create a logo using Sketch'n Sketch (on the branch value-editor, but it's not important I think)
The logo is composed of a black rectangle on the left and a white rectangle on the right, with yellow lines on the black rectangle.
At some point I wanted to align the right sides of the yellow rectangles by making them equal, I hold shift, selected two alignments, and went to the menu to make them equal. When the menu opened, I accidentally went on "Relate" and it made the whole application to freeze.

I may have accidentally selected one more element. But freezing the application is still a bug. What part of Sketch'n Sketch should I investigate to resolve this potential bug?

image

entering edit mode inserts an e

When the canvas is active (with the fancy code box) entering edit mode by pressing 'e' works, but then the 'e' is also inserted. I would expect that not to happen (and it's quite annoying). Using Chrome Version 44.0.2403.89 Ubuntu 15.04 (64-bit)

Build instructions

I was trying to get started adding text to the things you can manipulate in sketch-n-sketch. I was also hoping this would motivate me to learn about compilers and functional programming via Elm. I can't figure out how to build it locally. What I've done:

  1. Successfully ran make in src directory
  2. Installed fswatch
  3. Tried to run .\makewatch

What else am I supposed to do? Also, is it okay I'm using Elm 18.0?

Codegen breaks #options

Steps to replicate:

  1. Open the example Thaw/Freeze. The rectangle has its vertical axis frozen.
  2. Draw another rectangle in the canvas using the rectangle tool.
  3. The original rectangle no longer has its vertical axis frozen.

Make Equal by Copying Stack Overflow

Make Equal by Copying times out on this program when selecting the second two points.

(def point3 @ [x3 y3] ([202 389] : Point))

(def point @ [x y] ([65 437] : Point))

(def point2 @ [x2 y2] ([ (+ (/ x 1.5) (/ x3 3)) (+ (/ y 1.5) (/ y3 3))] : Point))

(svg [
])

screen shot 2017-09-16 at 8 14 33 pm

We are trying to define something in terms of itself: the problem is in maybeSatisfyUniqueNamesDependenciesByTwiddlingArithmetic. (Cycle detection in liftDependenciesBasedOnUniqueNames is working correctly.)

[Feature request] Make clicking on the editor/canvas switch between "Edit/Run Code"

Even in the demo videos I've seen a few "oops, forgot to click the 'edit code'-button" moments, and you designed the program ;)

As far as I can see, there is no ambiguity of intent when clicking on either side, so why not remove the need for a superfluous click on the run/edit code button? This would reduce the "friction" of the editing experience even further!

(note: I'm not suggesting that the button is removed, because it is not immediately obvious that clicking on either side would switch)

Nicely handle direct manipulations when code is dirty

Right now any code changes are just discarded.

This could be a source of frustration.

Better options:

  • If code is dirty and output side is clicked, run the dirty code first before doing anything.
  • Do some fancy code diffing to apply the DM change to the dirty code.

Source code for tutorials

Where is the source code for the Sketch-n-Sketch tutorials? They're out of date and I would like to propose some amendments to them.

Additionally, there is no longer a drop-down for the examples.

Lifting bug in "Create Function From Arguments"

Probably a problem with replacement order: EId to lift before is missing from the program or something.

screen shot 2017-09-16 at 7 29 56 pm

screen shot 2017-09-16 at 7 30 10 pm

Resulting program should have something like (def [x y] [150 148]) at the top level.

Add output tools menu

Should be similar to the Code Tools menu with similar architecture (requirements, etc.).

v0.6.2 release fails with "maximum call stack size exceeded"

The elm-lang.org home page links to http://ravichugh.github.io/sketch-n-sketch/releases/latest/ which redirects to http://ravichugh.github.io/sketch-n-sketch/releases/v0.5.2/. The latter fails for me almost immediately with the error "Maximum call stack size exceeded" when I run it from Chrome (53.0.2785.116) on Mac OS X on a machine with 16GB RAM. When run from Firefox on the same machine it works, or at least starts up OK.


Ed. note: Duplicate of #56, #93.

HtmlParser for <script>

Currently, if I have dynamically added code:e

<script>
document.body.append("<img src='" + url + "'>")
</script>

this will create trouble because it thinks that <img is a tag to parse.
We should only stop script parsing (and same for style) when </script> is encountered.

Improve target positions

(let p e1 e2) target positions: The whitespace between p and e1 is treated specially, with all characters up to the first newline (if any) dedicated to after-p, and the rest to before-e1. Instead, each polygon should be mapped to a set of code objects (specifically, white space objects in this case), and selection sets should be interpreted as the Cartesian product of the selected code object sets.

Build process for dev branch

I was talking to Justin/Ravi and they told me all the cool things happening on the dev branch, so I wanted to try it out. However, each time I try to run make in sketch-n-sketch/src on the dev branch, it uses up all my 15 GB of RAM on my Ubuntu machine. Is there a new build process?

FastParser performance issues

Here's a series of small examples that demonstrate FastParser performance issues. Try running the program [], then [[]], then [[[]]], etc., viewing the "FastParser.parseE milliseconds" output in the console.

The numbers I got (in milliseconds) are listed below.

I tried moving lazy <| \_ -> list (FastParser line 1278) higher up in the oneOf list. This improves performance only slightly; the last example below runs in 48s instead of 61s.

[
]

2

[[
]]

3

[[[
]]]

7

[[[[
]]]]

16

[[[[[
]]]]]

25

[[[[[[
]]]]]]

50

[[[[[[[
]]]]]]]

93

[[[[[[[[
]]]]]]]]

190

[[[[[[[[[
]]]]]]]]]

361

[[[[[[[[[[
]]]]]]]]]]

727

[[[[[[[[[[[
]]]]]]]]]]]

1482

[[[[[[[[[[[[
]]]]]]]]]]]]

3044

[[[[[[[[[[[[[
]]]]]]]]]]]]]

6264

[[[[[[[[[[[[[[
]]]]]]]]]]]]]]

14621

[[[[[[[[[[[[[[[
]]]]]]]]]]]]]]]

29158

[[[[[[[[[[[[[[[[
]]]]]]]]]]]]]]]]

61183



Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.