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

🪲 Set highlighter language and level #6126

Merged
merged 22 commits into from
Jan 30, 2025
Merged

Conversation

boryanagoncharenko
Copy link
Collaborator

PR #6085 makes uses of data-level and data-kwlang but these are never set. As a result, the language of the highlighter always defaults to English regardless of the current language. This PR makes some minimal changes to address the issue.

Fixes #6112

How to test
As an anonymous user go to /hedy and change the language to Turkish (or any other language). In the editor paste yazdır test and check that the first word is highlighted as a command. Do the same check for the /tryit page and a logged in user.

@boryanagoncharenko boryanagoncharenko changed the title 🪲 Set highliter language and level 🪲 Set highlighter language and level Jan 23, 2025
rix0rrr
rix0rrr previously approved these changes Jan 23, 2025
Copy link
Contributor

mergify bot commented Jan 23, 2025

Thank you for contributing! Your pull request is now going on the merge train (choo choo! Do not click update from main anymore, and be sure to allow changes to be pushed to your fork).

Copy link
Contributor

mergify bot commented Jan 23, 2025

This pull request has been removed from the queue for the following reason: pull request dequeued.

Pull request #6126 has been dequeued. The pull request rule doesn't match anymore. The following conditions don't match anymore:

  • all of:
    • #approved-reviews-by>=1
  • any of: [🔀 queue conditions]
    • all of: [📌 queue conditions of queue default_queue]
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]

You should look at the reason for the failure and decide if the pull request needs to be fixed or if you want to requeue it.

If you want to requeue this pull request, you need to post a comment with the text: @mergifyio requeue

@@ -210,8 +210,8 @@ export class HedyCodeMirrorEditor implements HedyEditor {
state: state
});

const levelStr = $(element).closest('[data-level]').attr('data-level');
const lang = $(element).closest('[data-kwlang]').attr('data-kwlang') ?? 'en';
const levelStr = $('[data-level]').attr('data-level');
Copy link
Collaborator

Choose a reason for hiding this comment

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

The old code tried to find the closest enclosing element that has a data-level attribute.

The new code finds any data-level attribute anywhere on the page, whether it has a relation to the editor or not.

Why did the old code not work?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There is no data-level or data-kwlang on any element. This is why it did not work. I added the attributes to the editor but then ofc closest does not work. We could either put the attributes on an enclosing element indeed which is a bit weird or keep them in the editor and fetch them directly from the editor $('#editor').attr('data-*'). What was your intention?

Copy link
Collaborator

@rix0rrr rix0rrr Jan 23, 2025

Choose a reason for hiding this comment

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

Putting the level and kwlang directly on the editor works for the main editor because we control the HTML for it, but doesn't work very well for example for all the syntax highlighted preview editors in running text, because those are <pre> tags that are generated from Markdown. So I wanted a place to put it where it's still in context, but not the editor itself, so it become "some enclosing <div>".

I'd like to keep the logic consistent between the read/write editor and the preview-only editors. That allows us to de-dupe this information wherever it makes sense (*).

I for sure though x.closest() would return x if it matched the selector, but perhaps it doesn't. The document seems to bear that out though, I recall looking this up:

image

https://api.jquery.com/closest/

(*) In general, I'd like to move to a future in which more data is stored in the HTML, via data-* attributes in strategic locations, than passed via JavaScript to initializeXxx() functions. The latter requires a very rigid initialization order that doesn't work very well with HTMX.

@@ -15,7 +15,8 @@
<!-- The actual editor -->
<div id="editor" data-cy="editor" style="background: #272822; font-size:0.95em; color: white; direction: {{ g.dir }};" lang="en" blurred='false'
{% if editor_readonly %}data-readonly="true"{% endif %}
class="w-full flex-1 text-lg rounded min-h-0 overflow-hidden fixed-editor-height"></div>
class="w-full flex-1 text-lg rounded min-h-0 overflow-hidden fixed-editor-height"
data-kwlang="{{ current_language().lang }}" data-level="{{ level }}"></div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

An enclosing scope should be good enough, and I think it should be on there already, no?

