def get_scripture_with_sn_quotes(self, bible_id, chapter, verse, rc,
                                  scripture):
     if not scripture:
         scripture = self.get_plain_scripture(bible_id, chapter, verse)
     footnotes_split = re.compile('<div class="footnotes">',
                                  flags=re.IGNORECASE | re.MULTILINE)
     verses_and_footnotes = re.split(footnotes_split, scripture, maxsplit=1)
     scripture = verses_and_footnotes[0]
     footnote = ''
     if len(verses_and_footnotes) == 2:
         footnote = f'<div class="footnotes">{verses_and_footnotes[1]}'
     if verse in self.sn_book_data[chapter]:
         sn_notes = self.sn_book_data[chapter][verse]
     else:
         sn_notes = []
     orig_scripture = scripture
     for sn_note_idx, sn_note in enumerate(sn_notes):
         occurrence = 1
         if RepresentsInt(
                 sn_note['Occurrence']) and int(sn_note['Occurrence']) > 0:
             occurrence = int(sn_note['Occurrence'])
         gl_quote_phrase = [[{
             'word': sn_note['GLQuote'],
             'occurrence': occurrence
         }]]
         phrase = sn_note['alignments'][bible_id]
         if not phrase:
             phrase = gl_quote_phrase
         if flatten_alignment(phrase).lower() in QUOTES_TO_IGNORE:
             continue
         split = ''
         if len(phrase) > 1:
             split = ' split'
         tag = f'<span class="highlight phrase phrase-{sn_note_idx+1}{split}">'
         marked_verse_html = html_tools.mark_phrases_in_html(scripture,
                                                             phrase,
                                                             tag=tag)
         if not marked_verse_html:
             fix = None
             if flatten_alignment(phrase).lower() not in QUOTES_TO_IGNORE:
                 if sn_note['GLQuote']:
                     marked_with_gl_quote = html_tools.mark_phrases_in_html(
                         scripture, gl_quote_phrase)
                     if marked_with_gl_quote:
                         fix = sn_note['GLQuote']
                 self.add_bad_highlight(rc, orig_scripture, sn_note['rc'],
                                        sn_note['GLQuote'], fix)
         else:
             scripture = marked_verse_html
     scripture += footnote
     return scripture
 def get_scripture_with_tw_words(self, bible_id, chapter, verse, rc=None):
     scripture = self.get_plain_scripture(bible_id, chapter, verse)
     footnotes_split = re.compile('<div class="footnotes">',
                                  flags=re.IGNORECASE | re.MULTILINE)
     verses_and_footnotes = re.split(footnotes_split, scripture, maxsplit=1)
     scripture = verses_and_footnotes[0]
     footnote = ''
     if len(verses_and_footnotes) == 2:
         footnote = f'<div class="footnotes">{verses_and_footnotes[1]}'
     orig_scripture = scripture
     if chapter not in self.tw_words_data or verse not in self.tw_words_data[chapter] or \
             not self.tw_words_data[chapter][verse]:
         return scripture
     phrases = self.tw_words_data[chapter][verse]
     for group_data_idx, group_data in enumerate(phrases):
         tw_rc = group_data['contextId']['rc']
         split = ''
         if len(group_data):
             split = ' split'
         tag = f'<a href="{tw_rc}" class="tw-phrase tw-phrase-{group_data_idx + 1}{split}">'
         alignment = group_data['alignments'][bible_id]
         if alignment:
             marked_verse_html = html_tools.mark_phrases_in_html(scripture,
                                                                 alignment,
                                                                 tag=tag)
             if not marked_verse_html:
                 if rc:
                     self.add_bad_highlight(rc, orig_scripture, tw_rc,
                                            flatten_alignment(group_data))
             else:
                 scripture = marked_verse_html
     scripture += footnote
     return scripture
