private void Write_body_wikitext(
      Bry_bfr bfr,
      Xoae_app app,
      Xowe_wiki wiki,
      byte[] data_raw,
      Xop_ctx ctx,
      Xoh_wtr_ctx hctx,
      Xoae_page page,
      byte page_tid,
      int ns_id) {
    // dump and exit if pre-generated html from html dumps
    byte[] hdump_data = page.Db().Html().Html_bry();
    if (Bry_.Len_gt_0(hdump_data)) {
      bfr.Add(hdump_data);
      return;
    }

    // dump and exit if MediaWiki message;
    if (ns_id
        == Xow_ns_
            .Tid__mediawiki) { // if MediaWiki and wikitext, must be a message; convert args back to
                               // php; DATE:2014-06-13
      bfr.Add(Gfs_php_converter.Xto_php(tmp_bfr, Bool_.N, data_raw));
      return;
    }

    // if [[File]], add boilerplate header; note that html is XOWA-generated so does not need to be
    // tidied
    if (ns_id == Xow_ns_.Tid__file)
      app.Ns_file_page_mgr()
          .Bld_html(wiki, ctx, page, bfr, page.Ttl(), wiki.Cfg_file_page(), page.File_queue());

    // get separate bfr; note that bfr already has <html> and <head> written to it, so this can't be
    // passed to tidy; DATE:2014-06-11
    Bry_bfr tidy_bfr = wiki.Utl__bfr_mkr().Get_m001();

    // write wikitext
    if (page.Html_data().Skip_parse()) {
      tidy_bfr.Add(page.Html_data().Custom_body());
    } else {
      if (page.Root()
          != null) { // NOTE: will be null if blank; occurs for one test:
                     // Logo_has_correct_main_page; DATE:2015-09-29
        page.Html_data()
            .Toc_mgr()
            .Clear(); // NOTE: always clear tocs before writing html; toc_itms added when writing
                      // html_hdr; DATE:2016-07-17
        wiki.Html_mgr()
            .Html_wtr()
            .Write_doc(tidy_bfr, ctx, hctx, page.Root().Data_mid(), page.Root());
        if (wiki.Html_mgr().Html_wtr().Cfg().Toc__show())
          gplx.xowa.htmls.core.wkrs.tocs.Xoh_toc_wtr.Write_toc(tidy_bfr, page, hctx);
      }
    }

    // if [[Category]], add catpage data
    if (ns_id == Xow_ns_.Tid__category) tidy_bfr.Add_safe(page.Html_data().Catpage_data());
    // if (ns_id == Xow_ns_.Tid__category) wiki.Ctg__catpage_mgr().Write_catpage(tidy_bfr, page,
    // hctx);

    // tidy html
    wiki.Html_mgr().Tidy_mgr().Exec_tidy(tidy_bfr, !hctx.Mode_is_hdump(), page.Url_bry_safe());

    // add back to main bfr
    bfr.Add_bfr_and_clear(tidy_bfr);
    tidy_bfr.Mkr_rls();

    // handle Categories at bottom of page; note that html is XOWA-generated so does not need to be
    // tidied
    int ctgs_len = page.Wtxt().Ctgs__len();
    if (ctgs_enabled
        && ctgs_len > 0 // skip if no categories found while parsing wikitext
        && !wiki.Html_mgr()
            .Importing_ctgs() // do not show categories if importing categories, page will wait for
                              // category import to be done; DATE:2014-10-15
        && !hctx.Mode_is_hdump() // do not dump categories during hdump; DATE:2016-10-12
    ) {
      if (app.Mode().Tid_is_gui())
        app.Usr_dlg().Prog_many("", "", "loading categories: count=~{0}", ctgs_len);
      Xoctg_pagebox_itm[] pagebox_itms = wiki.Ctg__pagebox_wtr().Get_catlinks_by_page(wiki, page);
      boolean hidden_enabled = wiki.App().Api_root().Addon().Wikis__ctgs__hidden_enabled();
      wiki.Ctg__pagebox_wtr().Write_pagebox(hidden_enabled, bfr, wiki, page, pagebox_itms);
    }

    // translate if variants are enabled
    Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
    if (vnt_mgr.Enabled())
      bfr.Add(
          vnt_mgr.Convert_lang()
              .Parse_page(vnt_mgr.Cur_itm(), page.Db().Page().Id(), bfr.To_bry_and_clear()));
  }
  private void Write_page_by_tid(
      Xop_ctx ctx,
      Xoh_wtr_ctx hctx,
      byte html_gen_tid,
      Bry_bfr bfr,
      Bry_fmtr fmtr,
      byte[] page_data) {
    // if custom_html, use it and exit; needed for Default_tab
    byte[] custom_html = page.Html_data().Custom_html();
    if (custom_html != null) {
      bfr.Add(custom_html);
      return;
    }
    // temp variables
    if (root_dir_bry == null) this.root_dir_bry = app.Fsys_mgr().Root_dir().To_http_file_bry();
    Xoa_ttl page_ttl = page.Ttl();
    int page_ns_id = page_ttl.Ns().Id();
    byte page_tid = Xow_page_tid.Identify(wiki.Domain_tid(), page_ns_id, page_ttl.Page_db());
    DateAdp modified_on = page.Db().Page().Modified_on();
    byte[] modified_on_msg =
        wiki.Msg_mgr()
            .Val_by_id_args(
                Xol_msg_itm_.Id_portal_lastmodified,
                modified_on.XtoStr_fmt_yyyy_MM_dd(),
                modified_on.XtoStr_fmt_HHmm());
    byte[] page_body_class = Xoh_page_body_cls.Calc(tmp_bfr, page_ttl, page_tid);
    byte[] html_content_editable =
        wiki.Gui_mgr().Cfg_browser().Content_editable() ? Content_editable_bry : Bry_.Empty;
    byte[] page_content_sub = Xoh_page_wtr_wkr_.Bld_page_content_sub(app, wiki, page, tmp_bfr);
    byte[] js_edit_toolbar_bry =
        html_gen_tid == Xopg_page_.Tid_edit
            ? wiki.Fragment_mgr().Html_js_edit_toolbar()
            : Bry_.Empty;
    Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
    if (vnt_mgr.Enabled()) {
      byte[] converted_title = vnt_mgr.Convert_lang().Converted_title(); // prefer converted title
      if (converted_title
          == null) // converted title does not exist; use regular page title and convert it
      converted_title = vnt_mgr.Convert_lang().Auto_convert(vnt_mgr.Cur_itm(), page_ttl.Page_txt());
      page_ttl = Xoa_ttl.Parse(wiki, page_ttl.Ns().Id(), converted_title);
    }
    byte[] page_name =
        Xoh_page_wtr_wkr_.Bld_page_name(
            tmp_bfr, page_ttl,
            null); // NOTE: page_name does not show display_title (<i>). always pass in null
    byte[] page_display_title =
        Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, page_ttl, page.Html_data().Display_ttl());
    page.Html_data()
        .Custom_tab_name_(
            page_name); // set tab_name to page_name; note that if null, gui code will ignore and
                        // use Ttl.Page_txt; PAGE: zh.w:釣魚臺列嶼主權問題 DATE:2015-10-05
    Xow_portal_mgr portal_mgr = wiki.Html_mgr().Portal_mgr().Init_assert();
    fmtr.Bld_bfr_many(
        bfr,
        root_dir_bry,
        Xoa_app_.Version,
        Xoa_app_.Build_date,
        app.Tcp_server().Running_str(),
        page.Db().Page().Id(),
        page.Ttl().Full_db(),
        page_name,
        page.Html_data().Page_heading().Init(page.Html_data(), page_display_title),
        modified_on_msg,
        mgr.Css_common_bry(),
        mgr.Css_wiki_bry(),
        page.Html_data().Head_mgr().Init(app, wiki, page).Init_dflts(),
        page.Lang().Dir_ltr_bry(),
        page.Html_data().Indicators(),
        page_content_sub,
        wiki.Html_mgr().Portal_mgr().Div_jump_to(),
        wiki.Xtn_mgr().Xtn_pgbnr().Write_html(page, ctx, hctx),
        page_body_class,
        html_content_editable,
        page_data,
        wdata_lang_wtr

        // sidebar divs
        ,
        portal_mgr.Div_personal_bry(),
        portal_mgr.Div_ns_bry(wiki.Utl__bfr_mkr(), page_ttl, wiki.Ns_mgr()),
        portal_mgr.Div_view_bry(
            wiki.Utl__bfr_mkr(), html_gen_tid, page.Html_data().Xtn_search_text()),
        portal_mgr.Div_logo_bry(),
        portal_mgr.Div_home_bry(),
        new Xopg_xtn_skin_fmtr_arg(page, Xopg_xtn_skin_itm_tid.Tid_sidebar),
        portal_mgr.Div_sync_bry(
            tmp_bfr, app.Api_root().Addon().Bldr().Sync().Manual_enabled(), wiki, page),
        portal_mgr.Div_wikis_bry(wiki.Utl__bfr_mkr()),
        portal_mgr.Sidebar_mgr().Html_bry(),
        mgr.Edit_rename_div_bry(page_ttl),
        page.Html_data().Edit_preview_w_dbg(),
        js_edit_toolbar_bry);
    Xoh_page_wtr_wkr_.Bld_head_end(bfr, tmp_bfr, page); // add after </head>
    Xoh_page_wtr_wkr_.Bld_html_end(bfr, tmp_bfr, page); // add after </html>		
  }