R167 / int-ipa

Interactive IPA transcription and learning tool
https://ipa.wdurand.com
MIT License
8 stars 3 forks source link

X-SAMPA version #16

Open abraver opened 7 months ago

abraver commented 7 months ago

I'm working with a blind student, and have been trying to modify the IPA chart to show X-SAMPA instead of IPA symbols—these are easier for her to read on her braille display. I'd like to make an X-SAMPA version of the chart (especially the audio page) so she can learn to link the X-SAMPA symbols to the sounds.

Requested feature

I'd like to make an X-SAMPA version of the keyboard, and I am happy to put in the legwork, but my attempts so far (see below) haven't worked.

Current alternatives

I tried editing the ipa_sounds_manifest with the X-SAMPA equivalents of the IPA characters in the “ipa” key for each entry, but that leads to the symbol showing up greyed out on the chart. I tried, too, to replace the IPA symbols across all files by searching with e.g. grep “ɢ”, but that also didn’t make any change to the keyboard.

These attempts were with the relative-path-assets version of the release.

I also tried doing the custom build option: I was able to yarn install with no problem, but upon yarn build I got the error pasted at the end of this message. I’m afraid my JS is quite rusty and I know nothing about yarn, so I haven’t been able to resolve that issue.

Additional context

Again, I'm happy to put in the legwork if you can help me figure out where I need to make the appropriate symbol swaps, or if you have any ideas about the yarn build message below.

Thanks!

yarn build error message:

Users/abraver/Sites/abc/int-ipa/.yarn/__virtual__/react-scripts-virtual-c0163935d6/0/cache/react-scripts-npm-4.0.3-119b1229eb-a05a46ce31.zip/node_modules/react-scripts/config/env.js:16
delete require.cache[require.resolve('./paths')];
                             ^

TypeError: Cannot convert undefined or null to object
    at Object.<anonymous> (/Users/abraver/Sites/abc/int-ipa/.yarn/__virtual__/react-scripts-virtual-c0163935d6/0/cache/react-scripts-npm-4.0.3-119b1229eb-a05a46ce31.zip/node_modules/react-scripts/config/env.js:16:30)
    at loadCJSModule (node:internal/modules/esm/translators:271:3)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:308:7)
    at ModuleJob.runSync (node:internal/modules/esm/module_job:209:17)
    at require (node:internal/modules/esm/translators:256:9)
    at Object.<anonymous> (/Users/abraver/Sites/abc/int-ipa/.yarn/__virtual__/react-scripts-virtual-c0163935d6/0/cache/react-scripts-npm-4.0.3-119b1229eb-a05a46ce31.zip/node_modules/react-scripts/scripts/build.js:23:1)
    at loadCJSModule (node:internal/modules/esm/translators:271:3)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:308:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
R167 commented 7 months ago

Hi @abraver! I'm traveling this weekend, but happy to help where i can, though probably when i get back. Do you know what versions of node and yarn you're running? those would be my first checks of whats going wrong.

I'm not familiar with X-SAMPA, but really appreciate any work you're willing to help with to make this site more accessible. Super cool to see someone else using it in the wild!

At present, for the audio (and video) files, i use a lookup table based on the computed symbol name (i think). the data is encoded in msgpack as a dictionary type of {symbol: []byte for sound}. The binpack script might be useful for some of the details here https://github.com/R167/int-ipa/blob/master/scripts/binpack_ipa.rb

It's been a minute since i last touched this project, so i'll probably need to spend a bit of time next week refamiliarizing myself with the code.

R167 commented 7 months ago

fwiw, the automatic build currently runs with node version 16, so it's possible the latest version broke something (or you're running an older version locally??)

abraver commented 7 months ago

Cool, I'd love to get this to work; any help is much appreciated.

[🐧 …/abc/int-ipa]$ node -v
v21.6.1
[🐧 …/abc/int-ipa]$ yarn -v
3.2.4
R167 commented 7 months ago

oh dang, node is up to v21 now? i wonder if yarn test will work. if not, the easiest thing at this point that i think will work is installing nodeenv, nvm, or another similar node manager, setting it up to run 16.x.x and then trying yarn build again. if you just want to run it locally for development, you can use yarn start

abraver commented 7 months ago

Success! nvm use 16 gets me up and running.

I'll try playing with it a bit, but would definitely appreciate any guidance you can provide when you're back from your travels.

abraver commented 7 months ago

I'll have to play more to see if it actually works, but it looks like if I update the symbols in src/utils/ipa.ts and also in public/config/ipa_sound_manifest.yaml I get the desire result.

Here, for testing purposes, I've just subbed in "X" instead of "p" for the bilabial stopː

image
abraver commented 7 months ago

A quick update: I've gotten the whole pulmonic consonant section to work both locally and on the server

image
R167 commented 7 months ago

nice. i wonder if the best way to support this would be aria-style tags on the various symbols + and x-sampa lookup in the metadata file maybe(?) Again, not that familiar with how x-sampa + braille screen readers work

abraver commented 7 months ago

