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

Feature/stim grammar #45

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ upload-experiment.sh

# Ignore the key used for testing purposes
key.txt

# node
node_modules

#vs code
.vscode
80 changes: 44 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,58 +45,66 @@ conditions, you'd need to create four lists.

### Presenting multiple words as one group

By defaut, the boilerplate experiment treats every word in the stimuli as a
group of its own containing one word. Note, in some papers, the terminology for
a group is a segment. Sometimes it is handy to group multiple words together,
to shorten the time it takes to complete the experiment for example. This is
possible, but must be enabled. The file `globals.js` contains another variable:
Previously, when the spr was presenting multiple words as one group/simultaneous, you
needed to separate them by inserting e.g. a `/`, as of now, you have to
specifically create groups yourself and grouping of words is always on. On
the. There are two kinds of groups `{{A group of words that is not recorded}}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the ... (missing word?)

`{{#A group of words that is NOT recorded.}}`. Recorded means that the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove NOT?

RT of this group is logged. Of course it is fine to have just one `{{word}}`
in a {{#group}}. the curly braces and # are stripped from the rendered
output. You should not put word letters etc outside of a group.

All the words of your spr need to be enclosed in **{{**double curly braces**}}**
so the phrase "double curly braces" is presented together. If you want the to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wan the ... to (missing word)

be presented individually, you'll need to make three groups such as

```javascript
const GROUPING_STRING = null;
```
{{double}} {{curly}} {{braces}}
```

To enable grouping you must define a useful delimiter between groups.
A little bit further in the file there's a commented version of this:
#### White space issues

In the example with three groups above, the " " are put outside of the group
as that might be more readable than e.g.

```javascript
const GROUPING_STRING = "/";
```
{{double }}{{curly }}{{braces}}
```

So in order to enable grouping, comment the first version and uncomment
the latter. In theory you can fill out any string instead of the `"/"`
(useful in case you need to use / in a stimulus).
Notice the string is turned into a regular expression in order to split
the stimulus into parts and to remove the `/` in the case described here.
In this example the spaces are embedded inside the groups, both methods are
fine, but the author finds the first method better readable. If you put
none white space characters outside of a group it will be considered a syntax error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understand, maybe add an example?


#### Presenting **bold** and *italic* words or ***both***

Like HTML you can render words in bold or italic like this:

```javascript
re = RegExp(GROUPING_STRING,'gu');
```
{{a word in <b>bold</b> or some words <i>in italic</i>}}
```

So make sure if you are going to be creative, that the expression is valid.
or even both.

### Warning the grouping string is going to be removed as it shouldn't be displayed
```
{{<b><i>Bold and italic</i></b>}}
```

In the stimulus file you should take care that the grouping string is removed
from the stimulus. So you should take in mind how the stimulus would appear
after the grouping string is removed.
However, the syntax for this is more strict than HTML, forgetting to close a bold
or italic tag will result in an error. The bold or you'll have to close the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bold or ... you'll (missing word)

innermost group first and then the outermost group. So the following are errors:

#### Example
1.

```javascript
{
stimulus : "This is/my fantasic stimlus./Don't you think!"
}
```
{{<b><i>Oops close i first</b></i>}}

The "/" will be removed, essentially gluing "is" and "my" together, just like
"stimulus." and "Word".
2.

#### Example improved
{{<b>Oops forgot to close b}}

```javascript
{
stimulus : "This is/ my fantasic stimlus./ Don't you think"
}
If you want then to be partially overlapping you should open a new group

```
{{<b>Bold <i> and italic</i></b> <i>, only italic</i>
```

## Output
Expand Down
7 changes: 7 additions & 0 deletions build.bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit of a silly comment, but I would expect this file to be called build.sh and would be confused seeing a .bash extension

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

# "Compile" grammar.js, from grammar.ne
npx nearleyc -o ./plugins/grammar.js ./plugins/grammar.ne -e spr_grammar

# package it using esbuild
node ./build.mjs
13 changes: 13 additions & 0 deletions build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as esbuild from 'esbuild'

await esbuild.build({
entryPoints: [
'./plugins/jspsych-spr-moving-window.js',
],
bundle:true,
outdir: 'dist',
minify: false,
sourcemap: true,
format: "esm"
})

9 changes: 0 additions & 9 deletions globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,3 @@ const FIX_CHOICES = [' '];
// is on screen.
const FINISH_TEXT_DUR = 3000;

// If no grouping character is selected or if it is null as in this example
// every word is a group of its own: sentences are split on whitespace.
// each word will be a one word group
const GROUPING_STRING = null;
// Or create word groups based on a splitting string
// Create groups using a "/". Note that every occurrence
// of a "/" will lead to presentation as a word group and the a "/" itself
// will not be displayed in the stimulus
//const GROUPING_STRING = "/";
7 changes: 1 addition & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@

<!--maybe one day this plugin will be put in the mainline jsPsych
repository.-->
<script src="plugins/jspsych-spr-moving-window.js"></script>

<script src="main.js"></script>
<script type="module" src="main.js"></script>
<style>
.jspsych-survey-multi-choice-text {
text-align: left !important;
Expand All @@ -40,8 +39,4 @@

</head>
<body></body>
<script>
// see main.js for the main function and experiment timeline
window.addEventListener('load', main);
</script>
</html>
27 changes: 20 additions & 7 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import {
sprMovingWindow,
checkStimuliSyntax
} from './dist/jspsych-spr-moving-window.js'

let jsPsych = initJsPsych({
exclusions: {
min_width : MIN_WIDTH,
min_height : MIN_HEIGHT
}
});

// export jsPsych globally because this is a module now...
// or export jsPsych and import it from the other files.
window.jsPsych = jsPsych

// I liked RandomError too :-)
class SprRandomizationError extends Error {
constructor(message) {
Expand Down Expand Up @@ -38,7 +47,7 @@ let instruction_screen_practice = {

let fixcross = {
type : sprMovingWindow,
stimulus : '+',
stimulus : '{{+}}',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the fixation cross be a "jsPsychHtmlKeyboardResponse"?

choices : FIX_CHOICES,
font_family : "Times New Roman",
font_size : 36,
Expand All @@ -62,7 +71,6 @@ let present_text = {
width : MIN_WIDTH,
height : MIN_HEIGHT,
post_trial_gap : ISI,
grouping_string : GROUPING_STRING,
data : {
id : jsPsych.timelineVariable('id'),
item_type : jsPsych.timelineVariable('item_type'),
Expand Down Expand Up @@ -135,16 +143,16 @@ let end_experiment = {
function randomizeStimuli(table) {
let shuffled = uil.randomization.randomizeStimuli(
table,
max_same_type=MAX_SUCCEEDING_ITEMS_OF_TYPE
MAX_SUCCEEDING_ITEMS_OF_TYPE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was the parameter name removed?

);

if (shuffled !== null)
table = shuffled;
else {
console.error('Unable to shuffle stimuli according constraints.');
let msg = "Unable to shuffle the stimuli, perhaps loosen the " +
"constraints, or check the item_types on the stimuli.";
throw new SprRandomizationError(msg);
console.error('Unable to shuffle stimuli according constraints.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

according to constraints

let msg = "Unable to shuffle the stimuli, perhaps loosen the " +
"constraints, or check the item_types on the stimuli.";
throw new SprRandomizationError(msg);
}

return table; // shuffled table if possible original otherwise
Expand Down Expand Up @@ -209,6 +217,8 @@ function main() {

// Option 1: client side randomization:
let stimuli = pickRandomList();
checkStimuliSyntax(PRACTICE_ITEMS);
checkStimuliSyntax(stimuli.table);
kickOffExperiment(getTimeline(stimuli.table), stimuli.list_name);

// Option 2: server side balancing:
Expand Down Expand Up @@ -280,3 +290,6 @@ function findList(name) {
}
return list;
}

// start the experiment
window.addEventListener('load', main);
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "jspsych-spr-mw",
"version": "1.0.0",
"description": "## A self paced reading with moving window experiment using jsPsych",
"main": "main.js",
"scripts": {
"test": "./build.bash && node ./dist/test.js",
"build": "./build.bash"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"moo": "^0.5.2",
"nearley": "^2.20.1"
},
"devDependencies": {
"esbuild": "0.24.0"
}
}
6 changes: 6 additions & 0 deletions plugins/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

# ignore grammar.js as it is generated from grammar.ne using nearley
grammar.js

# a test script
test.js
Loading