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

ink v1.1 ~ inkjs v2.2 #986

Merged
merged 40 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e34cc1e
porting all new tests
smwhr Oct 18, 2022
c86068d
linter
smwhr Oct 18, 2022
ca0173a
fix list contains 0
smwhr Oct 18, 2022
7a618c5
added HasIntersection
smwhr Oct 18, 2022
aa90913
Contains -> has
smwhr Oct 18, 2022
f1fccf9
port 2 Command Controls definition files
smwhr Oct 18, 2022
d0799ce
port choice class
smwhr Oct 18, 2022
da980d6
oops wrong file
smwhr Oct 18, 2022
c836cb1
Merge branch 'v1.1/commands-serializer' into v1.1/choice-class
smwhr Oct 18, 2022
530d557
merge in
smwhr Oct 19, 2022
1cecb22
Merge branch 'v1.1/empty-contains' into v1.1-runtime
smwhr Oct 19, 2022
7b20a01
avengers assemble
smwhr Oct 19, 2022
e77b13e
linter
smwhr Oct 19, 2022
c88de92
porting 1131145
smwhr Oct 20, 2022
c34457f
compiler/InkParser/InkParser.cs
smwhr Oct 20, 2022
53b1b06
compiler/ParsedHierarchy/Tag.cs
smwhr Oct 20, 2022
3dbb454
compiler/ParsedHierarchy/Wrap.cs
smwhr Oct 20, 2022
2b3de5e
linter
smwhr Oct 20, 2022
452f8a1
compiler/InkParser/InkParser_Tags.cs
smwhr Oct 20, 2022
9e0ab8a
linter
smwhr Oct 20, 2022
33a44b3
compiler/InkParser/InkParser_Choices.cs
smwhr Oct 20, 2022
895e800
compiler/InkParser/InkParser_Content.cs
smwhr Oct 20, 2022
073b0ed
compiler/InkParser/InkParser_Divert.cs
smwhr Oct 20, 2022
d412489
compiler/InkParser/InkParser_Logic.cs
smwhr Oct 20, 2022
85d2d5a
compiler/StringParser/StringParserState.cs
smwhr Oct 20, 2022
455177a
compiler/ParsedHierarchy/TunnelOnwards.cs
smwhr Oct 20, 2022
00b61bb
typos
smwhr Oct 20, 2022
952ab96
C#
smwhr Oct 20, 2022
d17354e
linter
smwhr Oct 20, 2022
3f47dcf
fixed all tests
smwhr Oct 20, 2022
7422bb9
linter
smwhr Oct 20, 2022
0284a38
Merge remote-tracking branch 'y-lohse/master' into v1.1-compiler
smwhr Oct 21, 2022
e47d7eb
version + fix inkjs-compiler
smwhr Oct 21, 2022
3aef5e4
port lookAheadSafe = true
smwhr Oct 21, 2022
a511db7
from 13 to 6 linter warnings
smwhr Oct 21, 2022
84fe3b1
port lookAhead default params
smwhr Oct 21, 2022
1240fd6
Merge pull request #985 from smwhr/v1.1-compiler
smwhr Oct 21, 2022
a6b81f8
Update version comparison table
smwhr Oct 21, 2022
7c5b97f
Update README.md
smwhr Oct 21, 2022
53e806f
Delete test.ts
smwhr Oct 21, 2022
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
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,22 @@ See [Differences with the C# Compiler](docs/compiler-differences.md).

## Compatibility table

| _inklecate_ version | _inkjs_ version |
| :-----------------: | :-------------: |
| 0.3.5 – 0.4.0 | 1.0.0 – 1.1.0 |
| 0.4.1 – 0.5.0 | 1.1.1 – 1.1.3 |
| 0.5.1 | 1.2.0 |
| 0.6.0 | 1.3.0 |
| 0.6.1 | 1.4.0 – 1.4.1 |
| 0.6.2 | 1.4.2 |
| 0.6.3 | 1.4.3 |
| 0.6.4 | 1.4.4 – 1.4.6 |
| 0.7.0 | 1.5.0 – 1.5.1 |
| 0.7.1 | 1.5.2 |
| 0.7.2 – 0.7.4 | 1.6.0 |
| 0.8.0 – 0.8.1 | 1.7.1 – 1.7.2 |
| 0.8.2 | 1.8.0 – 1.9.0 |
| 0.8.3 | 1.10.0 – 1.10.5 |
| 0.9.0 | 1.11.0 |
| 1.0.0 | 2.0.0 |
| _inklecate_ version | _inkjs_ version | _json_ version |
| :-----------------: | :-------------: | :------------: |
| 0.3.5 – 0.4.0 | 1.0.0 – 1.1.0 | 18 |
| 0.4.1 – 0.5.0 | 1.1.1 – 1.1.3 | |
| 0.5.1 | 1.2.0 | |
| 0.6.0 | 1.3.0 | |
| 0.6.1 | 1.4.0 – 1.4.1 | |
| 0.6.2 | 1.4.2 | |
| 0.6.3 | 1.4.3 | |
| 0.6.4 | 1.4.4 – 1.4.6 | |
| 0.7.0 | 1.5.0 – 1.5.1 | |
| 0.7.1 | 1.5.2 | |
| 0.7.2 – 0.7.4 | 1.6.0 | |
| 0.8.0 – 0.8.1 | 1.7.1 – 1.7.2 | |
| 0.8.2 | 1.8.0 – 1.9.0 | |
| 0.8.3 | 1.10.0 – 1.10.5 | |
| 0.9.0 | 1.11.0 | 19 |
| 1.0.0 | 2.0.0 - 2.1.0 | 20 |
| 1.1.1 | 2.2.0 | 21 |
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "inkjs",
"version": "2.1.0",
"version": "2.2.0",
"description": "A javascript port of inkle's ink scripting language (http://www.inklestudios.com/ink/)",
"main": "dist/ink-full.js",
"types": "ink.d.ts",
Expand Down
44 changes: 37 additions & 7 deletions script/inkjs-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,19 @@ if(jsonStory && write){
}

if(jsonStory && play){
const prompt = readline.createInterface({
const rl = readline.createInterface({
input: process.stdin, //or fileStream
output: process.stdout
});

const prompt = () => {
return new Promise<string>((resolve, reject) => {
rl.question('?> ', (answer: string) => {
resolve(answer)
})
})
}

const play = async () =>{
const story = new Story(jsonStory);

Expand All @@ -78,18 +87,39 @@ if(jsonStory && play){

for (let i=0; i<story.currentChoices.length; ++i) {
const choice = story.currentChoices[i];
process.stdout.write( `${i+1}: ${choice.text}\n` );
process.stdout.write( `${i+1}: ${choice.text}` );
if( story.currentChoices[i].tags !== null
&& story.currentChoices[i].tags!.length > 0){
process.stdout.write( " # tags: " + story.currentChoices[i].tags!.join(", ") );
}
process.stdout.write("\n")
}
process.stdout.write("?> ");
for await (const line of prompt) {
const choiceIndex = parseInt(line) - 1;
story.ChooseChoiceIndex(choiceIndex);
}
do{
const answer: string = await prompt();
if(answer.startsWith("->")){
const target = answer.slice(2).trim()
try{
story.ChoosePathString(target)
break;
}catch(e){
process.stdout.write(e.message + '\n');
}
}else{
const choiceIndex = parseInt(answer) - 1;
try{
story.ChooseChoiceIndex(choiceIndex);
break;
}catch(e){
process.stdout.write(e.message + '\n');
}
}
}while(true);
}while(true);

}
play().then(()=>{
process.stdout.write("\nDONE.")
process.stdout.write("DONE.\n")
process.exit(0);
});

Expand Down
1 change: 1 addition & 0 deletions src/compiler/Parser/CustomFlags.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export enum CustomFlags {
ParsingString = 0x1,
TagActive = 0x2,
}
142 changes: 85 additions & 57 deletions src/compiler/Parser/InkParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
} from "./StringParser/StringParser";
import { StringParserElement } from "./StringParser/StringParserElement";
import { Tag } from "./ParsedHierarchy/Tag";
import { Tag as RuntimeTag } from "../../engine/Tag";
import { Text } from "./ParsedHierarchy/Text";
import { TunnelOnwards } from "./ParsedHierarchy/TunnelOnwards";
import { VariableAssignment } from "./ParsedHierarchy/Variable/VariableAssignment";
Expand Down Expand Up @@ -227,6 +226,14 @@ export class InkParser extends StringParser {
this.SetFlag(Number(CustomFlags.ParsingString), value);
}

get tagActive(): boolean {
return this.GetFlag(Number(CustomFlags.TagActive));
}

set tagActive(value: boolean) {
this.SetFlag(Number(CustomFlags.TagActive), value);
}

public readonly OnStringParserError = (
message: string,
index: number,
Expand Down Expand Up @@ -441,6 +448,8 @@ export class InkParser extends StringParser {
// * "Hello[."]," he said.
const hasWeaveStyleInlineBrackets: boolean = this.ParseString("[") !== null;
if (hasWeaveStyleInlineBrackets) {
this.EndTagIfNecessary(startContent);

const optionOnlyTextAndLogic = this.Parse(
this.MixedTextAndLogic
) as ParsedObject[];
Expand All @@ -451,6 +460,8 @@ export class InkParser extends StringParser {

this.Expect(this.String("]"), "closing ']' for weave-style option");

this.EndTagIfNecessary(optionOnlyContent);

let innerTextAndLogic = this.Parse(
this.MixedTextAndLogic
) as ParsedObject[];
Expand All @@ -461,6 +472,8 @@ export class InkParser extends StringParser {

this.Whitespace();

this.EndTagIfNecessary(innerContent ?? startContent);

// Finally, now we know we're at the end of the main choice body, parse
// any diverts separately.
const diverts: ParsedObject[] = this.Parse(
Expand Down Expand Up @@ -492,10 +505,7 @@ export class InkParser extends StringParser {
innerContent = new ContentList();
}

const tags = this.Parse(this.Tags) as ParsedObject[];
if (tags !== null) {
innerContent.AddContent(tags);
}
this.EndTagIfNecessary(innerContent);

// Normal diverts on the end of a choice - simply add to the normal content
if (diverts !== null) {
Expand Down Expand Up @@ -1011,20 +1021,6 @@ export class InkParser extends StringParser {
this.MixedTextAndLogic
) as ParsedObject[];

// Terminating tag
let onlyTags: boolean = false;
const tags = this.Parse(this.Tags) as ParsedObject[];
if (tags) {
if (!result) {
result = tags;
onlyTags = true;
} else {
for (const tag of tags) {
result.push(tag);
}
}
}

if (!result || !result.length) {
return null;
}
Expand All @@ -1046,9 +1042,16 @@ export class InkParser extends StringParser {
this.TrimEndWhitespace(result, false);
}

// Add newline since it's the end of the line
// (so long as it's a line with only tags)
if (!onlyTags) {
this.EndTagIfNecessary(result);

// If the line doens't actually contain any normal text content
// but is in fact entirely a tag, then let's not append
// a newline, since we want the tag (or tags) to be associated
// with the line below rather than being completely independent.
let lineIsPureTag =
result.length > 0 && result[0] instanceof Tag && result[0].isStart;

if (!lineIsPureTag) {
result.push(new Text("\n"));
}

Expand All @@ -1068,7 +1071,7 @@ export class InkParser extends StringParser {
// Either, or both interleaved
let results: ParsedObject[] = this.Interleave<ParsedObject>(
this.Optional(this.ContentText),
this.Optional(this.InlineLogicOrGlue)
this.Optional(this.InlineLogicOrGlueOrStartTag)
);

// Terminating divert?
Expand All @@ -1084,6 +1087,9 @@ export class InkParser extends StringParser {
results = [];
}

// End previously active tag if necessary
this.EndTagIfNecessary(results);

this.TrimEndWhitespace(results, true);

results.push(...diverts);
Expand Down Expand Up @@ -1224,6 +1230,8 @@ export class InkParser extends StringParser {

diverts = [];

this.EndTagIfNecessary(diverts);

// Possible patterns:
// -> -- explicit gather
// ->-> -- tunnel onwards
Expand Down Expand Up @@ -2616,8 +2624,8 @@ export class InkParser extends StringParser {
return result;
};

public readonly InlineLogicOrGlue = (): ParsedObject =>
this.OneOf([this.InlineLogic, this.Glue]) as ParsedObject;
public readonly InlineLogicOrGlueOrStartTag = (): ParsedObject =>
this.OneOf([this.InlineLogic, this.Glue, this.StartTag]) as ParsedObject;

public readonly Glue = (): Glue | null => {
// Don't want to parse whitespace, since it might be important
Expand All @@ -2635,6 +2643,9 @@ export class InkParser extends StringParser {
return null;
}

let wasParsingString = this.parsingStringExpression;
let wasTagActive = this.tagActive;

this.Whitespace();

const logic = this.Expect(
Expand All @@ -2643,6 +2654,7 @@ export class InkParser extends StringParser {
) as ParsedObject;

if (logic === null) {
this.parsingStringExpression = wasParsingString;
return null;
}

Expand All @@ -2657,6 +2669,19 @@ export class InkParser extends StringParser {

this.Expect(this.String("}"), "closing brace '}' for inline logic");

// Allow nested strings and logic
this.parsingStringExpression = wasParsingString;

// Difference between:
//
// 1) A thing # {image}.jpg
// 2) A {red #red|blue #blue} sequence.
//
// When logic ends in (1) we still want tag to continue.
// When logic ends in (2) we want to auto-end the tag.
// Side note: we simply disallow tags within strings.
if (!wasTagActive) this.EndTagIfNecessary(contentList);

return contentList;
};

Expand Down Expand Up @@ -2710,6 +2735,8 @@ export class InkParser extends StringParser {
this.InnerExpression,
];

let wasTagActiveAtStartOfScope = this.tagActive;

// Adapted from "OneOf" structuring rule except that in
// order for the rule to succeed, it has to maximally
// cover the entire string within the { }. Used to
Expand Down Expand Up @@ -3204,50 +3231,51 @@ export class InkParser extends StringParser {
* Begin Tags section.
*/

private _endOfTagCharSet: CharacterSet = new CharacterSet("#\n\r\\");

public readonly Tag = (): Tag | null => {
public readonly StartTag = (): ParsedObject | null => {
this.Whitespace();

if (this.ParseString("#") === null) {
return null;
}

this.Whitespace();

let sb = "";
do {
// Read up to another #, end of input or newline
const tagText: string =
this.ParseUntilCharactersFromCharSet(this._endOfTagCharSet) || "";
sb += tagText;

// Escape character
if (this.ParseString("\\") !== null) {
const c: string = this.ParseSingleCharacter();
if (c !== "\0") {
sb += c;
}

continue;
}
if (this.parsingStringExpression) {
this.Error(
"Tags aren't allowed inside of strings. Please use \\# if you want a hash symbol."
);
}

break;
} while (true);
let result: ParsedObject | null = null;
if (this.tagActive) {
let contentList = new ContentList();
contentList.AddContent(new Tag(/*isStart:*/ false));
contentList.AddContent(new Tag(/*isStart:*/ true));
result = contentList;
} else {
result = new Tag(/*isStart:*/ true);
}
this.tagActive = true;

const fullTagText = sb.trim();
this.Whitespace();

return new Tag(new RuntimeTag(fullTagText));
return result;
};

public readonly Tags = (): Tag[] | null => {
const tags = this.OneOrMore(this.Tag) as Tag[];
if (tags === null) {
return null;
public EndTagIfNecessary(outputContentList: ParsedObject[] | null): void;
public EndTagIfNecessary(outputContentList: ContentList | null): void;
public EndTagIfNecessary(
outputContentList: ParsedObject[] | ContentList | null
): void {
if (this.tagActive) {
if (outputContentList != null) {
if (outputContentList instanceof ContentList) {
outputContentList.AddContent(new Tag(/*isStart:*/ false));
} else {
outputContentList.push(new Tag(/*isStart:*/ false));
}
}
this.tagActive = false;
}

return tags;
};
}

/**
* End Tags section.
Expand Down
Loading