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

Make "Speaker Notes" translatable #1390

Open
mgeisler opened this issue Oct 19, 2023 · 9 comments
Open

Make "Speaker Notes" translatable #1390

mgeisler opened this issue Oct 19, 2023 · 9 comments
Labels
bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed

Comments

@mgeisler
Copy link
Collaborator

The "Speaker Notes" string is currently hard-coded in the JavaScript code that injects it:

h4.append("Speaker Notes");

There are several other strings in that file that need translation too.

@mgeisler mgeisler added bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed labels Oct 19, 2023
@Sweetdevil144
Copy link

Hello @mgeisler !!
Is the issue still open?
If so then I would like to work on it!! 🙂

@mgeisler
Copy link
Collaborator Author

Hi @Sweetdevil144, it is open! Please go ahead and propose a plan for how we can do this.

@Sweetdevil144
Copy link

Sweetdevil144 commented Oct 20, 2023

Hello @mgeisler ,
I think a practical solution for making "Speaker Notes" translatable would be to implement a language file that houses translations for all relevant strings within the code. Based on the user's selected language preference, we can dynamically load the corresponding translation from the file.

What are your views on this?
Appreciate any suggestions !! :-)

@mgeisler
Copy link
Collaborator Author

I think a practical solution for making "Speaker Notes" translatable would be to implement a language file that houses translations for all relevant strings within the code.

Yeah, I think we should find a way to inject the string "Speaker Notes" into the PO files we already use to translate the course. We have a translation pipeline set up for the course and we should try to build on it.

The translation work by

  • Extracting text from the pages using a custom mdbook backend
  • Translating text when publishing using a custom mdbook preprocessor

See TRANSLATIONS.md for the details and see mdbook-i18n-helpers for the tooling.

Now, how do speaker notes work? They work purely using JavaScript, see speaker-notes.js. The code looks for a details element and transforms what is inside. The Speaker Notes string come from there.

To make something appear in the PO files, it needs to be part of the pages when the mdbook-xgettext backend is running. We can do this by hand: we could turn every <details> ... into ## Speaker Notes heading. The JavaScript would then need to be updated to find this heading instead of finding the details element — which becomes a little tricky when the heading is translated for some langauges (we could perhaps add an ID with a header attribute?).

Asking people to write # Speaker Notes and add a special ID by hand is a bit error-prone — and it won't help with translating the other strings that the JavaScript code adds: the hover text for the icon, as an example. We might need a different approach for this.

Some ideas:

  • Create a new mdbook preprocessor which injects material into the pages. This material would be seen by mdbook-xgettext and so end up in the PO files. This could be a new mdbook-speaker-notes preprocessor which would know about the strings needed by the JavaScript code. The strings could be put into a <div style="display: none"> ... </div> element: they would still be extracted for translation, but they should not disturb the page itself.
  • Extract the strings from the JavaScript and somehow inject them into the published book. This could be a small JSON file put next to the normal book output: the JavaScript would then load it at runtime.
  • Perhaps some other idea?

I think I lean towards using a new preprocessor. That has less moving parts at runtime and we could encapsulate the full logic into this preprocessor.

@Sweetdevil144
Copy link

I agree that leveraging our current systems for consistency and efficiency is a smart approach.
Alright, here's what I'm thinking: we should probably come up with a new mdbook preprocessor to handle this situation. If we name it something like "mdbook-speaker-notes," it could take care of adding the specific strings we need for the JavaScript in our speaker-notes.js file. I lack much knowledge about the mdbook processing, but here's how I would go with this.

Imagine it like this: while it's processing, the preprocessor would sneak these strings onto the pages. Maybe it could put them inside a hidden <div> tag. You know, something that stays out of sight but still gets the job done. Here's a quick sketch of what that might look like:

<div style="display: none" id="speaker-notes-strings">
  <span id="speaker-notes-title">Speaker Notes</span>
  <!-- We can pop more strings in here as needed -->
</div>

Then, we just tweak our speaker-notes.js a bit. It would grab the text it needs right from this hidden <div>. So instead of having the text hard-coded, it pulls the title like this:

let speakerNotesTitle = document.querySelector("#speaker-notes-title").innerText;
h4.append(speakerNotesTitle);

One of the cool things about this setup is that when mdbook-xgettext does its thing, it'll pick up these strings and pop them into the PO files. That means they're all set for translation, which is super handy.

I like this approach because it keeps everything neat and organized. All the translation stuff is bundled into the preprocessor, so the runtime side stays simpler. Plus, it fits nicely with the translation system we've already got, making it easier to handle down the road.

Of course, this means a bit of extra work. We'd need to change up the speaker-notes.js and build the new preprocessor from scratch. It might be worth running this idea by rest of the team and other contributors to see what they think and figure out the best way to move forward.

@Sweetdevil144
Copy link

I too am learning rust using comprehensive-rust btw :- )

@moaminsharifi
Copy link
Collaborator

What I can suggest, we can add an item menu like at the end of the sidebar menu and make it hidden with display:none; then because the text is in SUMMARY.md people can translate it and you can take this value from html.
The other option would be to create a dictionary (hash table) and put it in the code. like

{
"EN"=> "Speaker Notes"
}
almost like what you said, @mgeisler

@mgeisler
Copy link
Collaborator Author

What I can suggest, we can add an item menu like at the end of the sidebar menu and make it hidden with display:none; then because the text is in SUMMARY.md people can translate it and you can take this value from html.

That would be cool, but unfortuantely SUMMARY.md is a weird file: it has a particular strict format which is parsed by mdbook. So it's not simply included literally on every page.

Imagine it like this: while it's processing, the preprocessor would sneak these strings onto the pages. Maybe it could put them inside a hidden <div> tag. You know, something that stays out of sight but still gets the job done. Here's a quick sketch of what that might look like:

<div style="display: none" id="speaker-notes-strings">
  <span id="speaker-notes-title">Speaker Notes</span>
  <!-- We can pop more strings in here as needed -->
</div>

Then, we just tweak our speaker-notes.js a bit. It would grab the text it needs right from this hidden <div>. So instead of having the text hard-coded, it pulls the title like this:

let speakerNotesTitle = document.querySelector("#speaker-notes-title").innerText;
h4.append(speakerNotesTitle);

One of the cool things about this setup is that when mdbook-xgettext does its thing, it'll pick up these strings and pop them into the PO files. That means they're all set for translation, which is super handy.

Yes, I think this could work very well! I like the approach too since it has some good qualities:

  • It will work for others who don't use the mdbook-gettext preprocessor
  • It integrates well with mdbook-xgettext

So the new preprocessor will inject both the hidden div and it will also inject the JavaScript needed (perhaps as a link?). That makes it possible to clean up the configuration in general: to enable speaker-notes, you just have to enable the preprocessor. Everything is nicely encapsulated.

You should take a look at @djmitche's tiny mdbook-course preprocessor as a starting point. It adds a bit of information to the pages right now and I think you'll want to copy this approach.

@Sweetdevil144
Copy link

Sure. I'm on it! : )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants