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.
// 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
Le texte Markdown à montrer. Le poser remplace le document (is_source se relit alors vide) ; vide efface la vue. Le HTML brut qu'il contient est affiché comme du texte, jamais exécuté. Se relit tel qu'il a été posé
is_source
string
""
Un fichier Markdown à montrer : un chemin du poste (.md, .markdown, .txt…), une adresse file:/// ou une URL https://. 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, REASON_TOO_LARGE. Le poser remplace le document (is_markdown se relit alors vide) ; ue_loaded ou ue_load_failed suit
ib_search_enabled
boolean
true
Ctrl+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_case
boolean
false
Option 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_word
boolean
false
Option 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_style
string
""
Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_mode
string
""
Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accent
long
-1
Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)
is_tooltip
string
""
Info-bulle simple affichée au survol du composant
is_super_tooltip_title
string
""
Titre de l'info-bulle enrichie (prend le pas sur is_tooltip)
is_super_tooltip_text
string
""
Texte de l'info-bulle enrichie (balisage riche accepté)
Vide 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é). Rend 0, -2 si le composant n'est pas créé
of_refresh ( ) → long
Relit is_source (sur le disque ou le réseau) : de quoi montrer un fichier réécrit au même chemin ; 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_search ( string as_query ) → long
Surligne 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 ou un lien. ue_search_result dit combien. Une requête vide est of_clear_search. 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 ( ) → long
Passe à 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 ( ) → long
Passe à 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_clear_search ( ) → long
Efface 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_match_count ( ) → long
Rend le nombre d'occurrences de la recherche courante, lu EN DIRECT — le 12 d'une barre d'état 3 / 12. 0 sans recherche
of_match_index ( ) → long
Rend 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_toc ( ref string as_titles[], ref long al_levels[], ref string as_anchors[] ) → long
La 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
of_scroll_to ( string as_anchor ) → long
Amène le titre as_anchor en haut de la vue : son ancre telle que of_toc la donne, avec ou sans #, ou son texte. Rend 0, -5 si aucun titre ne correspond, -2 si le composant n'est pas créé
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. 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
is_source 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). 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, la courante est al_index (1-basé, 0 si aucune) — de quoi afficher « 3 / 12 »
// ue_link_clicked of uo_md : the viewer never navigates, the application decides
if Lower(Right(as_url, 3)) = ".md" and FileExists(as_url) then
uo_md.is_source = as_url // another page of the help
else
ShellExecuteW(0, "open", as_url, "", "", 1) // a web page, a mail
end if
Éditer du Markdown : un codeeditor et un markdownview #
// 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
// Local variables
string ls_titles[], ls_anchors[]
long ll_levels[], ll_i
// One line per heading, indented by its level
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
// SelectionChanged of lb_toc : bring that heading to the top
uo_md.of_scroll_to(/*anchor*/ ls_anchors[index])
C'est un lecteur, pas un éditeur : pour écrire du Markdown, un codeeditor en SYNTAX_MARKDOWN à côté, relié par une ligne dans son ue_changed (voir l'exemple).
Les liens sont à vous : rien ne s'ouvre tout seul ; ue_link_clicked donne l'adresse, déjà résolue contre le dossier du fichier, et vous choisissez — le navigateur, un autre document dans le même composant, un écran de l'application.
Un document n'exécute rien : le HTML brut s'affiche tel qu'écrit, un lien javascript: reste du texte, une image http:// est refusée — un document venu d'ailleurs se montre sans risque.
Les images : un chemin relatif se lit contre le dossier du fichier ; pour une image du Web, préférez https://, ou téléchargez-la d'abord (restclient.of_download) et donnez son chemin.
Un gros document reste fluide : les premiers blocs s'affichent tout de suite, le reste dans les instants qui suivent ; la recherche, of_scroll_to et l'impression attendent qu'il soit entier.
De droite à gauche : le document suit le sens de l'application (listes, citations et tableaux se retournent), un bloc de code reste de gauche à droite.
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.