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

slightly more precise types for format nodes #97

Merged
merged 3 commits into from
Feb 15, 2023
Merged
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
2 changes: 1 addition & 1 deletion src/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class Emitter {
}

emitUnderscore(node: UnderscoreNode) {
this.wrapFragment('var', node.contents);
this.str += `<var>${node.contents}</var>`;
}

emitTag(tag: OpaqueTagNode | CommentNode | TagNode) {
Expand Down
8 changes: 4 additions & 4 deletions src/node-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,25 @@ export type TextNode = {

export type StarNode = {
name: 'star';
contents: FragmentNode[];
contents: (TextNode | CommentNode | TagNode)[];
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is a breaking change anyway, is there sufficient reason to continue supporting comments and tags inside *, `, and ~ formatting wrappers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This PR is breaking in the sense of requiring integration work in ecmarkup, but not in the sense of requiring any specifications to change. Whereas prohibiting tags inside of * would actually be a breaking change for at least Temporal. Since I've already written the code necessary to support the more complicated types there's not that much to be gained by restricting these and forcing Temporal to adapt, I think.

Copy link
Contributor

@gibson042 gibson042 Jan 30, 2023

Choose a reason for hiding this comment

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

Fair enough. I've opened tc39/proposal-temporal#2494 against Temporal regardless, and don't see any offending text in either ecma262 or ecma402. It might also make a good linter check, but that's obviously not necessary.

And if the functionality is worth keeping, it should probably be documented at https://github.com/tc39/ecmarkdown#inline-formatting .

Copy link
Contributor Author

@bakkot bakkot Jan 31, 2023

Choose a reason for hiding this comment

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

it should probably be documented at

It is, I think? The constraint on _ is "cannot contain whitespace or other formatting characters", whereas the constraint on * is "cannot contain asterisks", for example.

Edit: wait, no, that's entirely the wrong statement.

location: LocationRange;
};

export type UnderscoreNode = {
name: 'underscore';
contents: FragmentNode[];
contents: string;
location: LocationRange;
};

export type TickNode = {
name: 'tick';
contents: FragmentNode[];
contents: (TextNode | CommentNode | TagNode)[];
location: LocationRange;
};

export type TildeNode = {
name: 'tilde';
contents: FragmentNode[];
contents: (TextNode | CommentNode | TagNode)[];
location: LocationRange;
};

Expand Down
17 changes: 15 additions & 2 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
OrderedListNode,
OrderedListItemNode,
UnorderedListItemNode,
FormatNode,
} from './node-types';

// TODO types for escapeHtml
Expand Down Expand Up @@ -283,11 +284,14 @@ export class Parser {
return this.finish({ name: 'text', contents }, undefined, endLoc);
}

parseFormat(format: Format, opts: ParseFragmentOpts) {
parseFormat(
format: Format,
opts: ParseFragmentOpts
): (TextNode | CommentNode | TagNode | FormatNode)[] {
const startTok = this._t.next() as FormatToken;
let contents: (TextNode | CommentNode | TagNode)[] = [];

if (startTok.name === 'underscore') {
if (format === 'underscore') {
if (this._t.peek().name === 'text') {
contents = [this._t.next() as TextNode];
}
Expand Down Expand Up @@ -336,6 +340,15 @@ export class Parser {
} else {
return [this.finish(ntNode, start, end)];
}
} else if (format === 'underscore') {
return [
this.finish(
// the cast is justified by the check at the start of this function
{ name: 'underscore', contents: (contents as [TextNode])[0].contents },
start,
end
),
];
}

return [this.finish({ name: format, contents }, start, end)];
Expand Down
2 changes: 1 addition & 1 deletion src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const childKeys = {
algorithm: ['contents'],
text: [],
star: ['contents'],
underscore: ['contents'],
underscore: [],
tick: ['contents'],
tilde: ['contents'],
pipe: [],
Expand Down