Yeah, I think the ideal version would be something along the lines of adding a key in the ipa_sound_manifest.yaml file for SAMPA in addition to the ipa, audio, and video entries. I'm going to just manually edit ipa_sound_manifest.yaml and ipa.ts for now, replacing the IPA symbols with X-SAMPA, and have my student see how it works for her. Once I get notes from her, I think we'll have a better idea what the optimal solution is.

The student has both a screenreader and a tactile refreshable Braille display. We've found that the Braille display does well at displaying X-SAMPA, because she already knows all the Braille patterns for the base letters and punctuation that's used as modifiers.

I'll report back when I have more information.

abraver commented 7 months ago

One thing we've come across is that navigating tables with a screenreader can be challenging, because as the cursor hits each cell, it doesn't tell you which column/row you are in (e.g., if you land on [b], there's not an easy way to look up what the place and manner are). So, I'd like to try to get the full sound description in the table cell along with the symbol.

Since this will make the table very crowded, I'd like to make it so that the screenreader reads the description, but it doesn't show visually. I had hoped that aria-label would do the trick, but it seems the screenreader just skips over it in this table. What seems to be the more or less standard solution for text to appear to a screenreader but not visually is {position: absolute; left: -10000px} or similar. In other words, the ideal solution would be to add a div (with a class that positions it off the screen) that pulls from the description key in Sound or one of those.

My TypeScript knowledge (or lack thereof) comes into play here, because I can't figure out how to get the description text onto the IPA chart. I gather it's probably something with one of the types like IpaSoundsParsed or something, but I'm out of my depth here. Any help or pointers would be appreciated. I'm happy to do most of the work if you can point me in the right direction.

abraver commented 7 months ago

I'm running into a new issue—

ipaDescription.ts exports a PulmonicDescriptions dictionary. In Pulmonics.tsx I am trying to access this to get the description to display in the cell for the screen reader. I've imported PulmonicDescriptions with import { PulmonicDescriptions } from "../../utils/ipaDescription";.

I'm having trouble accessing this dictionary, though, in Pulmonics.tsx. if I do something like const voiceless_desc = PulmonicDescriptions.get("b") it happily returns "Voiced Bilabial Stop". However when I try to get the current voiceless symbol (which is defined a few lines above as const voiceless = PULMONICS[y]?.[x * 2]; with e.g. ,const voiceless_desc = PulmonicDescriptions.get(voiceless);`, I get the following error:

TypeScript error in /Users/abraver/Sites/abc/int-ipa/src/components/keyboard/Pulmonics.tsx(82,55):
Argument of type '"" | "x" | "_" | "b" | "p" | "q" | "s" | "g" | "d" | "k" | "r" | "z" | "t" | "t`" | "d`" | "c" | "J\\" | "G\\" | "?" | "m" | "F" | "n" | "n`" | "J" | "N" | "N\\" | "B\\" | "R\\" | "4" | "r`" | "p\\" | ... 28 more ... | "L\\"' is not assignable to parameter of type 'Pulmonics'.
  Type '""' is not assignable to type 'Pulmonics'.  TS2345

    81 | 
  > 82 |       const voiceless_desc = PulmonicDescriptions.get(voiceless);
       |                                                       ^
    83 | 
    84 |       const voiced = PULMONICS[y]?.[x * 2 + 1];
    85 |

As far as I can tell, voiceless should just be a string plucked from the PULMONICS array, so I'm not sure why it's throwing this error. I've tried casting as string with const voiceless_desc = PulmonicDescriptions.get(voiceless.toString()); but then I get the related error Argument of type 'string' is not assignable to parameter of type 'Pulmonics'. TS2345.

Any help would be most appreciated.

R167 commented 7 months ago

Hey @stylerw, I remember when we talked last you said you had some success with a vision impaired student using a screenreader and a translation layer/lookup file they used to make navigation easier? Wondering if any of that would be useful here.

@abraver, do you have your code pushed to a branch or something? That would make it easier for me to understand what you're talking about by being able to see the more-full source :)

Finally got a bit of free time out of the craziness of the last couple weeks to get back to this project

abraver commented 7 months ago

@stylerw: Any suggestions you have for working with visually impaired students in linguistics would be great, related to this project or otherwise.

@R167: I've done a pretty hack-y job of it so far with no version control(!). Let me make an actual fork and I'll share that with you as soon as I get a chance.

abraver commented 7 months ago

@R167: Here is a branch with the modifications I made: https://github.com/abraver/int-ipa/tree/xsampa/

You can see it running at https://aaronbraver.com/int-ipa/build/#/keyboard/audio

At this point, all that's happening is I've replaced the IPA strings with their SAMPA counterparts in ipa_sound_manifest.yaml and ipa.ts. Pulmonics.tsx, at the creation of the voiced/voiceless pairs grabs the description from PulmonicDescriptions and puts it into a span that hides the content visually, but is still accessed by a screen reader.*

I don't get any errors now, but I think ultimately the ideal situation would be to add a key to ipa_sound_manifest.yaml or similar that has the X-SAMPA, and we could have a toggle or something to display that version or the IPA.

(*The aria-hidden properties and similar seem to not work well, and from what I can tell from some Googling, this approach of position: absolute; left: 10000px is pretty commonly used.)