Skip to content

Commit 5758427

Browse files
authored
Fix noor bayan rendering (#733)
* Fix treebank rendering issue * fix phrase arc line * Support multiple locales for Irab and treebank * refactor ayah navigation
1 parent 4b3cf6c commit 5758427

20 files changed

Lines changed: 532 additions & 386 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# frozen_string_literal: true
2+
3+
ActiveAdmin.register Morphology::DerivedWord do
4+
menu parent: 'Morphology'
5+
actions :index, :show
6+
includes :verse
7+
8+
filter :verse_id, as: :numeric
9+
filter :word_id, as: :numeric
10+
filter :derived_word_id, as: :numeric
11+
filter :form_name
12+
filter :en_translation
13+
filter :en_transliteration
14+
15+
index do
16+
id_column
17+
column :verse do |resource|
18+
resource.verse && link_to(resource.verse.verse_key, [:cms, resource.verse])
19+
end
20+
column :word_id
21+
column :derived_word_id
22+
column :form_name
23+
column :en_transliteration
24+
column :en_translation
25+
actions
26+
end
27+
28+
show do
29+
attributes_table do
30+
row :id
31+
row :verse do |resource|
32+
resource.verse && link_to(resource.verse.verse_key, [:cms, resource.verse])
33+
end
34+
row :word_id
35+
row :derived_word do |resource|
36+
resource.derived_word && link_to(resource.derived_word.location, [:cms, resource.derived_word])
37+
end
38+
row :word_verb_from
39+
row :form_name
40+
row :en_transliteration
41+
row :en_translation
42+
row :created_at
43+
row :updated_at
44+
end
45+
end
46+
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
ActiveAdmin.register Morphology::GrammarConcept do
4+
menu parent: 'Morphology'
5+
actions :index, :show
6+
7+
filter :arabic
8+
filter :english
9+
10+
index do
11+
id_column
12+
column :arabic
13+
column :english
14+
column('Words') { |c| c.word_segments.size }
15+
actions
16+
end
17+
18+
show do
19+
attributes_table do
20+
row :id
21+
row :arabic
22+
row :english
23+
row :created_at
24+
row :updated_at
25+
end
26+
end
27+
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
ActiveAdmin.register Morphology::GrammarPattern do
4+
menu parent: 'Morphology'
5+
actions :index, :show
6+
7+
filter :arabic
8+
filter :english
9+
10+
index do
11+
id_column
12+
column :arabic
13+
column :english
14+
actions
15+
end
16+
17+
show do
18+
attributes_table do
19+
row :id
20+
row :arabic
21+
row :english
22+
row :created_at
23+
row :updated_at
24+
end
25+
end
26+
end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
ActiveAdmin.register Morphology::WordGrammarConcept do
4+
menu parent: 'Morphology'
5+
actions :index, :show
6+
includes :word, :grammar_concept
7+
8+
filter :word_id, as: :numeric
9+
filter :grammar_concept_id, as: :numeric
10+
11+
index do
12+
id_column
13+
column :word do |resource|
14+
resource.word && link_to(resource.word.location, [:cms, resource.word])
15+
end
16+
column :grammar_concept do |resource|
17+
resource.grammar_concept && link_to(resource.grammar_concept.english.presence || resource.grammar_concept.arabic, [:cms, resource.grammar_concept])
18+
end
19+
actions
20+
end
21+
22+
show do
23+
attributes_table do
24+
row :id
25+
row :word do |resource|
26+
resource.word && link_to(resource.word.location, [:cms, resource.word])
27+
end
28+
row :grammar_concept
29+
row :created_at
30+
row :updated_at
31+
end
32+
end
33+
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# frozen_string_literal: true
2+
3+
ActiveAdmin.register Morphology::WordVerbForm do
4+
menu parent: 'Morphology'
5+
actions :index, :show
6+
includes :word
7+
8+
filter :word_id, as: :numeric
9+
filter :name
10+
filter :value
11+
12+
index do
13+
id_column
14+
column :word do |resource|
15+
resource.word && link_to(resource.word.location, [:cms, resource.word])
16+
end
17+
column :name
18+
column :value
19+
actions
20+
end
21+
22+
show do
23+
attributes_table do
24+
row :id
25+
row :word do |resource|
26+
resource.word && link_to(resource.word.location, [:cms, resource.word])
27+
end
28+
row :name
29+
row :value
30+
row :created_at
31+
row :updated_at
32+
end
33+
end
34+
end

app/assets/stylesheets/components/_treebank.scss

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@
3232

3333
svg {
3434
display: inline-block;
35-
max-width: 100%;
3635
background: #fff;
3736
}
3837
}
3938

4039
.treebank-banner-text {
4140
fill: #1a5c38;
4241
font-weight: bold;
42+
direction: rtl;
43+
unicode-bidi: bidi-override;
4344
}
4445

4546
.treebank-banner-ref {
@@ -298,7 +299,6 @@
298299

299300
svg {
300301
display: inline-block;
301-
max-width: 100%;
302302
background: #fff;
303303
}
304304

@@ -398,6 +398,10 @@
398398
&:last-child {
399399
margin-bottom: 0;
400400
}
401+
402+
.qpc-hafs {
403+
direction: inherit;
404+
}
401405
}
402406

403407
span {

app/controllers/community_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class CommunityController < ApplicationController
22
before_action :init_presenter
33

4-
DEFAULT_LANGUAGE = 174 # We're focusing on Urdu atm
4+
DEFAULT_LANGUAGE = 174
55
helper_method :current_language
66
before_action :load_resource_access
77

app/controllers/morphology/treebank_controller.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def index
133133
def show
134134
@chapter_number = params[:chapter].to_i
135135
@verse_number = params[:verse].to_i
136-
@locale = %w[en ar].include?(params[:locale].to_s) ? params[:locale].to_s : 'ar'
136+
@locale = %w[en ar ur].include?(params[:locale].to_s) ? params[:locale].to_s : 'en'
137137

138138
@verse = Verse.find_by(chapter_id: @chapter_number, verse_number: @verse_number)
139139
return head :not_found unless @verse
@@ -142,7 +142,7 @@ def show
142142
.where(chapter_id: @chapter_number)
143143
.where('first_verse_id <= ? AND last_verse_id >= ?', @verse.id, @verse.id)
144144
.order(:sentence_number)
145-
.includes(:word_tokens)
145+
.includes(word_tokens: %i[root lemma])
146146

147147
@irab_tokens = @sentences.flat_map(&:word_tokens)
148148

@@ -158,7 +158,7 @@ def show
158158
def data
159159
chapter_number = params[:chapter].to_i
160160
verse_number = params[:verse].to_i
161-
locale = %w[en ar].include?(params[:locale].to_s) ? params[:locale].to_s : 'ar'
161+
locale = %w[en ar ur].include?(params[:locale].to_s) ? params[:locale].to_s : 'en'
162162

163163
verse = Verse.find_by(chapter_id: chapter_number, verse_number: verse_number)
164164
return head :not_found unless verse

app/javascript/controllers/treebank_controller.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,17 @@ export default class extends Controller {
299299
}
300300

301301
this.applyZoom();
302+
if (this.hasCanvasTarget) this.centerScroll(this.canvasTarget);
303+
}
304+
305+
// Center the horizontal scroll so a wide treebank opens on its middle rather
306+
// than one edge. rAF lets layout settle after the SVG width is applied.
307+
centerScroll(scroller) {
308+
if (!scroller) return;
309+
requestAnimationFrame(() => {
310+
const overflow = scroller.scrollWidth - scroller.clientWidth;
311+
if (overflow > 0) scroller.scrollLeft = overflow / 2;
312+
});
302313
}
303314

304315
sentenceMaxLevel(sentence) {
@@ -435,6 +446,7 @@ export default class extends Controller {
435446
svgContainer.innerHTML = "";
436447
svgContainer.appendChild(svg);
437448
this.applyZoom();
449+
this.centerScroll(svgContainer);
438450
}
439451

440452
async toggleCard(event) {
@@ -551,6 +563,7 @@ class TreebankRenderer {
551563
this.phraseLevelHeight = 0; // total height of the phrase-level rows (set in render)
552564
this.PHRASE_LEVEL_STEP = 70; // vertical distance between consecutive phrase levels
553565
this.PHRASE_EDGE_ARC_HEIGHT = 50; // how high a phrase (constituency) edge arcs above its band
566+
this.PHRASE_EDGE_FOOT_LIFT = 28; // float phrase-edge arcs above the phrase nodes so they clear the phrase surface text drawn above each dot
554567
this.phraseTopGap = 0; // extra headroom so phrase-edge arcs clear the banner (set in render)
555568
this.tokenRowHeight = 90; // bottom row: location + arabic + POS label
556569
this.arcBandHeight = 0;
@@ -576,7 +589,7 @@ class TreebankRenderer {
576589
// Only reserve top headroom when phrase edges exist — otherwise their arcs
577590
// (which rise PHRASE_EDGE_ARC_HEIGHT above the top phrase row) collide with
578591
// the banner and overlap the text.
579-
this.phraseTopGap = phraseEdges.length > 0 ? (this.PHRASE_EDGE_ARC_HEIGHT + 24) : 0;
592+
this.phraseTopGap = phraseEdges.length > 0 ? (this.PHRASE_EDGE_ARC_HEIGHT + this.PHRASE_EDGE_FOOT_LIFT + 24) : 0;
580593

581594
const tempSvg = document.createElementNS(this.SVG_NS, "svg");
582595
tempSvg.style.position = "absolute";
@@ -616,7 +629,6 @@ class TreebankRenderer {
616629
svg.setAttribute("xmlns", this.SVG_NS);
617630
svg.setAttribute("data-base-width", svgW);
618631
svg.setAttribute("data-base-height", svgH);
619-
svg.style.maxWidth = "100%";
620632
svg.style.display = "block";
621633

622634
this.drawBanner(svg, svgW, bannerTextW);
@@ -1081,11 +1093,16 @@ class TreebankRenderer {
10811093

10821094
if (fromX === null || toX === null || fromY === null || toY === null) continue;
10831095

1084-
const bandY = Math.min(fromY, toY);
1096+
// Float the drawn arc a fixed amount above the two node feet so it clears
1097+
// the phrase surface text. The nodes/blocks themselves stay on their band
1098+
// (kept inline) — only the arc path lifts.
1099+
const fromFootY = fromY - this.PHRASE_EDGE_FOOT_LIFT;
1100+
const toFootY = toY - this.PHRASE_EDGE_FOOT_LIFT;
1101+
const bandY = Math.min(fromFootY, toFootY);
10851102
const apexAbsY = bandY - ARC_HEIGHT;
10861103

10871104
const path = document.createElementNS(this.SVG_NS, "path");
1088-
const d = `M ${fromX},${fromY} C ${fromX},${apexAbsY} ${toX},${apexAbsY} ${toX},${toY}`;
1105+
const d = `M ${fromX},${fromFootY} C ${fromX},${apexAbsY} ${toX},${apexAbsY} ${toX},${toFootY}`;
10891106
path.setAttribute("d", d);
10901107
path.setAttribute("fill", "none");
10911108
path.setAttribute("stroke-width", "1.5");

0 commit comments

Comments
 (0)