예제 #3
0
    def get_body_html(self):
        self.logger.info('Generating OBS SN SQ html...')
        obs_sn_sq_html = f'''
<section id="{self.lang_code}-obs-sn">
    <div class="resource-title-page no-header">
        <img src="{self.resources['obs-sn'].logo_url}" class="logo" alt="OBS">
        <h1 class="section-header">{self.simple_title}</h1>
    </div>
'''
        intro_file = os.path.join(self.resources['obs-sq'].repo_dir, 'content',
                                  '00.md')
        if os.path.isfile(intro_file):
            intro_id = 'obs-sq-intro'
            intro_content = markdown2.markdown_path(intro_file)
            intro_content = html_tools.increment_headers(intro_content, 1)
            intro_content = intro_content.replace(
                '<h2>', '<h2 class="section-header">', 1)
            obs_sn_sq_html += f'''
    <article id="{intro_id}">
        {intro_content}
    </article>
'''
        for chapter_num in range(1, 51):
            chapter_num = str(chapter_num).zfill(2)
            sn_chapter_dir = os.path.join(self.resources['obs-sn'].repo_dir,
                                          'content', chapter_num)
            sq_chapter_file = os.path.join(self.resources['obs-sq'].repo_dir,
                                           'content', f'{chapter_num}.md')
            obs_chapter_data = obs_tools.get_obs_chapter_data(
                self.resources['obs'].repo_dir, chapter_num)
            chapter_title = obs_chapter_data['title']
            # HANDLE RC LINKS FOR OBS SN CHAPTER
            obs_sn_chapter_rc_link = f'rc://{self.lang_code}/obs-sn/help/obs/{chapter_num}'
            obs_sn_chapter_rc = self.add_rc(obs_sn_chapter_rc_link,
                                            title=chapter_title)
            obs_sn_sq_html += f'''
    <section id="{obs_sn_chapter_rc.article_id}">
        <h2 class="section-header">{chapter_title}</h2>
        <section id="{obs_sn_chapter_rc.article_id}-notes" class="no-break">
            <h3 class="section-header no-break">{self.translate('study_notes')}</h3>
'''
            if 'bible_reference' in obs_chapter_data and obs_chapter_data[
                    'bible_reference']:
                obs_sn_sq_html += f'''
                    <div class="bible-reference" class="no-break">{obs_chapter_data['bible_reference']}</div>
            '''
            frames = obs_chapter_data['frames']
            for frame_idx, frame in enumerate(frames):
                image = frame['image']
                frame_num = str(frame_idx + 1).zfill(2)
                frame_title = f'{chapter_num}:{frame_num}'
                obs_sn_file = os.path.join(sn_chapter_dir, f'{frame_num}.md')

                if os.path.isfile(obs_sn_file):
                    notes_html = markdown2.markdown_path(obs_sn_file)
                    notes_html = html_tools.increment_headers(notes_html, 3)
                else:
                    no_study_notes = self.translate(
                        'no_study_notes_for_this_frame')
                    notes_html = f'<div class="no-notes-message">({no_study_notes})</div>'

                # HANDLE RC LINKS FOR OBS SN FRAME
                obs_sn_rc_link = f'rc://{self.lang_code}/obs-sn/help/obs/{chapter_num}/{frame_num}'
                obs_sn_rc = self.add_rc(obs_sn_rc_link,
                                        title=frame_title,
                                        article=notes_html)
                # HANDLE RC LINKS FOR OBS FRAME
                obs_rc_link = f'rc://{self.lang_code}/obs/book/obs/{chapter_num}/{frame_num}'
                self.add_rc(obs_rc_link,
                            title=frame_title,
                            article_id=obs_sn_rc.article_id)

                obs_text = ''
                if frame['text'] and notes_html:
                    obs_text = frame['text']
                    orig_obs_text = obs_text
                    phrases = html_tools.get_phrases_to_highlight(
                        notes_html, 'h4')
                    if phrases:
                        for phrase in phrases:
                            alignment = alignment_tools.split_string_into_alignment(
                                phrase)
                            marked_obs_text = html_tools.mark_phrases_in_html(
                                obs_text, alignment)
                            if not marked_obs_text:
                                self.add_bad_highlight(obs_sn_rc,
                                                       orig_obs_text,
                                                       obs_sn_rc.rc_link,
                                                       phrase)
                            else:
                                obs_text = marked_obs_text

                obs_sn_sq_html += f'''
        <article id="{obs_sn_rc.article_id}">
          <h4>{frame_title}</h4>
          <div class="obs-img-and-text">
            <img src="{image}" class="obs-img"/>
            <div class="obs-text">
                {obs_text}
            </div>
          </div>
          <div class="obs-sn-notes">
            {notes_html}
          </div>
        </article>
'''
            obs_sn_sq_html += '''
    </section>
'''
            if os.path.isfile(sq_chapter_file):
                obs_sq_title = f'{self.translate("study_questions")}'
                obs_sq_html = markdown2.markdown_path(sq_chapter_file)
                obs_sq_html = html_tools.increment_headers(obs_sq_html, 2)
                soup = BeautifulSoup(obs_sq_html, 'html.parser')
                header = soup.find(re.compile(r'^h\d'))
                header.decompose()
                obs_sq_html = str(soup)
                # HANDLE RC LINKS FOR OBS SQ
                obs_sq_rc_link = f'rc://{self.lang_code}/obs-sq/help/obs/{chapter_num}'
                obs_sq_rc = self.add_rc(obs_sq_rc_link,
                                        title=obs_sq_title,
                                        article=obs_sq_html)
                obs_sn_sq_html += f'''
        <article id="{obs_sq_rc.article_id}">
          <h3 class="section-header">{obs_sq_title}</h3>
          {obs_sq_html}
        </article>
    </section>
'''
        obs_sn_sq_html += '''
</section>
'''
        return obs_sn_sq_html
