ScPL (Shortcuts Programming Language)

repository·master·Indexed 43 days ago

https://github.com/pfgithub/scpl

A text-based programming language for writing iOS Shortcuts, allowing developers to build complex shortcuts using code instead of the standard drag-and-drop interface. Version 1.14.0 provides a wide range of actions for data, file manipulation, web interactions, and system settings. It includes a web editor, a VS Code extension, and the scpl-cli for compiling .scpl files into .shortcut files. Note: ScPL does not support iOS 13/14+ actions.

Tokens
137.5K
Snippets
540
Records
631
Agent score
54%

What's inside ScPL

  1. What is ScPL

    master

    ScPL is a programming language designed for writing iOS Shortcuts in text. It provides an alternative to the standard drag-and-drop interface in the Shortcuts app, making it easier to manage large, complex shortcuts by allowing you to copy, paste, and type actions directly.

    Note: ScPL has not been updated to support the new iOS 13/14+ actions. If you require support for newer iOS actions, consider using Jellycuts.

  2. Use ArgLists for multi-line action arguments

    master

    If an action requires many arguments, use an arglist (denoted by a{ ... }) to spread them across multiple lines for better readability. This is particularly useful for complex actions like getfile.

    getfile a{
      service="iCloud Drive"
      showdocumentpicker=false
      filepath="/myfile.txt"
      errorifnotfound=false
    }
  3. Use actions inside other actions and fields

    master

    ScPL allows you to nest actions inside text fields or other fields that accept variables using the \(action) syntax. This creates a 'magic variable' that directly references the result of that nested action without needing to explicitly name it.

    Additionally, you can use actions inside the arguments of other actions to avoid disrupting the main action's input flow. This is useful for conditional logic where you want to check a value without changing the data being passed to the primary action.

    // Nesting an action inside a text field
    Text "My number is \(Number -2.5)"
    
    // Using an action inside another action's argument
    If Equals (Text "Goodbye")
    	ShowResult "If the action input was disrupted, this would run"
    Otherwise
    	QuickLook
    End If
  4. Use the @set macro and Parser Variables

    master

    Parser variables exist only during the ScPL parsing phase and are replaced with their values when the shortcut is generated. They are defined using @set and accessed using @:variableName.

    Parser variables can hold:

    • Simple values (strings, numbers).
    • Lists (e.g., [1, 2, 3]).
    • Actions or lists of actions.
    • Dictionaries of other parser variables (passed via {key:value} syntax).
    // Setting and using a simple variable
    @set varname "value"
    text "value is \(@:varname)"
    
    // Setting a list
    @set list [1, 2, 3]
    list @:list
    
    // Setting an action
    @set myaction (text "hi")
    @:myaction
    
    // Setting a macro that takes input
    @set test (Text @:value)
    @:test{value:"Hi!"}
  5. Use Variable Aggrandizements

    master

    Aggrandizements allow you to transform or access specific properties of a variable using a specialized syntax within GetVariable.

    Supported aggrandizements:

    • as/coerce: Coerce the variable to a specific type (e.g., as:Dictionary).
    • key/forKey: Access a key in a dictionary (e.g., key:myKey).
    • get/getProperty: Access a property (partial support).

    Shortcut Syntax: For dictionary access, you can use the shorthand v:VariableName:KeyName instead of the full {as:Dictionary,key:KeyName} syntax.

    // Full syntax
    GetVariable v:MyVariable{as:Dictionary,key:myKey}
    
    // Shorthand syntax
    GetVariable v:MyDictionary:myKey
  6. How variables work in ScPL

    master

    Variables are prefixed with a type identifier followed by a colon and the name. There are three types:

    • v:: Named variables (e.g., v:MyVar). Use quotes for names with spaces: v:"My Var".
    • mv:: Magic variables (e.g., mv:Magic).
    • s:: Special variables.

    Using Variables

    Variables can be used as direct field values or embedded within strings/barlists using the \(v:VariableName) syntax.

    Text mv:MyMagicVariable
    Text "Backslash parenthesis are used to put a variable inside text, like \(v:ThisVariable)."

    Setting Variables

    • Named Variables: Use the SetVariable action.
    • Magic Variables: Use the -> arrow syntax to mark an action as magical.
    # Setting a named variable
    Text "My text"
    SetVariable "MyVariable"
    ShowResult "My text is \(v:MyVariable)"
    
    # Setting a magic variable
    Text "My text" -> mv:Magic
    ShowResult "Magic! \(mv:Magic)"
    Text "My text"
    SetVariable "MyVariable"
    
    # now you can use it
    ShowResult "My text is \(v:MyVariable)"
  7. Use InputArg to disrupt action input

    master

    The ^(action) syntax, known as InputArg, allows you to provide a specific value to an action that would otherwise use the previous action's output. This effectively 'disrupts' the input chain by injecting a new value into the next action.

    Text "Some text"
    QuickLook ^(Text "Different text")
  8. Use the Nothing action to separate blocks or clear inputs

    master

    The Nothing action (internally identified as is.workflow.actions.nothing) performs no operation and produces no output. It is primarily used for two purposes:

    1. Separation: To visually or logically separate blocks of actions within a workflow.
    2. Input Clearing: To ensure that no input is passed to the subsequent action in a sequence (since InputPassthrough is set to false).

    You can invoke this action using the keyword Nothing or any of its associated keywords: nil, nothing, empty, discard, or clear.

    Nothing 
  9. Configure Request Bodies for GetContentsofURL

    master

    If advanced is true and the method is not GET, you can specify the type of request body using the requestBody argument. The available options are JSON, Form, or File.

    Depending on the chosen requestBody type, you must provide the corresponding data via one of the following arguments:

    • Form: Use formValues (a dictionary) to provide multipart form data. This is useful for uploading files as field values.
    • JSON: Use jSONValues (a dictionary) to provide a JSON object.
    • File: Use file (a variable picker) to provide a specific file to be sent in the request body.

    Note: requestBody and its associated data arguments are only available for non-GET methods.

    // Example: Sending a JSON body
    GetContentsofURL advanced=true method="POST" requestBody="JSON" jSONValues={"key": "value"}
    
    // Example: Sending a Multipart Form
    GetContentsofURL advanced=true method="POST" requestBody="Form" formValues={"field1": "value1"}
  10. Set variables using arrows or assignment

    master

    You can create SetVariable actions using two different syntaxes:

    1. Arrow syntax: Append -> v:VariableName to an action.
    2. Assignment syntax: Use mv:VariableName = action before the action.

    Both methods automatically generate the necessary logic to store the action's output into a named variable.

    // Arrow syntax
    Text "My Text" -> v:MyNamedVariable
    
    // Assignment syntax
    mv:WowMagic = Text "My Text"
  11. Limit the number of items returned by Find Music

    master

    You can restrict the number of music items returned using the limit and getItems arguments.

    • limit: A switch that accepts a boolean (true or false) or a variable.
    • getItems: A stepper number that accepts a number or a variable. This argument is only enabled if limit is set to true.
  12. Workaround for PhoneNumber parameter implementation

    master

    The WFPhoneNumber parameter (type WFPhoneNumberFieldParameter) is not yet fully implemented in ScPL.

    If you need to use this parameter, you can attempt to use a raw value. A suggested workaround is to convert an existing .shortcut file to a .scpl file to extract the specific values you want to use in this parameter.