preventing dashed sentence spillover / centering sentences

PennController for IBEX Forums Support preventing dashed sentence spillover / centering sentences

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #7008
    Avery
    Participant

    Hi there,

    I have a bit of a dual issue with dashed sentence appearance. When using base Ibex’s dashed sentence function, we found that longer sentences were spilling over onto two lines. We wanted to prevent that, however, and keep a single sentence to a single line.

    I snooped around on the forums and found this function you’d suggested for someone else, and I was able to use it as a custom function using Ibex’s dashed sentence, that I changed a little for our needs (the one in my code below)

    dashed = (name,sentence) => [
        newText(name,"").css({display:'flex','flex-direction':'row','white-space':'nowrap','line-height':'2em','max-width':'100%'}).print()
        ,
        ...sentence.split(/[\s\t<>]+/).map( (w,i) => (w=="br"?
                newText("").css("width","100vw").print(getText(name))
                :
                newText(name+'-'+i, w.replace(/([^.,?:;!]+)/g,"<span class='DashedSentence-ospan'><span class='DashedSentence-ispan'>$1</span></span>"))
                    .css("margin","0em 0.2em")
                    .print(getText(name))
        ))
        ,
        ...sentence.split(/[\s\t<>]+/).map((w,i)=>(w!="br"?[newKey(i+"-"+w," ").log().wait(),getText(name+'-'+i).text(w.replace(/_/g," "))]:null))
    ]

    There are a couple downsides to this: one is that the above function doesn’t re-mask the previously-revealed words (for some reason, I haven’t been successful in getting that to work). Also, though, centering the text is an issue. As words are revealed, they change in width from the masked version, and as it works to keep the text centered, it kind of pops around on the screen, which isn’t ideal.

    Is there a way to either more easily prevent the out-of-the-box dashed sentences function from spilling text over, and if not, what could I do to improve this function for the issues above?

    Thank you in advance!

    #7009
    Jeremy
    Keymaster

    Hi,

    Try this:

    newController("DashedSentence",{s:"This is a rather long sentence but hopefully this will be long enough that it should insert linebreaks into narrow containers"})
        .css("white-space","nowrap")
        .center()
        .print()
        .wait()

    Note that since you don’t want any linebreak, your sentence might overflow horizontally from the page area if it is too long

    Jeremy

    #7010
    Jeremy
    Keymaster

    I re-read your message and realized that you might want to print multiple sentences, but only one per line

    Here’s a suggestion, it will split your string at every ., ? or ! followed by a space and print each sentence on a new, centered line:

    dashed = (name,sentences) => [
        newText(name,"").size("100vw","auto").center().css("text-align","center").print()
        ,
        ...sentences.split(/(?<=[\.!\?])[\s\t]/).map( (s,n) => [
            newText(name+"-s"+n,"")
                .css({display:'inline-block','line-height':'2em','white-space':'nowrap'})
                .print(getText(name))
            ,
            ...s.split(/[\s\t]+/).map( (w,i) =>
                    newText(name+'-s'+n+"-"+i, w.replace(/([^.,?:;!\s])/g,"<span class='DashedSentence-ospan'><span class='DashedSentence-ispan'>$1</span></span>"))
                        .css("margin","0em 0.25em")
                        .print(getText(name+"-s"+n))
            )
        ] ).flat()
        ,
        newKey(name+'-start', " ").log().wait() // first keypress, to reveal first word
        ,
        ...sentences.split(/(?<=[\.!\?])[\s\t]/).map( (s,n) => [
            ...s.split(/[\s\t]+/).map((w,i)=>[
                getText(name+'-s'+n+'-'+i).text(w) // reveal chunk
                ,
                newKey('s'+n+'-'+i+"-"+w," ").log().wait() // wait for keypress
                ,
                getText(name+'-s'+n+'-'+i).text(w.replace(/([^.,?:;!\s])/g,"<span class='DashedSentence-ospan'><span class='DashedSentence-ispan'>$1</span></span>")) // hide chunk
            ] ).flat()
        ] ).flat()
    ]

    Jeremy

    #7011
    Avery
    Participant

    Thank you so much, Jeremy!

    I have one more question for you. It’s about group selection. I know PCIbex is intended to automatically split participants by group, but it doesn’t seem to be doing so for our experiment. Critically, participants in one group receive different instructions. The CSV file looks like this:

    ItemNumber,Sentence,compQ,corrAnsw,itemType,Group
    1,"Instructions1",NA,NA,instructions,A
    1,"Instructions2",NA,NA,instructions,B
    0,"test sentence 1",1,item,A
    1,"test sentence 2",0,item,A

    In the actual instructions block, the critical manipulation is here:

    
    Template(PennController.GetTable("fulldesign.csv")
        .filter( variable => variable.itemType == "instructions" ),
        variable =>
    newTrial("direcitons",    
    newText("instruc",variable.Sentence)
            .bold()
            .print()
    )
    )
        

    But it always loads the same sentence on refreshing. Is this intended behavior?

    #7012
    Jeremy
    Keymaster

    By default the internal counter that controls automatic group assignment is only incremented upon completion: https://doc.pcibex.net/advanced-tutorial/10_counterbalancing.html#controlling-group-assignment

    If you want to change that, you can use SetCounter

    Jeremy

    #7013
    Avery
    Participant

    Thank you so much! I guess in that case I have one final question (sorry).

    I added SetCounter(“counter”, “inc”, 1) to the beginning of the experiment. I’d thought that would fix the issue, but what I’m realizing now is that even when I refresh the experiment, the experiment always seems to be loading Sentence 2 (from Group B). The CSV file is identical to what I pasted above, but with “sentence 1” and “sentence 2” replaced by actual sentences, and more test trials below.

    Here’s a more complete version of the relevant portion:

    Template(PennController.GetTable("fulldesign.csv")
        .filter( variable => variable.itemType == "instructions" ),
        variable =>
    newTrial("directions",
         // Automatically print all Text elements, centered
        newText("<p>Welcome! Please read the following information carefully.</p>")
            .print()
        ,
        newText("instruc",variable.Sentence)
            .bold()
            .print()
        ,
        newText("<p>Please enter your Amazon Worker ID below, and then click the button below to view some practice examples before the experiment starts. Note that your Amazon Worker ID is not your email. You can find your Worker ID in the MTurk Dashboard.</p>")
            .print()
        ,
        newTextInput("inputID", "")
            .center()
            .css("margin","1em")
            .log()
        ,  
        newText("idInst", "Amazon Worker ID:"),
        newCanvas(500,75)
            .add(   0 , 20 , getText("idInst") )
            .add( 150,  0, getTextInput("inputID") )
            .print()
        ,    
        newButton("validate","I have read the above information")
            .center()
            .print()
            .wait(
                getTextInput("inputID").test.text(/[^\s]+/)  
                    .failure( newText("Please enter your Amazon Worker ID.").color("red").print() )
            )
    )
    )

    Any advice is appreciated!

    #7015
    Jeremy
    Keymaster

    Hi,

    Did you reference the SetCounter trial in your Sequence?

    Here’s a demo: https://farm.pcibex.net/r/LiCSni/

    Jeremy

    #7018
    Avery
    Participant

    Hi Jeremy,

    I did not–that was the issue, I was missing “Counter” in the Sequence list.

    Thank you so much for all of your help with this!

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.