@@ -25,7 +25,8 @@
<!-- The actual editor -->
<div id="editor" style="background: #272822; font-size:0.95em; color: white; direction: {{ g.dir }};" lang="en" blurred='false'
{% if editor_readonly %}data-readonly="true"{% endif %}
class="w-full flex-1 text-lg rounded min-h-0 overflow-hidden fixed-editor-height"></div>
class="w-full flex-1 text-lg rounded min-h-0 overflow-hidden fixed-editor-height"
data-kwlang="{{ current_language().lang }}" data-level="{{ level }}"></div>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, if we can put this attribute on a <div> that contains all editors, it should work already?

@@ -48,7 +48,8 @@
<link rel="icon" type="image/png" href="{{static('/images/Hedy-logo-96x96-laptop.png')}}"/>
<link rel="stylesheet" href="{{static('/fontawesome/css/all.min.css')}}"/>
</head>
<body id="main_container" dir="{{ g.dir }}" class="{% if not raw %}bg-gray-100{% endif %}" hx-ext="disable-element,morph" data-logged-in="{{ 1 if username else 0 }}">
<body id="main_container" dir="{{ g.dir }}" class="{% if not raw %}bg-gray-100{% endif %}" hx-ext="disable-element,morph"
data-logged-in="{{ 1 if username else 0 }}" data-kwlang="{{ current_language().lang }}" data-level="{{ level }}">
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the kwlang necessarily the same as the current display language?

And what about pages that don't have a level parameter? (Like, teacher's interface documentation? Or the explore page? Or the public adventures search page) It seems safer to scope this more strictly to the code page bits?

But also -- I'm not sure, I'm asking.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If the user is logged in and their profile language is set to Turkish but their keyword language is set to English, should we highlight Turkish keywords if they are used? I think we should, so the language there should not be the g.keyword_lang, it should be the session language.

I am not sure how to resolve this with given the constraints. I put the data attributes in the main container because this is literally the common div that encompasses all usages of editor and editor-like elements. However, as you pointed out it does not make sense to use a level there, which is what I meant by weird in my previous comment.

I placed it now on the editor_area which is your initial idea probably. However, this does not work as expected. I get intermittent failures to load the highlighting correctly which look like this:
Screenshot 2025-01-24 at 13 02 12
Screenshot 2025-01-24 at 13 04 28
Screenshot 2025-01-24 at 13 15 12

Converted this to a draft, so that it does not get merged until this is solved.

@boryanagoncharenko boryanagoncharenko marked this pull request as draft January 24, 2025 11:22
Copy link
Contributor

mergify bot commented Jan 24, 2025

Thank you for contributing! Your pull request is now going on the merge train (choo choo! Do not click update from main anymore, and be sure to allow changes to be pushed to your fork).

@rix0rrr
Copy link
Collaborator

rix0rrr commented Jan 24, 2025

I ended up putting them in level-page.html, which contains a <div> that is a shared common ancestor of the editor and the adventure tabs with preview text. It seems to work.

I did change the source back to g.keyword_lang though.

If the user is logged in and their profile language is set to Turkish but their keyword language is set to English, should we highlight Turkish keywords if they are used? I think we should, so the language there should not be the g.keyword_lang, it should be the session language.

Well... if not for that, then what is keyword_lang even for?

It may be that there is no useful distinction between keyword language and interface language; but if that's the case, I think I'd rather do that by setting g.keyword_lang = g.lang somewhere in the Python, rather than having a mix of language interpretations in the HTML templates.

There also seems to be a bunch of swizzling of HTML attributes in JavaScript, where we set $(element).attr('lang', someValue). I changed all these to data-lang as well... but preferably they all shouldn't be necessary anymore. This kind of set-x-to-y-before-calling-z code is bound to creep full of errors over time as it is being changed and no one has a full picture of what data goes where, when, anymore.

