Skip to content

add a visual indicator to AC bodies#684

Merged
bakkot merged 4 commits intomainfrom
mark-ac-bodies
Mar 30, 2026
Merged

add a visual indicator to AC bodies#684
bakkot merged 4 commits intomainfrom
mark-ac-bodies

Conversation

@michaelficarra
Copy link
Copy Markdown
Member

Fixes #682.

image image

Disclaimer: I used AI in the process of making this PR.

src/Algorithm.ts Outdated
}

for (const step of node.querySelectorAll('li')) {
if (/\ba new Abstract Closure\b/.test(ownTextContent(step))) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There are other phrasings, e.g. "a new Job Abstract Closure".

We have an existing test here. You could factor it out and use it in both places instead of duplicating.

(There's another test here, come to think, which should probably use the "when called" test; that captures non-AC code blocks like read-modify-write modification function as well.)

Copy link
Copy Markdown
Member

@gibson042 gibson042 Mar 28, 2026

Choose a reason for hiding this comment

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

The / performs the following steps (atomically )?when called:$/ test seems best to me, and I like the idea of factoring it out for use like

Suggested change
if (/\ba new Abstract Closure\b/.test(ownTextContent(step))) {
if (isAbstractClosure(step)) {

e.g.,

const acHeaderRe =
  / performs the following steps (atomically )?when called:$/`;

export function isAbstractClosure(step: Element): boolean {
  // Decide based on text of the last non-<ol> child.
  const { childNodes } = step;
  for (let i = childNodes.length - 1; i >= 0; i--) {
    const childNode = childNodes[i];
    if ((childNode as Element).tagName === 'OL') continue;
    return acHeaderRe.test(childNode.textContent);
  }
  return false;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd prefer to have it just run on text instead of elements, and let the caller pick the text to use instead of having to operate on HTML elements of an assumed structure.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FWIW, the implementation that landed is inherently less efficient than one which looks only at the text of a single child and therefore has a runtime that basically triples the above. I'd prefer processing to be as fast as possible, except where the resulting optimizations hinder comprehension (which I claim is not the case here).

src/Algorithm.ts Outdated
}

for (const step of node.querySelectorAll('li')) {
if (/\ba new Abstract Closure\b/.test(ownTextContent(step))) {
Copy link
Copy Markdown
Member

@gibson042 gibson042 Mar 28, 2026

Choose a reason for hiding this comment

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

The / performs the following steps (atomically )?when called:$/ test seems best to me, and I like the idea of factoring it out for use like

Suggested change
if (/\ba new Abstract Closure\b/.test(ownTextContent(step))) {
if (isAbstractClosure(step)) {

e.g.,

const acHeaderRe =
  / performs the following steps (atomically )?when called:$/`;

export function isAbstractClosure(step: Element): boolean {
  // Decide based on text of the last non-<ol> child.
  const { childNodes } = step;
  for (let i = childNodes.length - 1; i >= 0; i--) {
    const childNode = childNodes[i];
    if ((childNode as Element).tagName === 'OL') continue;
    return acHeaderRe.test(childNode.textContent);
  }
  return false;
}

@michaelficarra
Copy link
Copy Markdown
Member Author

Comments addressed.

@bakkot bakkot merged commit 68ef31d into main Mar 30, 2026
2 checks passed
@bakkot bakkot deleted the mark-ac-bodies branch March 30, 2026 18:18
Comment on lines +349 to +356
export function ownTextContent(el: Element): string {
let text = '';
for (const child of el.childNodes) {
if (child.nodeType === 1 && (child as Element).tagName === 'OL') continue;
text += child.textContent;
}
return text;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the record, I have the same complaint about this function as @bakkot raised about my proposed isAbstractClosure—it presumes an HTML structure without any indication of such a requirement (i.e., "own" does not imply anything specific to HTML list items).

If we're going to keep this function implementation (given an element, return the concatenation of all non-<ol> children's textContent), I'd prefer renaming it to something like stepOwnTextContent, or alternatively generalizing the implementation to also filter out <ul> children and renaming it to something like liOwnTextContent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

visually distinguish AC bodies

3 participants