예제 #4
0
    def get_tn_checking_html(self):
        self.populate_tn_groups_data()
        self.populate_tn_book_data()

        by_rc_cat_group = {}
        for chapter in self.tn_book_data:
            for verse in self.tn_book_data[chapter]:
                for data in self.tn_book_data[chapter][verse]:
                    if data['contextId']:
                        rc_link = data['contextId']['rc']
                        parts = rc_link[5:].split('/')
                        category = parts[3]
                        group = parts[4]
                        if category not in by_rc_cat_group:
                            by_rc_cat_group[category] = {}
                        if group not in by_rc_cat_group[category]:
                            by_rc_cat_group[category][group] = []
                        by_rc_cat_group[category][group].append(data)

        tn_html = f'''
<section id="{self.lang_code}-{self.name}-{self.project_id}" class="{self.name}">
    <article id="{self.lang_code}-{self.name}-{self.project_id}-cover" class="resource-title-page">
        <img src="{self.main_resource.logo_url}" class="logo" alt="UTN">
        <h1 class="section-header">{self.title}</h1>
        <h2 class="section-header">{self.project_title}</h2>
    </article>
'''

        categories = sorted(by_rc_cat_group.keys())
        for category in categories:
            groups = sorted(by_rc_cat_group[category].keys())
            for group in groups:
                tn_rc_link = f'rc://{self.lang_code}/tn/help/{category}/{group}'
                tn_rc = self.add_rc(tn_rc_link, title=f'{group} ({category})')
                tn_html += f'''
    <article id="{tn_rc.article_id}">
        <h3 class="section-header">Support Reference: [[{tn_rc.rc_link}]]</h3>
        <table width="100%">
            <tr>
               <th style="width:1px;padding:0 !important"></th>
               <th>Verse</th>
               <th>{self.ult_id.upper()} Alignment</th>
               <th>{self.ult_id.upper()} Text</th>
               <th>{self.ust_id.upper()} Alignment</th>
               <th>{self.ust_id.upper()} Text</th>
               <th>{self.ol_bible_id.upper()} Quote</th>
               <th>{self.ol_bible_id.upper()} Text</th>
            </tr>
'''
                for group_data in by_rc_cat_group[category][group]:
                    context_id = group_data['contextId']
                    context_id['rc'] = tn_rc.rc_link
                    chapter = str(context_id['reference']['chapter'])
                    verse = str(context_id['reference']['verse'])
                    group_data['scripture'] = {}
                    for bible_id in [self.ult_id, self.ust_id]:
                        alignment = group_data['alignments'][bible_id]
                        if not alignment:
                            group_data['alignments'][
                                bible_id] = '<div style="color: red">NONE</div>'
                        else:
                            group_data['alignments'][
                                bible_id] = flatten_alignment(alignment)
                        scripture = self.get_plain_scripture(
                            bible_id, chapter, verse)
                        marked_html = None
                        if alignment:
                            marked_html = mark_phrases_in_html(
                                scripture, alignment)
                        if marked_html:
                            group_data['scripture'][bible_id] = marked_html
                        else:
                            group_data['scripture'][
                                bible_id] = f'<div style="color: red">{scripture}</div>'
                    scripture = self.get_plain_scripture(
                        self.ol_bible_id, chapter, verse)
                    ol_alignment = split_string_into_alignment(
                        group_data['OrigQuote'])
                    marked_html = mark_phrases_in_html(scripture, ol_alignment)
                    if marked_html:
                        group_data['scripture'][self.ol_bible_id] = marked_html
                    else:
                        marked_html = mark_phrases_in_html(scripture,
                                                           ol_alignment,
                                                           break_on_word=False)
                        if marked_html:
                            scripture = marked_html
                        group_data['scripture'][
                            self.
                            ol_bible_id] = f'<div style="color: red">{scripture}</div>'
                    tn_html += f'''
            <tr id="{group_data['rc'].article_id}">
                <td style="width:1px;padding:0 !important"><a id="{group_data['ID']}"></a><a href="#{group_data['rc'].article_id}"><i class="fa fa-link"></i></a></td>
                <td>
                    {chapter}:{verse}
                    (<a href="https://git.door43.org/unfoldingWord/{self.lang_code}_tn/src/branch/master/{self.lang_code}_tn_{self.book_number}-{self.project_id.upper()}.tsv#L{group_data['row']}" target="tn-repo">{group_data['ID']}</a>)
                </td>
                <td>
                    {group_data['alignments'][self.ult_id]}
                </td>
                <td>
                    {group_data['scripture'][self.ult_id]}
                </td>
                <td>
                    {group_data['alignments'][self.ust_id]}
                </td>
                <td>
                    {group_data['scripture'][self.ust_id]}
                </td>
                <td style="direction: {'rtl' if self.ol_lang_code == 'hbo' else 'ltr'}">
                    {group_data['OrigQuote']}
                </td>
                <td style="direction: {'rtl' if self.ol_lang_code == 'hbo' else 'ltr'}">
                    {group_data['scripture'][self.ol_bible_id]}
                </td>
            </tr>
'''
                tn_html += '''
        </table>
    </article>
'''

        tn_html += '''
</section>
'''
        self.logger.info('Done generating TN Checking HTML.')
        return tn_html
    def get_body_html(self):
        self.logger.info('Generating OBS SN html...')
        obs_sn_html = f'''
<section id="{self.lang_code}-obs-sn">
    <div class="resource-title-page no-header">
        <img src="{self.resources['obs-sn'].logo_url}" class="logo" alt="OBS">
        <h1 class="section-header">{self.simple_title}</h1>
    </div>
'''
        for chapter in range(1, 51):
            chapter_num = str(chapter).zfill(2)
            sn_chapter_dir = os.path.join(self.resources['obs-sn'].repo_dir, 'content', chapter_num)
            chapter_data = obs_tools.get_obs_chapter_data(self.resources['obs'].repo_dir, chapter_num)
            obs_sn_html += f'<article id="{self.lang_code}-obs-sn-{chapter_num}">\n\n'
            obs_sn_html += f'<h2 class="section-header">{chapter_data["title"]}</h2>\n'
            if 'bible_reference' in chapter_data and chapter_data['bible_reference']:
                obs_sn_html += f'''
                    <div class="bible-reference no-break">{chapter_data['bible_reference']}</div>
'''
            for frame_idx, frame in enumerate(chapter_data['frames']):
                frame_num = str(frame_idx+1).zfill(2)
                frame_title = f'{chapter_num}:{frame_num}'
                obs_sn_file = os.path.join(sn_chapter_dir, f'{frame_num}.md')

                if os.path.isfile(obs_sn_file):
                    notes_html = markdown2.markdown_path(obs_sn_file)
                    notes_html = html_tools.increment_headers(notes_html, 3)
                else:
                    no_study_notes = self.translate('no_study_notes_for_this_frame')
                    notes_html = f'<div class="no-notes-message">({no_study_notes})</div>'

                # HANDLE RC LINKS FOR OBS SN FRAMES
                obs_sn_rc_link = f'rc://{self.lang_code}/obs-sn/help/obs/{chapter_num}/{frame_num}'
                obs_sn_rc = self.add_rc(obs_sn_rc_link, title=frame_title, article=notes_html)
                # HANDLE RC LINKS FOR OBS FRAMES
                obs_rc_link = f'rc://{self.lang_code}/obs/bible/obs/{chapter_num}/{frame_num}'
                self.add_rc(obs_rc_link, title=frame_title, article_id=obs_sn_rc.article_id)

                obs_text = ''
                if frame['text'] and notes_html:
                    obs_text = frame['text']
                    orig_obs_text = obs_text
                    phrases = html_tools.get_phrases_to_highlight(notes_html, 'h4')
                    if phrases:
                        for phrase in phrases:
                            alignment = alignment_tools.split_string_into_alignment(phrase)
                            marked_obs_text = html_tools.mark_phrases_in_html(obs_text, alignment)
                            if not marked_obs_text:
                                self.add_bad_highlight(obs_sn_rc, orig_obs_text, obs_sn_rc.rc_link, phrase)
                            else:
                                obs_text = marked_obs_text

                obs_sn_html += f'''
<div id="{obs_sn_rc.article_id}" class="frame">
    <h3>{frame_title}</h3>
    <div id="{obs_sn_rc.article_id}-text" class="frame-text">
        {obs_text}
    </div>
    <div id="{obs_sn_rc.article_id}-notes" class="frame-notes">
        {notes_html}
    </div>
</div>
'''
                if frame_idx < len(chapter_data['frames']) - 1:
                    obs_sn_html += '<hr class="frame-divider"/>'
            obs_sn_html += '</article>\n\n'
        obs_sn_html += '</section>'
        return obs_sn_html