(I don't want to put in the effort to validate which bits can be removed though...)

@rix0rrr
Copy link
Collaborator

rix0rrr commented Jan 24, 2025

Current status:
image

Copy link
Contributor

mergify bot commented Jan 24, 2025

Thank you for contributing! Your pull request is now going on the merge train (choo choo! Do not click update from main anymore, and be sure to allow changes to be pushed to your fork).

@boryanagoncharenko
Copy link
Collaborator Author

I am afraid using the level-page.html does not cover all scenarios. The following screenshots are done with Teacher1 when the language and the keyword language are both set to Bulgarian:

Viewing a public program:
Screenshot 2025-01-27 at 11 00 48

Previewing a custom adventure:
Screenshot 2025-01-27 at 11 01 13

I think the common denominator is the layout.html which is too wide of a context.

@rix0rrr
Copy link
Collaborator

rix0rrr commented Jan 27, 2025

Do we have a list of places where common UI elements are used? I feel like this "not catching of all cases" comes up all the time... ☹️

@boryanagoncharenko
Copy link
Collaborator Author

Do we have a list of places where common UI elements are used? I feel like this "not catching of all cases" comes up all the time... ☹️

I know :(

I traced that the editor-and-output.html is used in the following places:

  • the code-page which uses layout.html > level-page.html. Btw the code-page can be tested via /hedy, /tryit, /slides/{level_id}, /hour-of-code. The rest of the usages will be removed soon.
  • the customize-adventure page which uses layout.html > auth.html
  • the view-program page which uses directly layout.html
  • the public-adventures page (specifically the htmx-preview-adventure.html) which uses layout.html > auth.html

But I noticed we also have an embedded-editor.html which is returned by embedded/{level_id}, which I forgot to check at all.

Btw I think the keyword language is meant to define in which language to display the keywords in the program at hand. The highlighting, however, should work for the current language and English. I base this assumption on the way the grammars of the language (the lark files, not the highlighting grammars) are created.

@rix0rrr
Copy link
Collaborator

rix0rrr commented Jan 27, 2025

Thanks, that list is extremely helpful!

Btw I think the keyword language is meant to define in which language to display the keywords in the program at hand. The highlighting, however, should work for the current language and English.

I think highlighting will automatically work for <language> + English anyway... ?

But that brings up a good point: let's say keyword language is set to German and display language is set to Dutch (for whatever reason). Keywords should be rendered in German if we do that, right? Shouldn't we then highlight "German + English" (i.e., the keyword language) rather than "Dutch + English" (the UI language) ?

@boryanagoncharenko
Copy link
Collaborator Author

But that brings up a good point: let's say keyword language is set to German and display language is set to Dutch (for whatever reason). Keywords should be rendered in German if we do that, right? Shouldn't we then highlight "German + English" (i.e., the keyword language) rather than "Dutch + English" (the UI language) ?

In your profile, if you set a language other than English, you can only choose your keyword language to be either that same language or English. So, if my language is Turkish, I can pick to have as a keyword language either English or Turkish. I think this was done to simplify the problem of grammar generation.

@boryanagoncharenko
Copy link
Collaborator Author

However, I have to point out that we did explore the idea of having multiple languages at the same time, e.g. Dutch, Frisian and English, or Dutch, French and English. This would work for countries with multiple official languages. It sounds like a very nice feature but it got de-prioritized.

@rix0rrr
Copy link
Collaborator

rix0rrr commented Jan 27, 2025

So you are saying that the highlighting grammar based on the display language is going to be a union of all possible keyword languages for that display language?

That's good to know... but for clarity's sake I think I would still prefer a different keyword then. How about:

g.render_keyword_lang
g.highlight_keyword_lang

? Or something to that effect?

(Because effectively we are talking about them being different)

@rix0rrr
Copy link
Collaborator

rix0rrr commented Jan 28, 2025

I added the attributes in other missing places. It's not elegant, but it'll do... ? We can start paying more attention in the future.

@boryanagoncharenko boryanagoncharenko marked this pull request as ready for review January 29, 2025 13:14
Copy link
Contributor

mergify bot commented Jan 30, 2025

Thank you for contributing! Your pull request is now going on the merge train (choo choo! Do not click update from main anymore, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 063e62a into main Jan 30, 2025
11 checks passed
@mergify mergify bot deleted the broken_highlighting_6112 branch January 30, 2025 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

🪲 code highlighting in slides does not work properly for translations on Alpha
2 participants