Skip to content

Conversation

@glebm
Copy link

@glebm glebm commented Jun 5, 2025

This is a draft PR for #372 to demonstrate a Speech API that does not rely on mutable global state, while preserving the existing APIs that do rely on global state.

src/interface.rs Outdated
}

fn cleanup_mathml_with_rules<'a>(_rules: &SpeechRules, mathml: Element<'a>) -> Result<Element<'a>> {
// TODO: Canonicalization does not seem to actually use rules?
Copy link
Author

@glebm glebm Jun 5, 2025

Choose a reason for hiding this comment

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

I have a question about this: I haven't been able to find where canonicalization actually uses rules, but the comment here seems to indicate that it does?

Commenting out rule loading in the canonicalize tests also doesn't cause any test failures.

MathCAT/src/interface.rs

Lines 109 to 111 in ca4b933

// We need the main definitions files to be read in so canonicalize can work.
// This call reads all of them for the current preferences, but that's ok since they will likely be used
crate::speech::SPEECH_RULES.with(|rules| rules.borrow_mut().read_files())?;

Copy link
Owner

Choose a reason for hiding this comment

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

Canonicalization uses the preference files (e.g., for decimal and block separators to fix up numbers). It also reads the definition files so it knows what are function names (and other things I think) for restructuring the code.

Copy link
Author

@glebm glebm Jun 6, 2025

Choose a reason for hiding this comment

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

Thanks, I think I have something sensible now.

The new stateless interface in the stateless_interface.rs. It is speech-only but it'll be possible to extend to Braille in the future if someone needs it.

The other new files, such as element_util.rs, contain functions moved out of interface.rs so that they can be reused in the stateless version.

Canonicalization code is modified to allow for stateless use (it is also deduplicated a bit thanks to the new CanonicalizeContextPatternsOptions struct)

@glebm glebm force-pushed the external-rules branch 3 times, most recently from 06e9380 to e14807a Compare June 9, 2025 23:56
@glebm
Copy link
Author

glebm commented Jun 9, 2025

@NSoiffer I got somewhere with this but running the example I wrote results in a strange error:

cargo build --examples
target/debug/examples/stateless-example

Error(Msg("Pattern match/replacement failure!"), State { next_error: Some(Error(Msg("attempting replacement pattern: \"default\" for \"math\".\nReplacement\n[with:\n variables: [name: ClearSpeak_Fractions=x: \"IfThenElse($Verbosity='Verbose' and $ClearSpeak_Fractions='Auto', 'EndFrac', $ClearSpeak_Fractions)\"],[name: ClearSpeak_AbsoluteValue=x: \"IfThenElse($Verbosity='Verbose' and $ClearSpeak_AbsoluteValue='Auto', 'AbsEnd', $ClearSpeak_AbsoluteValue)\"],[name: ClearSpeak_Roots=x: \"IfThenElse($Verbosity='Verbose' and $ClearSpeak_Roots='Auto', 'RootEnd', $ClearSpeak_Roots)\"],[name: ClearSpeak_Matrix=x: \"IfThenElse($Verbosity='Verbose' and $ClearSpeak_Matrix='Auto', 'EndMatrix', $ClearSpeak_Matrix)\"],[name: MatchingPause=x: \"false()\"],[name: IsColumnSilent=x: \"false()\"],\n replace: [test: [ if: 'x: \"$MathRate = 100\"' then:[x: \"*\"] else:[rate: 987654321.5[x: \"*\"]]]\n]]\n...due to matching the MathML\n <math id='Mo5oau70-0' data-id-added='true'>\n <mrow id='Mo5oau70-1' data-id-added='true'>\n <msup id='Mo5oau70-2' data-id-added='true'>\n <mi id='Mo5oau70-3' data-id-added='true'>sin</mi>\n <mn id='Mo5oau70-4' data-id-added='true'>2</mn>\n </msup>\n <mo id='Mo5oau70-5' data-id-added='true'>&#x2061;</mo>\n <mi data-previous-space-width='0' id='Mo5oau70-6' data-id-added='true'>x</mi>\n </mrow>\n </math>\n with the pattern\nx: \".\"\nThe patterns are in /home/gleb/MathCAT/Rules/Languages/en/SharedRules/default.yaml.\n"), State { next_error: Some(Error(Msg("Can't evaluate variable def for [name: ClearSpeak_Fractions=x: \"IfThenElse($Verbosity='Verbose' and $ClearSpeak_Fractions='Auto', 'EndFrac', $ClearSpeak_Fractions)\"] with ContextStack 0 old_values\n\n"), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })), backtrace: InternalBacktrace { backtrace: None } })), backtrace: InternalBacktrace { backtrace: None } })

I'd appreciate help figuring this one out.

The code still uses global variables in some places (e.g. xpath) but I somewhat expected it to run at this point.

glebm added a commit to glebm/MathCAT that referenced this pull request Jun 10, 2025
Makes `interface.rs` file easier to navigate.

Also extracted `enable_logs` to `logs.rs`.

This is a refactoring that I've extracted from NSoiffer#374,
where these functions are used by both the stateful
and the stateless interface and I wanted to avoid
any dependencies from `stateless_interface` on
`interface`.
glebm added a commit to glebm/MathCAT that referenced this pull request Jun 10, 2025
@glebm
Copy link
Author

glebm commented Jun 10, 2025

This PR has become too huge to review, so I've started sending bits of it that are not about statelessness as separate PRs with the hope of reducing the diff here.

@NSoiffer
Copy link
Owner

I apologize that it has taken forever for me to get to looking at this...

Instead of pushing to main, the work needs to be in a branch. Since I don't think you can create a branch in the MathCAT repo, I've created one for this work: stateless.

I looked at some of the conflicts and I don't understand how you plan to make this work and still have (normal) MathCAT run. For example, it appears that one of the conflicts in interface.rs is that you have removed the functions that add ids. Those need to stick around for standard MathCAT functionality (they provide a hook for synchronized speech highlighting). Maybe you should add a "stateless" "feature" to MathCAT similar to "include-zip" or "enable-logs". This allows you to include or exclude code based on whether that feature is set or not.

I'll try to be more proactive about your needs going forward. Again, apologies about my slowness.

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.

2 participants