예제 #6
0
    def get_tw_checking_html(self):
        tw_html = f'''
<section id="{self.lang_code}-{self.name}-{self.project_id}" class="{self.name}">
    <article id="{self.lang_code}-{self.name}-{self.project_id}-cover" class="resource-title-page">
        <img src="{self.main_resource.logo_url}" class="logo" alt="UTW">
        <h1 class="section-header">{self.title}</h1>
        <h2 class="section-header">{self.project_title}</h2>
    </article>
'''

        tw_path = os.path.join(self.resources_dir, self.ol_lang_code,
                               'translationHelps/translationWords')
        if not tw_path:
            self.logger.error(f'{tw_path} not found!')
            exit(1)
        tw_version_path = get_latest_version_path(tw_path)
        if not tw_version_path:
            self.logger.error(f'No versions found in {tw_path}!')
            exit(1)

        groups = get_child_directories(tw_version_path)
        for group in groups:
            files_path = os.path.join(tw_version_path,
                                      f'{group}/groups/{self.project_id}',
                                      '*.json')
            files = glob(files_path)
            for file in files:
                base = os.path.splitext(os.path.basename(file))[0]
                tw_rc_link = f'rc://{self.lang_code}/tw/dict/bible/{group}/{base}'
                tw_rc = self.add_rc(tw_rc_link, title=base)
                self.get_tw_article_html(tw_rc)
                tw_html += f'''
    <article id="{tw_rc.article_id}">
        <h3 class="section-header">[[{tw_rc.rc_link}]]</h3>
        <table width="100%">
            <tr>
               <th style="width:1px;padding:0 !important"></th>
               <th>Verse</th>
               <th>{self.ult_id.upper()} Alignment</th>
               <th>{self.ult_id.upper()} Text</th>
               <th>{self.ust_id.upper()} Alignment</th>
               <th>{self.ust_id.upper()} Text</th>
               <th>{self.ol_bible_id.upper()} Quote</th>
               <th>{self.ol_bible_id.upper()} Text</th>
            </tr>
'''

                tw_group_data = load_json_object(file)
                for group_data in tw_group_data:
                    context_id = group_data['contextId']
                    context_id['rc'] = tw_rc.rc_link
                    chapter = str(context_id['reference']['chapter'])
                    verse = str(context_id['reference']['verse'])
                    context_id['scripture'] = {}
                    context_id['alignments'] = {}
                    for bible_id in [self.ult_id, self.ust_id]:
                        alignment = self.get_aligned_text(
                            bible_id, group_data['contextId'])
                        if alignment:
                            context_id['alignments'][
                                bible_id] = flatten_alignment(alignment)
                        else:
                            context_id['alignments'][
                                bible_id] = '<div style="color: red">NONE</div>'
                        scripture = self.get_plain_scripture(
                            bible_id, chapter, verse)
                        marked_html = None
                        if alignment:
                            marked_html = mark_phrases_in_html(
                                scripture, alignment)
                        if marked_html:
                            context_id['scripture'][bible_id] = marked_html
                        else:
                            context_id['scripture'][
                                bible_id] = f'<div style="color: red">{scripture}</div>'
                    scripture = self.get_plain_scripture(
                        self.ol_bible_id, chapter, verse)
                    ol_alignment = context_id['quote']
                    if isinstance(ol_alignment, str):
                        ol_alignment = split_string_into_alignment(
                            ol_alignment)
                    if not isinstance(ol_alignment[0], list):
                        ol_alignment = convert_single_dimensional_quote_to_multidimensional(
                            ol_alignment)
                    marked_html = mark_phrases_in_html(scripture, ol_alignment)
                    if marked_html:
                        context_id['scripture'][self.ol_bible_id] = marked_html
                    else:
                        context_id['scripture'][
                            self.
                            ol_bible_id] = f'<div style="color: red">{scripture}</div>'
                    tw_html += f'''
            <tr id="{tw_rc.article_id}-{chapter}-{verse}">
                <td style="width:1px;padding:0 !important"><a href="#{tw_rc.article_id}-{chapter}-{verse}"><i class="fa fa-link"></i></td>
                <td>
                    {chapter}:{verse}
                </td>
                <td>
                    {context_id['alignments'][self.ult_id]}
                </td>
                <td>
                    {context_id['scripture'][self.ult_id]}
                </td>
                <td>
                    {context_id['alignments'][self.ust_id]}
                </td>
                <td>
                    {context_id['scripture'][self.ust_id]}
                </td>
                <td style="direction: {'rtl' if self.ol_lang_code == 'hbo' else 'ltr'}">
                    {flatten_alignment(ol_alignment)}
                </td>
                <td style="direction: {'rtl' if self.ol_lang_code == 'hbo' else 'ltr'}">
                    {context_id['scripture'][self.ol_bible_id]}
                </td>
            </tr>
'''
                tw_html += '''
        </table>
    </article>
'''

        tw_html += '''
</section>
'''
        self.logger.info('Done generating TW Checking HTML.')
        return tw_html
    def get_obs_tn_html(self):
        obs_tn_html = f'''
<section id="obs-sn">
    <div class="resource-title-page no-header">
        <img src="{self.resources['obs'].logo_url}" class="logo" alt="OBS">
        <h1 class="section-header">{self.simple_title}</h1>
    </div>
'''
        obs_tn_chapter_dirs = sorted(
            glob(os.path.join(self.main_resource.repo_dir, 'content', '*')))
        for obs_tn_chapter_dir in obs_tn_chapter_dirs:
            if os.path.isdir(obs_tn_chapter_dir):
                chapter_num = os.path.basename(obs_tn_chapter_dir)
                chapter_data = obs_tools.get_obs_chapter_data(
                    self.resources['obs'].repo_dir, chapter_num)
                obs_tn_html += f'''
    <article id="{self.lang_code}-obs-tn-{chapter_num}">
        <h2 class="section-header">{chapter_data['title']}</h2>
'''
                frames = [None] + chapter_data[
                    'frames']  # first item of '' if there are intro notes from the 00.md file
                for frame_idx, frame in enumerate(frames):
                    frame_num = str(frame_idx).zfill(2)
                    frame_title = f'{chapter_num}:{frame_num}'
                    notes_file = os.path.join(obs_tn_chapter_dir,
                                              f'{frame_num}.md')
                    notes_html = ''
                    if os.path.isfile(notes_file):
                        notes_html = markdown2.markdown_path(notes_file)
                        notes_html = html_tools.increment_headers(
                            notes_html, 3)
                    if (not frame or not frame['text']) and not notes_html:
                        continue

                    # HANDLE RC LINKS FOR OBS FRAME
                    frame_rc_link = f'rc://{self.lang_code}/obs/book/obs/{chapter_num}/{frame_num}'
                    frame_rc = self.add_rc(frame_rc_link, title=frame_title)
                    # HANDLE RC LINKS FOR NOTES
                    notes_rc_link = f'rc://{self.lang_code}/obs-tn/help/{chapter_num}/{frame_num}'
                    notes_rc = self.add_rc(notes_rc_link,
                                           title=frame_title,
                                           article=notes_html)

                    obs_text = ''
                    if frame and frame['text']:
                        obs_text = frame['text']
                        orig_obs_text = obs_text
                        if notes_html:
                            phrases = html_tools.get_phrases_to_highlight(
                                notes_html, 'h4')
                            for phrase in phrases:
                                alignment = alignment_tools.split_string_into_alignment(
                                    phrase)
                                marked_obs_text = html_tools.mark_phrases_in_html(
                                    obs_text, alignment)
                                if not marked_obs_text:
                                    if self.lang_code in TN_TITLES_TO_IGNORE and \
                                            phrase.lower() not in TN_TITLES_TO_IGNORE[self.lang_code]:
                                        self.add_bad_highlight(
                                            notes_rc, orig_obs_text,
                                            notes_rc.rc_link, phrase)
                                else:
                                    obs_text = marked_obs_text

                    if frame_idx == len(frames) - 1:
                        if 'bible_reference' in chapter_data and chapter_data[
                                'bible_reference']:
                            notes_html += f'''
                                <div class="bible-reference" class="no-break">{chapter_data['bible_reference']}</div>
                        '''
                    # Some OBS TN languages (e.g. English) do not have Translation Words in their TN article
                    # while some do (e.g. French). We need to add them ourselves from the tw_cat file
                    if notes_html and '/tw/' not in notes_html and chapter_num in self.tw_cat and \
                            frame_num in self.tw_cat[chapter_num] and len(self.tw_cat[chapter_num][frame_num]):
                        notes_html += f'''
           <h3>{self.resources['tw'].simple_title}</h3>
           <ul>
'''
                        for rc_link in self.tw_cat[chapter_num][frame_num]:
                            notes_html += f'''
                <li>[[{rc_link}]]</li>
'''
                        notes_html += '''
            </ul>
'''
                    notes_rc.set_article(notes_html)

                    if obs_text:
                        obs_text = f'''
            <div id="{frame_rc.article_id}" class="frame-text">
                {obs_text}
            </div>
'''
                    if notes_html:
                        notes_html = f'''
            <div id="{notes_rc.article_id}-notes" class="frame-notes">
                {notes_html}
            </div>
'''

                    obs_tn_html += f'''
        <div id="{notes_rc.article_id}">
            <h3>{frame_title}</h3>
            {obs_text}
            {notes_html}
        </div>
'''
                    if frame_idx < len(frames) - 1:
                        obs_tn_html += '<hr class="frame-divider"/>\n'
                obs_tn_html += '''
    </article>
'''
        obs_tn_html += '''
</section>
'''
        return obs_tn_html