PBToolboxAI v5 ← Site

markdownview — u_pbt_markdownview #

← Référence des composants · Sommaire du guide

markdownview affiche un document Markdown en lecture seule, aux couleurs du thème : titres, listes, tableaux, listes de tâches, code coloré, images. Vous posez le texte dans is_markdown, ou le chemin d'un fichier dans is_source ; un lien ne navigue jamais, il lève ue_link_clicked et c'est l'application qui décide. Le HTML brut d'un document n'est jamais exécuté.

▶ Le voir en vrai — Application de démonstration, tuile Markdown viewer, avec le code et cette page côte à côte.


En bref #

Userobjectu_pbt_markdownview
EntréeUn texte Markdown (is_markdown), ou un fichier du poste ou une URL https:// (is_source)
SyntaxeCommonMark, plus les tableaux, les listes de tâches, le barré, les liens et adresses e-mail nus, les alertes (> [!NOTE]) et les émojis (:+1:) de GitHub
Retourue_link_clicked pour un lien, avec sa nature (l'application décide), ue_loaded / ue_load_failed pour un document, ue_search_result pour la recherche, ue_task_toggled pour une case cochée
SécuritéLe HTML brut est montré comme du texte ; un lien javascript:, vbscript: ou data: n'est pas cliquable ; une image http:// est refusée, une image d'un partage réseau aussi ; un document du Web n'affiche aucun fichier du poste

Démarrage rapide #

// Show a Markdown file : its pictures and relative links are read against its folder
uo_md.is_source = "C:\Acme\Help\guide.md"

// ... or any text the application has
uo_md.is_markdown = "# Release notes~n~n- [x] Orders~n- [ ] Invoices"

// ue_link_clicked : the viewer never navigates, the application decides where to open as_url

Propriétés #

PropriétéTypeDéfautDescription
is_markdownstring""Le texte Markdown à montrer. Le poser remplace le document (is_source se relit alors vide) ; vide efface la vue. Un nouveau texte du MÊME document — la recette d'édition — garde la position de lecture. Le HTML brut qu'il contient est affiché comme du texte, jamais exécuté (voir ib_allow_html). Se relit tel qu'il a été posé
is_sourcestring""Un fichier Markdown à montrer : un chemin du poste (.md, .markdown, .txt…), une adresse file:/// ou une URL https:// — lue par le client HTTPS natif de la bibliothèque (le proxy et l'identité Windows du poste, aucun mur CORS). Ses images et liens relatifs se lisent contre son dossier. http:// est refusé (REASON_INSECURE), comme tout fichier qui n'est pas du texte (REASON_UNSUPPORTED) ; au-delà de 16 Mo, fichier ou URL, REASON_TOO_LARGE. Le fichier se lit en arrière-plan : lisez la table des matières ou déplacez-vous dedans une fois ue_loaded reçu (pendant la lecture, of_toc rend 0 et of_scroll_to attend le fichier). Le poser remplace le document (is_markdown se relit alors vide)
is_base_pathstring""Le dossier (ou l'adresse https://) contre lequel se lisent les images et liens relatifs d'un TEXTE posé par is_markdown — une aide gardée en base de données à côté de ses images. Vide : le dossier courant de l'application. Un fichier montré par is_source prend toujours son propre dossier. Lue en direct
ib_allow_htmlbooleanfalsetrue dessine une liste COURTE et fermée de balises HTML inertes du document — b, i, u, s, kbd, sub, sup, mark, small, br, img (src, alt, width, height : les règles d'une image Markdown), a (href : les règles d'un lien Markdown) et details / summary. Toute autre balise, un script, un style, un gestionnaire d'événement restent du texte. false : tout le HTML est montré tel qu'écrit
ib_network_picturesbooleanfalsefalse : une image du document posée sur le RÉSEAU (un partage d'un serveur) n'est pas chargée — ouvrir un partage livre l'identité Windows de l'utilisateur à ce serveur —, sauf si elle est sur le partage d'où le document lui-même a été lu. true : pour l'application qui montre SES documents depuis un partage. Un document lu sur le Web n'affiche jamais un fichier du poste
ib_remote_picturesbooleantruetrue charge les images https:// d'un document ; false n'en charge aucune — rien ne quitte le poste du seul fait qu'un document est affiché (un pixel de suivi reste une vignette)
ib_tasks_editablebooleanfalsetrue laisse l'utilisateur cocher les cases d'une liste de tâches (un clic, ou Espace sur une case) : ue_task_toggled donne la LIGNE du source et le nouvel état ; le TEXTE reste à l'application, qui le réécrit. false : les cases sont en lecture seule
ib_track_headingbooleanfalsetrue lève ue_heading_visible chaque fois qu'un autre titre atteint le haut de la vue pendant que le lecteur fait défiler — une table des matières qui suit la lecture
ii_zoominteger100La taille de lecture, de 50 à 300 % (100 : la taille du thème). Ctrl+molette dans le document la change par pas de 10 ; lue en direct
is_positionstring""La position de lecture, un texte comme 12:35 (le premier bloc visible et de combien il commence au-dessus du haut). Lisez-la avant de fermer un long document, reposez-la pour le rouvrir là où le lecteur l'avait laissé. Lue en direct ; vide quand rien n'est affiché. Un fichier en cours de lecture la prend une fois à l'écran
ib_search_enabledbooleantrueCtrl+F dans le document ouvre une zone de recherche — la même recherche que of_search : taper surligne, Entrée ou F3 suivant, Maj+Entrée ou Maj+F3 précédent, Échap ferme. false laisse le raccourci à une application qui cherche depuis sa propre zone
ib_find_match_casebooleanfalseOption de recherche : ne trouve que le texte de même casse. La bascule Aa de la zone de recherche est le même interrupteur. Lue en direct ; of_reset la remet à false
ib_find_whole_wordbooleanfalseOption de recherche : ne trouve le texte que comme mot entier (pen n'est pas trouvé dans pencil). La bascule ab de la zone de recherche est le même interrupteur. Lue en direct ; of_reset la remet à false
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)
is_tooltipstring""Info-bulle simple affichée au survol du composant
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie

Méthodes #

MéthodeDescription
of_clear ( ) → longVide la vue : is_markdown et is_source se relisent vides ; ib_search_enabled et les options de recherche gardent leur valeur (c'est of_reset qui remet chaque propriété). Une recherche ouverte le dit : ue_search_result(0, 0). Rend 0, -2 si le composant n'est pas créé
of_clear_search ( ) → longEfface la recherche : plus de surlignage ni d'occurrence courante (of_match_count rend 0), la zone de recherche se ferme. Rend 0, -2 si le composant n'est pas créé
of_copy ( ) → longCopie dans le presse-papiers le texte que l'utilisateur a sélectionné — ce que font Ctrl+C et Ctrl+Inser dans le document. Rend 0, -5 si rien n'est sélectionné, -2 si le composant n'est pas créé
of_match_count ( ) → longRend le nombre d'occurrences de la recherche courante, lu EN DIRECT — le 12 d'une barre d'état 3 / 12 ; 50 000 au plus sont comptées. 0 sans recherche
of_match_index ( ) → longRend la position (1-basée) de l'occurrence courante, lue EN DIRECT — le 3 d'une barre d'état 3 / 12. 0 sans occurrence
of_refresh ( ) → longRelit is_source (sur le disque ou le réseau) : de quoi montrer un fichier réécrit au même chemin ; la position de lecture est gardée ; ue_loaded ou ue_load_failed suit. Rend 0, -5 si aucun document n'est montré, -2 si le composant n'est pas créé
of_scroll_to ( string as_anchor ) → longAmène le titre as_anchor en haut de la vue : son ancre telle que of_toc la donne, avec ou sans #, ou son texte ; un titre dans un details fermé l'ouvre. Pendant la lecture d'un fichier posé par is_source, l'ancre attend le fichier et l'appel rend 0. Rend 0, -5 si aucun titre ne correspond, -2 si le composant n'est pas créé
of_search ( string as_query ) → longSurligne chaque occurrence (sans casse par défaut — voir ib_find_match_case —, en mot entier avec ib_find_whole_word) et saute à la première ; une occurrence peut traverser un gras, un lien ou un retour à la ligne du source, jamais un saut de ligne forcé. ue_search_result dit combien (50 000 au plus). Une requête vide est of_clear_search. Pendant la lecture d'un fichier, la recherche porte sur lui quand il arrive. La zone de recherche s'ouvre avec la requête dedans ; avec ib_search_enabled à false, le document surligne seulement. Rend 0, -2 si le composant n'est pas créé
of_search_next ( ) → longPasse à l'occurrence SUIVANTE (revient à la première après la dernière) ; ue_search_result donne la nouvelle position. Rend 0, -2 si le composant n'est pas créé
of_search_prev ( ) → longPasse à l'occurrence PRÉCÉDENTE (revient à la dernière avant la première) ; ue_search_result donne la nouvelle position. Rend 0, -2 si le composant n'est pas créé
of_selected_text ( ) → stringRend le texte que l'utilisateur a sélectionné dans le document, lu EN DIRECT — vide quand rien n'est sélectionné
of_toc ( ref string as_titles[], ref long al_levels[], ref string as_anchors[] ) → longLa table des matières, lue EN DIRECT : une entrée par titre, dans l'ordre — son texte, son niveau (1 à 6) et son ancre (ce que prennent of_scroll_to et un lien #ancre, à la manière de GitHub : « Release checklist » donne release-checklist). Les tableaux sont vidés d'abord. Rend le nombre de titres, 0 pour un document sans titre — et pendant la lecture d'un fichier posé par is_source : demandez-la dans ue_loaded

Événements #

ÉvénementQuand
ue_heading_visible (string as_anchor)Avec ib_track_heading : un autre titre a atteint le haut de la vue. as_anchor est son ancre telle que of_toc la donne, vide au-dessus du premier titre
ue_link_clicked (string as_url, string as_kind)L'utilisateur a suivi un lien (un clic, ou Entrée sur un lien qui a le focus). Le composant ne navigue PAS : ouvrez as_url où vous voulez. as_kind dit ce que c'est — LINK_WEB, LINK_MAIL, LINK_DOCUMENT (un fichier Markdown ou texte que ce composant sait montrer), LINK_FILE (tout autre fichier : ne le lancez jamais sans demander), LINK_OTHER. Un lien relatif d'un fichier montré par is_source arrive résolu contre son dossier ; un lien #titre défile tout seul et n'est pas levé ; un lien javascript: ou data: n'est même pas cliquable
ue_loaded (string as_source)Le document est à l'écran : as_source est is_source tel que vous l'avez écrit, ou une chaîne vide pour un texte posé par is_markdown
ue_load_failed (string as_source, string as_reason)Le document n'a pas pu être montré : as_reason est l'une des constantes REASON_* — REASON_NOT_FOUND (pas de fichier), REASON_TOO_LARGE (plus de 16 Mo), REASON_INSECURE (http://), REASON_UNSUPPORTED (pas un fichier texte, ou un autre protocole), REASON_FAILED (une erreur de lecture ou de réseau, ou un texte illisible). as_source est vide pour un texte posé par is_markdown ; le document précédent reste affiché. ue_loaded n'est pas levé
ue_search_result (long al_count, long al_index)Une recherche a démarré ou avancé : al_count occurrences en tout (50 000 au plus), la courante est al_index (1-basé, 0 si aucune) — de quoi afficher « 3 / 12 »
ue_task_toggled (long al_line, boolean ab_checked)Avec ib_tasks_editable : l'utilisateur a coché (ab_checked à true) ou décoché une case d'une liste de tâches. al_line est la ligne du source Markdown (1-basée). Le composant ne réécrit pas le texte : l'application change [ ] / [x] sur cette ligne et repose le texte (voir l'exemple)

Exemple #

Une aide en ligne qui ouvre ses liens #

Un document vient souvent d'ailleurs : le tri se fait sur la nature du lien, jamais sur son texte. Une page Web ou un courriel s'ouvrent dans leur programme, un autre document s'affiche dans le même composant, et un fichier — un .exe, un .bat — n'est jamais lancé sans demander.

// ue_link_clicked of uo_md : the viewer never navigates, the application decides by the kind
choose case as_kind
	case u_pbt_markdownview.LINK_WEB, u_pbt_markdownview.LINK_MAIL

		// A web page, a mail : their program
		ShellExecuteW(0, "open", as_url, "", "", 1)
	case u_pbt_markdownview.LINK_DOCUMENT

		// Another page of the help : in this viewer
		uo_md.is_source = as_url
	case else

		// A file of the disk or of the network : never run without asking
		MessageBox("Link", "This link leads to a file : " + as_url)
end choose

Éditer du Markdown : un codeeditor et un markdownview #

Le visualiseur garde sa position de lecture quand le texte change : on édite la fin d'un long document sans que l'aperçu remonte en haut.

// Local variables
string ls_notes

// The notes of the customer, in Markdown
ls_notes = "# Notes~n~n- [ ] Call back on Monday"

// The editor colours Markdown ; the viewer shows the page
uo_editor.is_syntax = u_pbt_codeeditor.SYNTAX_MARKDOWN
uo_editor.is_text = ls_notes
uo_md.is_markdown = ls_notes

// ue_changed of uo_editor : the whole recipe
uo_md.is_markdown = uo_editor.is_text

Une table des matières dans une liste #

Pour un fichier posé par is_source, remplissez la liste dans ue_loaded : avant, le fichier est encore en lecture.

// Local variables
string ls_titles[], ls_anchors[]
long ll_levels[], ll_i

// ue_loaded of uo_md : one line per heading, indented by its level
lb_toc.Reset()
for ll_i = 1 to uo_md.of_toc(/*titles*/ ls_titles, /*levels*/ ll_levels, /*anchors*/ ls_anchors)
	lb_toc.AddItem(Fill(" ", (ll_levels[ll_i] - 1) * 3) + ls_titles[ll_i])
next
// Local variables
string ls_titles[], ls_anchors[]
long ll_levels[]

// SelectionChanged of lb_toc : bring that heading to the top
uo_md.of_toc(/*titles*/ ls_titles, /*levels*/ ll_levels, /*anchors*/ ls_anchors)
uo_md.of_scroll_to(/*anchor*/ ls_anchors[index])

Une liste de contrôle que l'utilisateur coche #

// Local variables
string ls_text
long ll_at, ll_n

// The user may tick the boxes of the text
uo_md.ib_tasks_editable = true

// ue_task_toggled of uo_md : the start of line al_line of the text
ls_text = uo_md.is_markdown
ll_at = 1
for ll_n = 2 to al_line
	ll_at = Pos(ls_text, "~n", ll_at) + 1
next

// Its box, the first "[" of the line, becomes [x] or [ ]
ll_at = Pos(ls_text, "[", ll_at)
if ab_checked then
	ls_text = Replace(ls_text, ll_at, 3, "[x]")
else
	ls_text = Replace(ls_text, ll_at, 3, "[ ]")
end if

// The text set back : the view keeps its place
uo_md.is_markdown = ls_text

Le composant ne réécrit jamais le texte lui-même : l'application garde la main sur ce qu'elle enregistre.

Rouvrir un document là où le lecteur l'a laissé #

// Before closing the window : remember the place in the guide
SetProfileString("acme.ini", "help", "position", uo_md.is_position)

// When the guide is shown again : the place is taken once the file is on screen
uo_md.is_source = "C:\Acme\Help\guide.md"
uo_md.is_position = ProfileString("acme.ini", "help", "position", "")

Bonnes pratiques #


Hérité du socle commun #

Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.

MembresRôleDétaillé dans
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.1 Le moteur de propriétés
is_accessible_name · is_accessible_descriptionLe nom et la description que dit un lecteur d'écran3.4 Propriétés et events optionnels

← Référence des composants · Sommaire du guide