OVH Cloud OVH Cloud

Recréer un arbre à partir d'une liste.

22 réponses
Avatar
Julien Arlandis
Bonjour,

Je suis en train de coder un client de news entièrement en Javascript, celui se connecte à usenet via le protocole HTTP-NNTP que je suis en train de spécifier. Le prototype en cours de réalisation est accessible à cette adresse : http://http://news.julien-arlandis.fr/ (Accès en écriture seulement sur les groupes fr.test et nemo.test)
Le format d'échange de données entre le client et le serveur est le json.

Pour pouvoir gérer l'arborescence des messages en fonction des champs References, j'ai besoin d'un algorithme capable de transformer une liste d'articles contenant les articles référents (ici clé "ref"):

liste=[
{"id":"a", "ref":["d"]},
{"id":"b", "ref":["d","c"]},
{"id":"c", "ref":["d"]},
{"id":"d", "ref":[]},
{"id":"e", "ref":["d","c","f"]},
{"id":"f", "ref":["d","c"]},
{"id":"g", "ref":["d","c","f"]},
{"id":"h", "ref":["d"]},
{"id":"i", "ref":["d","a"]},
{"id":"j", "ref":[]},
{"id":"k", "ref":["j"]},
{"id":"l", "ref":["j","k"]},
]

en un objet json qui reflète la structure de l'arborescence des fichiers :

arbre={
"d":{
"a":{
"i":{}
},
"c":{
"f":{
"e":{},
"g":{}
},
"b":{}
},
"h":{}
},
"i":{
"j":{
"k":{}
}
}
}

Avez vous une idée sur la façon de procéder en javascript?
Autre question, en json si la clé d'un objet possède des caractères spéciaux comme le -, comment peut aux éléments de la structure?

Exemple : si j'ai toto = {"message-id":"xxx"}
Je ne pourrais pas faire toto.message-id (confusion avec l'opérateur de soustraction).

10 réponses

1 2 3
Avatar
Olivier Miakinen
Le 07/04/2013 16:39, Olivier Miakinen a écrit :

Je vais envoyer deux articles répondant à celui-ci, l'un contenant
le programme PHP complet (algo + tests) et l'autre le résultat des
tests.



<?php

function construis_arbo($liste)
{
$arbre = array("" => array());

while ($liste) {
foreach ($liste as $id => &$refs) {
// voyons un article non encore placé dans l'arbre
while ($refs) {
// on regarde la dernière référence de l'article
$ref = end($refs);
if (isset($arbre[$ref])) {
// l'article en référence est dans l'arbre :
// article placé
$arbre[$ref][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
continue 3; /* while ($liste) */
}
if (isset($liste[$ref])) {
// l'article en référence est encore à placer :
// voir un autre article, celui-ci sera traité
// plus tard.
continue 2; /* foreach ($liste) */
}
// l'article en référence n'existe pas : on le supprime
// de la liste des références
array_pop($refs);
}
// Cet article n'a pas (ou n'a plus) de références : on le
// place à la racine de l'arbre
$arbre[""][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
}

// S'il n'y a pas de références circulaires (a -> b -> a par
// exemple), $liste doit être vide. Sinon, on retire la dernière
// référence du premier article, qui existe forcément puisque
// tous les articles non traités le sont à cause d'une référence
// non résolue, et on repart pour un tour.
foreach ($liste as $id => &$refs) {
// Le fait d'utiliser foreach est une bidouille, en réalité
// on ne touche qu'au premier article avant de repartir au
// début.
array_pop($refs);
continue 2; /* while ($liste) */
}
}
return $arbre;
}

function affiche_liste($liste)
{
foreach ($liste as $id => $refs) {
printf("$id => [%s]n", implode(",", $refs));
}
}

function affiche_arbo($arbre, $refid, $indent)
{
foreach ($arbre[$refid] as $id) {
printf("%s%sn", $indent, $id);
affiche_arbo($arbre, $id, $indent . " ");
}
}

$liste = array(
"a" => array("d"),
"b" => array("d","c"),
"c" => array("d"),
"d" => array(),
"e" => array("d","c","f"),
"f" => array("d","c"),
"g" => array("d","c","f"),
"h" => array("d"),
"i" => array("d","a"),
"j" => array(),
"k" => array("j"),
"l" => array("j","k")
);

echo "==========================n";
echo "liste normalen";
affiche_liste($liste);
$arbre = construis_arbo($liste);
affiche_arbo($arbre, "", "");
echo "==========================n";
echo "liste tronquéen";
$lis = $liste; /* liste tronquée */
unset($lis["k"]);
unset($lis["d"]);
affiche_liste($lis);
$arbre = construis_arbo($lis);
affiche_arbo($arbre, "", "");
echo "==========================n";
echo "liste mélangéen";
$lesti = array(); /* liste mélangée */
$keys = array_keys($liste);
shuffle($keys);
foreach ($keys as $key) {
$lesti[$key] = $liste[$key];
}
affiche_liste($lesti);
$arbre = construis_arbo($lesti);
affiche_arbo($arbre, "", "");
echo "==========================n";
echo "liste inverséen";
$etsil = array_reverse($liste); /* liste inversée */
affiche_liste($etsil);
$arbre = construis_arbo($etsil);
affiche_arbo($arbre, "", "");
echo "==========================n";
echo "liste avec bouclen";
$lislislis = $liste;
$lislislis["xyz"] = array("yzx", "zxy");
$lislislis["yzx"] = array("zxy", "xyz");
$lislislis["zxy"] = array("xyz", "yzx");
affiche_liste($lislislis);
$arbre = construis_arbo($lislislis);
affiche_arbo($arbre, "", "");
echo "==========================n";
?>
Avatar
Olivier Miakinen
Le 07/04/2013 16:39, Olivier Miakinen a écrit :

Je vais envoyer deux articles répondant à celui-ci, l'un contenant
le programme PHP complet (algo + tests) et l'autre le résultat des
tests.



========================= liste normale
a => [d]
b => [d,c]
c => [d]
d => []
e => [d,c,f]
f => [d,c]
g => [d,c,f]
h => [d]
i => [d,a]
j => []
k => [j]
l => [j,k]
d
h
a
i
c
b
f
e
g
j
k
l
========================= liste tronquée
a => [d]
b => [d,c]
c => [d]
e => [d,c,f]
f => [d,c]
g => [d,c,f]
h => [d]
i => [d,a]
j => []
l => [j,k]
a
i
c
f
e
g
b
h
j
l
========================= liste mélangée
b => [d,c]
j => []
g => [d,c,f]
a => [d]
f => [d,c]
h => [d]
c => [d]
d => []
e => [d,c,f]
i => [d,a]
k => [j]
l => [j,k]
j
k
l
d
a
i
h
c
b
f
g
e
========================= liste inversée
l => [j,k]
k => [j]
j => []
i => [d,a]
h => [d]
g => [d,c,f]
f => [d,c]
e => [d,c,f]
d => []
c => [d]
b => [d,c]
a => [d]
j
k
l
d
c
f
g
e
b
h
a
i
========================= liste avec boucle
a => [d]
b => [d,c]
c => [d]
d => []
e => [d,c,f]
f => [d,c]
g => [d,c,f]
h => [d]
i => [d,a]
j => []
k => [j]
l => [j,k]
xyz => [yzx,zxy]
yzx => [zxy,xyz]
zxy => [xyz,yzx]
d
h
a
i
c
b
f
e
g
j
k
l
xyz
yzx
zxy
==========================
Avatar
Julien Arlandis
Le 07/04/13 16:39, Olivier Miakinen a écrit :
Le 07/04/2013 02:42, Julien Arlandis a écrit :

En partant des données json de base, j'ai rapidement écrit un algo pour [...]





Merci pour ce travail remarquable.


Tes lignes sont toujours trop longues. Tant que tu n'as pas résolu le
problème du wordwrap, tu ne voudrais pas insérer des sauts de ligne
à la main ?



J'ai retiré le wordwrap car ça créait plus de problèmes qu'autre chose,
d'autant plus que sur thunderbird le retour à la ligne est automatique à
la lecture, sauf pour les citations mais dans ce cas les retours
chariots peuvent être replacés manuellement.
Mon problème, c'est qu'à chaque foi que l'article est cité de nouveaux
retours chariots sont créés et à la fin l'article devient illisible.
Pour résoudre ce problème je suppose qu'il ne faudrait jamais appliquer
le wordwrap sur les lignes qui commencent par un chevron?

Un autre problème lié à la citation, c'est que ça coupe le contenu des
balises contenant du code à interpréter (BBcode, latex ou autre).
Donc si les lignes trop longues reviennent à la ligne automatiquement à
la lecture et si la personne qui répond peut elle rajouter les retours
lignes là où ça l'arrange, quel est le problème ? De plus, en HTML la
longueur de la ligne est automatique car elle dépend de la taille de la
fenêtre du navigateur qui dépend de la taille de l'écran. Bref pas
facile de faire un compromis.

Ton exemple avec javascript et json ne me suffit pas pour savoir comment
écrire le programme, alors je le fais en PHP.

Expurgée de ses lignes de commentaires, la fonction qui construit
l'arborescence est étonnamment courte bien qu'elle traite tous les
cas, même pathologiques (boucles de références) :

=============================================================== > function construis_arbo($liste)
{
$arbre = array("" => array());

while ($liste) {
foreach ($liste as $id => &$refs) {
while ($refs) {
$ref = end($refs);
if (isset($arbre[$ref])) {
$arbre[$ref][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
continue 3; /* while ($liste) */
}
if (isset($liste[$ref])) {
continue 2; /* foreach ($liste) */
}
array_pop($refs);
}
$arbre[""][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
}
foreach ($liste as $id => &$refs) {
array_pop($refs);
continue 2; /* while ($liste) */
}
}

return $arbre;
}
===============================================================


Joli, je vais de ce pas coder ça en Javascript, je te tiens au courant.

Je vais envoyer deux articles répondant à celui-ci, l'un contenant
le programme PHP complet (algo + tests) et l'autre le résultat des
tests.

Avatar
Olivier Miakinen
Le 07/04/2013 17:49, Julien Arlandis a écrit :

Tes lignes sont toujours trop longues. Tant que tu n'as pas résolu le
problème du wordwrap, tu ne voudrais pas insérer des sauts de ligne
à la main ?



J'ai retiré le wordwrap car ça créait plus de problèmes qu'autre chose,



Ça ne pourra fonctionner correctement que quand tu l'implémenteras
dans l'éditeur et non pas après coup. Au fait, est-ce seulement
possible ? Qu'est-ce que tu utilises pour la rédaction du contenu
des articles ?

d'autant plus que sur thunderbird le retour à la ligne est automatique à
la lecture, sauf pour les citations mais dans ce cas les retours
chariots peuvent être replacés manuellement.



Certes, mais c'est vachement pénible. Moi qui ne plonke que rarement,
j'ai plonké pendant plusieurs mois un contributeur pourtant intéressant
sur fciwa et quelques autres groupes pour cette seule raison. À chaque
fois que je tentais de lui répondre je me retrouvais avec des lignes de
3 km à redécouper, et je n'avais vraiment pas envie de perdre mon temps
à ça.

Mon problème, c'est qu'à chaque fois que l'article est cité de nouveaux
retours chariots sont créés et à la fin l'article devient illisible.



Comme je le disais, il ne faut pas reproduire ce bug d'Outlook Express !

Pour résoudre ce problème je suppose qu'il ne faudrait jamais appliquer
le wordwrap sur les lignes qui commencent par un chevron?



Tout simplement, oui.

Un autre problème lié à la citation, c'est que ça coupe le contenu des
balises contenant du code à interpréter (BBcode, latex ou autre).



Ah oui, j'ai vu sur fr.test que tu faisais des tests avec latex. Mais
quitte à envoyer autre chose que du text/plain, pourquoi ne pas passer
à HTML ? Ce ne serait pas plus approprié ? Certes, ça ne passera pas
sur la hiérarchie fr.*, mais le BBcode et le latex non plus ne sont pas
les bienvenus, et je suppose donc que tu créeras une autre hiérarchie
où ils sont autorisés, non ?... (Rassure-moi !)

Donc si les lignes trop longues reviennent à la ligne automatiquement à
la lecture et si la personne qui répond peut elle rajouter les retours
lignes là où ça l'arrange, quel est le problème ?



Pour le destinataire : ce n'est pas à lui de passer du temps à
reformater l'article qu'il reçoit avant d'y répondre. C'est très
pénible.

Pour l'émetteur soucieux de bonne typographie : il insèrera de toute
façon des sauts de ligne, ne serait-ce que pour que la coupure ne
se fasse pas avant un « : » ou au milieu de « 20 h 30 ». S'il les
insère un tout petit peu trop loin par rapport à l'affichage de ceux
qui vont le lire, par exemple au bout de 90 caractères au lieu de
80, cela reproduira à l'affichage le bug d'Outlook Express : une
alternance de lignes longues et de lignes courtes.

De plus, en HTML la
longueur de la ligne est automatique car elle dépend de la taille de la
fenêtre du navigateur qui dépend de la taille de l'écran. Bref pas
facile de faire un compromis.



Ça, ce sera le rôle de l'infâme format flowed le jour où tu décideras
de le proposer. Je parle des lecteurs, bien sûr. Pour le rédacteur, il
faut que la coupure se fasse à la bonne longueur au moment où il rédige.
Et donc je repose ma question : est-ce possible et vois-tu comment le
faire ?

Ton exemple avec javascript et json ne me suffit pas pour savoir comment
écrire le programme, alors je le fais en PHP.

[...]





J'ai trouvé comment traiter le cas où c'est le premier article qui
manque. Je n'ai pas encore testé, mais il suffit de rajouter une
dizaine de lignes dans mon code, sans rien changer d'autre. Dès
que j'ai le temps, je les écris ici (à moins que tu ne préfères
attendre que j'aie testé d'abord, et alors ce ne sera pas avant
cette nuit).

Cordialement,
--
Olivier Miakinen
Avatar
Julien Arlandis
Le 08/04/13 12:19, Olivier Miakinen a écrit :
Le 07/04/2013 17:49, Julien Arlandis a écrit :

Tes lignes sont toujours trop longues. Tant que tu n'as pas résolu le
problème du wordwrap, tu ne voudrais pas insérer des sauts de ligne
à la main ?



J'ai retiré le wordwrap car ça créait plus de problèmes qu'autre chose,



Ça ne pourra fonctionner correctement que quand tu l'implémenteras
dans l'éditeur et non pas après coup. Au fait, est-ce seulement
possible ? Qu'est-ce que tu utilises pour la rédaction du contenu
des articles ?



Un simple textarea, j'ai vérifié que google groups ne l'implémente pas
non plus, y a t-il seulement un webmail qui le propose? Comment le
problème est il contourné dans ce cas ?

d'autant plus que sur thunderbird le retour à la ligne est automatique à
la lecture, sauf pour les citations mais dans ce cas les retours
chariots peuvent être replacés manuellement.



Certes, mais c'est vachement pénible. Moi qui ne plonke que rarement,
j'ai plonké pendant plusieurs mois un contributeur pourtant intéressant
sur fciwa et quelques autres groupes pour cette seule raison. À chaque
fois que je tentais de lui répondre je me retrouvais avec des lignes de
3 km à redécouper, et je n'avais vraiment pas envie de perdre mon temps
à ça.



En fait je ne comprends toujours pas l'intérêt de couper une phrase en
insérant un retour chariot en plein milieu alors même que l'affichage
est parfaitement géré par le client sans cet artifice. Encore que si les
retours chariots automatiques étaient différents des retours chariots
manuels je pourrais décider de les ignorer côté HTML, mais dans l'état
actuel je suis obligé pour formater mon texte de remplacer tous les n
par des <br>.
Pour faciliter le travail de celui qui va répondre on dénature la
syntaxe même de la phrase, laquelle n'exige un retour à la ligne qu'à la
fin de celle ci, et pas là où on devine que le lecteur l'attend.

Pourtant il existe une solution, regarde ce message :
http://news.julien-arlandis.fr/?

Le message est à la fois lisible et tu peux y répondre sans soucis car
par défaut le texte d'un textarea ne déborde pas mais ne rajoute pas de
retours chariots pour autant. Le problème ne se pose donc pas. Pourquoi
ne pas avoir implémenté ce mécanisme dans les lecteurs de news tout
simplement ?


Mon problème, c'est qu'à chaque fois que l'article est cité de nouveaux
retours chariots sont créés et à la fin l'article devient illisible.



Comme je le disais, il ne faut pas reproduire ce bug d'Outlook Express !

Pour résoudre ce problème je suppose qu'il ne faudrait jamais appliquer
le wordwrap sur les lignes qui commencent par un chevron?



Tout simplement, oui.

Un autre problème lié à la citation, c'est que ça coupe le contenu des
balises contenant du code à interpréter (BBcode, latex ou autre).



Ah oui, j'ai vu sur fr.test que tu faisais des tests avec latex. Mais
quitte à envoyer autre chose que du text/plain, pourquoi ne pas passer
à HTML ? Ce ne serait pas plus approprié ? Certes, ça ne passera pas
sur la hiérarchie fr.*, mais le BBcode et le latex non plus ne sont pas
les bienvenus, et je suppose donc que tu créeras une autre hiérarchie
où ils sont autorisés, non ?... (Rassure-moi !)



Y aura une autre hiérarchie 100% compatible JNTP, ce n'est pas tout car
toutes les évolutions du protocole ne seront pas compatibles avec NNTP,
pour assurer l'intéropérabilité des deux protocoles elles ne seront pas
activées pour l'usage des hiérarchies communes. Néanmoins, je compte
développer une nouvelle hiérarchie Nemo qui appliquera le protocole JNTP
à 100%, elle ne pourra donc pas être relayée sur NNTP pour des raisons
de sécurité, car j'ai prévu que le nouvel identifiant (le JID) soit un
hash de l'ensemle des entêtes obligatoires et non modifiables de
l'article. Tout article dont le hash n'est pas valide sera
automatiquement éjecté et par le client et par le serveur. J'ai
également prévu un champ pour signer numériquement l'article, l'idée est
simple : chaque utilisateur génère une phrase secrète qu'il stocke dans
son client. Lors de la rédaction d'un article, il réalise avant
d'expédier l'article les opérations suivantes :

MyHash = SHA1(From + Subject + Body + Newsgroups + SHA1(From + Subject
+ Body + Newsgroups + phrase_secrete))

Dans l'article il rajoute l'entête :
Signature: MyHash

Pour prouver son identité lors de la suppression ou de la modification
de son message, l'auteur devra fournir la clé
SHA1(From + Subject + Body + Newsgroups + phrase_secrete)

Si le hash de cette clé concaténée au message est identique à MyHash
c'est qu'il est l'auteur de l'article.

Chose nouvelle également, le JID sera de cette forme
SHA1(enêtes+body)@domaine_du_serveur_de_news_emetteur

Les serveurs devront avoir un certificat numérique valable et devront
signer tous les articles émis par leurs abonnés. Toutes ces règles ne
seront pas optionnelles, elles devront être appliquées.

Donc si les lignes trop longues reviennent à la ligne automatiquement à
la lecture et si la personne qui répond peut elle rajouter les retours
lignes là où ça l'arrange, quel est le problème ?



Pour le destinataire : ce n'est pas à lui de passer du temps à
reformater l'article qu'il reçoit avant d'y répondre. C'est très
pénible.

Pour l'émetteur soucieux de bonne typographie : il insèrera de toute
façon des sauts de ligne, ne serait-ce que pour que la coupure ne
se fasse pas avant un « : » ou au milieu de « 20 h 30 ». S'il les
insère un tout petit peu trop loin par rapport à l'affichage de ceux
qui vont le lire, par exemple au bout de 90 caractères au lieu de
80, cela reproduira à l'affichage le bug d'Outlook Express : une
alternance de lignes longues et de lignes courtes.



Su un navigateur, la typographie se gère à l'affichage et pas à la
rédaction, c'est ce qui assure la compatibilité de lecture sur
différents médias.


De plus, en HTML la
longueur de la ligne est automatique car elle dépend de la taille de la
fenêtre du navigateur qui dépend de la taille de l'écran. Bref pas
facile de faire un compromis.



Ça, ce sera le rôle de l'infâme format flowed le jour où tu décideras
de le proposer. Je parle des lecteurs, bien sûr. Pour le rédacteur, il
faut que la coupure se fasse à la bonne longueur au moment où il rédige.
Et donc je repose ma question : est-ce possible et vois-tu comment le
faire ?



Je ne comprends toujours pas ce qu'est ce format=flowed, que fait il
exactement, à quoi sert il, à qui est il destiné?

Ton exemple avec javascript et json ne me suffit pas pour savoir comment
écrire le programme, alors je le fais en PHP.

[...]





J'ai trouvé comment traiter le cas où c'est le premier article qui
manque. Je n'ai pas encore testé, mais il suffit de rajouter une
dizaine de lignes dans mon code, sans rien changer d'autre. Dès
que j'ai le temps, je les écris ici (à moins que tu ne préfères
attendre que j'aie testé d'abord, et alors ce ne sera pas avant
cette nuit).



Pas de soucis, je n'ai pas encore eu le temps d'implémenter ton algo en
javascript, mais les choses avancent ...

Crosspost sur fr.comp.securite et retour sur fr.comp.lang.javascript
Avatar
Julien Arlandis
Le 08/04/13 12:19, Olivier Miakinen a écrit :

Ah oui, j'ai vu sur fr.test que tu faisais des tests avec latex. Mais
quitte à envoyer autre chose que du text/plain, pourquoi ne pas passer
à HTML ?



On ne peut pas permettre à un utilisateur d'injecter du HTML, c'est la
porte ouverte aux failles XSS. Il faut nécessairement passer par un
langage de balisage léger dont on contrôle la transition vers HTML.


Ça, ce sera le rôle de l'infâme format flowed le jour où tu décideras
de le proposer. Je parle des lecteurs, bien sûr. Pour le rédacteur, il
faut que la coupure se fasse à la bonne longueur au moment où il rédige.
Et donc je repose ma question : est-ce possible et vois-tu comment le
faire ?



Non je n'ai pas trouvé, mais ce dont je suis pratiquement certain c'est
que le wordwrap n'est pas adapté au HTML. Le problème ne se pose pas
entre navigateurs mais entre navigateur et client de news. M'est avis
que la solution doit aussi s'adapter...
Avatar
Julien Arlandis
Le 08/04/13 19:21, Julien Arlandis a écrit :
Le 08/04/13 12:19, Olivier Miakinen a écrit :

Ah oui, j'ai vu sur fr.test que tu faisais des tests avec latex. Mais
quitte à envoyer autre chose que du text/plain, pourquoi ne pas passer
à HTML ?



On ne peut pas permettre à un utilisateur d'injecter du HTML, c'est la
porte ouverte aux failles XSS. Il faut nécessairement passer par un
langage de balisage léger dont on contrôle la transition vers HTML.


Ça, ce sera le rôle de l'infâme format flowed le jour où tu décideras
de le proposer. Je parle des lecteurs, bien sûr. Pour le rédacteur, il
faut que la coupure se fasse à la bonne longueur au moment où il rédige.
Et donc je repose ma question : est-ce possible et vois-tu comment le
faire ?



Non je n'ai pas trouvé, mais ce dont je suis pratiquement certain c'est
que le wordwrap n'est pas adapté au HTML. Le problème ne se pose pas
entre navigateurs mais entre navigateur et client de news. M'est avis
que la solution doit aussi s'adapter...



Que le client de news doit aussi s'adapter, pardon.
Avatar
SAM
Le 08/04/13 18:56, Julien Arlandis a écrit :
Pourtant il existe une solution, regarde ce message :
http://news.julien-arlandis.fr/?



Joli.

Le message est à la fois lisible



Ha! Non! J'y comprends rien à ce message !
C'est en quelle langue ?



Je sais pas trop à quoi sert ce Nemo ?

Et qui donne des messages le lendemain de leur envoi (et en anglishe,
les dates des NG fr)


Cordialement,
--
Stéphane Moriaux avec/with iMac-intel 27" & Mac OS X 10.6.8
Avatar
Olivier Miakinen
Salut !

On est de plus en plus HS sur fclj. À défaut d'une meilleure idée, je
fais suivre vers fr.comp.usenet.serveurs

Le 08/04/2013 18:56, Julien Arlandis a écrit :

Ça ne pourra fonctionner correctement que quand tu l'implémenteras
dans l'éditeur et non pas après coup. Au fait, est-ce seulement
possible ? Qu'est-ce que tu utilises pour la rédaction du contenu
des articles ?



Un simple textarea, j'ai vérifié que google groups ne l'implémente pas
non plus,



C'est l'une des tares rédhibitoires de Google groupes en tant que
nouvelleur. Certes, ce n'est pas la seule.

y a t-il seulement un webmail qui le propose?



D'habitude je fuis les webmails, mais je viens d'essayer celui de
GalacSys. Il propose par configuration de choisir la taille de la
zone de saisie (nombre de lignes et nombre de colonnes, par défaut
24 lignes de 78 colonnes), et il fait le wordwrap en conséquence.
Si j'insère des sauts de ligne, il en tient compte. Il semble donc
que celui-ci le propose.

En fait je ne comprends toujours pas l'intérêt de couper une phrase en
insérant un retour chariot en plein milieu alors même que l'affichage
est parfaitement géré par le client sans cet artifice.



Parfaitement géré ? Permets-moi de ne pas être d'accord
! Je te donne ici deux exemples de ce que je disais à 12
h 19 dans mon article précédent.

Tu pourras me répondre que dans ce cas l'émetteur devrait mettre
des espaces insécables au lieu des espaces simples, ce à quoi je te
rétorquerai d'essayer avec Internet Explorer ou Firefox : à moins
que ça n'ait été corrigé depuis la dernière fois que j'ai essayé,
c'est impossible.

Encore que si les
retours chariots automatiques étaient différents des retours chariots
manuels je pourrais décider de les ignorer côté HTML,



Mais non, il ne s'agit pas de les ignorer, bien au contraire ! S'il y
a un saut de ligne fait automatiquement lors de la composition, et
si l'auteur est content avec ça (il n'en insère pas un autre avant),
alors c'est qu'il faut l'officialiser au moment de l'envoi. Finalement,
ça ne doit pas être si difficile que ça...

Pour faciliter le travail de celui qui va répondre on dénature la
syntaxe même de la phrase, laquelle n'exige un retour à la ligne qu'à la
fin de celle ci, et pas là où on devine que le lecteur l'attend.



Pour ne *pas* dénaturer le texte écrit par l'auteur, il faut et il
suffit que ce qui est envoyé corresponde exactement à ce que l'auteur
voyait au moment de cliquer sur le bouton d'envoi.

Pourtant il existe une solution, regarde ce message :
http://news.julien-arlandis.fr/?



Je ne vois rien, les deux grandes zones sont vides.

Y aura une autre hiérarchie 100% compatible JNTP, ce n'est pas tout car
toutes les évolutions du protocole ne seront pas compatibles avec NNTP,
pour assurer l'intéropérabilité des deux protocoles elles ne seront pas
activées pour l'usage des hiérarchies communes. Néanmoins, je compte
développer une nouvelle hiérarchie Nemo qui appliquera le protocole JNTP
à 100%, elle ne pourra donc pas être relayée sur NNTP pour des raisons
de sécurité, car j'ai prévu que le nouvel identifiant (le JID) soit un
hash de l'ensemle des entêtes obligatoires et non modifiables de
l'article. Tout article dont le hash n'est pas valide sera
automatiquement éjecté et par le client et par le serveur. J'ai
également prévu un champ pour signer numériquement l'article, l'idée est
simple : chaque utilisateur génère une phrase secrète qu'il stocke dans
son client. Lors de la rédaction d'un article, il réalise avant
d'expédier l'article les opérations suivantes :

MyHash = SHA1(From + Subject + Body + Newsgroups + SHA1(From + Subject
+ Body + Newsgroups + phrase_secrete))



Ça me semble compliqué, et source d'erreurs dans les implémentations
concurrentes de la tienne (qui, je le rappelle, doivent exister si
tu comptes standardiser ton protocole). Par exemple, la suppression
des lignes vides à la fin du Body, ou un folding en plus ou en moins
dans le champ Subject, détruiraient ton hash.

Pourquoi pas tout simplement :
MyHash = SHA1(Message-ID + SHA1(Message-ID + phrase_secrete))
?

Pour prouver son identité lors de la suppression ou de la modification
de son message, l'auteur devra fournir la clé
SHA1(From + Subject + Body + Newsgroups + phrase_secrete)

Si le hash de cette clé concaténée au message est identique à MyHash
c'est qu'il est l'auteur de l'article.



Étant entendu que la « modification » est aussi une suppression de
l'article d'origine, ça devrait fonctionner. Parce que sinon, dès
qu'un auteur aurait fait une modification, n'importe qui aurait pu
venir remodifier l'article d'origine avec la même clé.

Chose nouvelle également, le JID sera de cette forme
SHA1(enêtes+body)@domaine_du_serveur_de_news_emetteur



Entre les entêtes qui peuvent changer et l'obligation d'unicité, je
soupçonne qu'il risque d'y avoir des problèmes, sans en être sûr.
Il faudra soigneusement vérifier tout ça.

Les serveurs devront avoir un certificat numérique valable et devront
signer tous les articles émis par leurs abonnés. Toutes ces règles ne
seront pas optionnelles, elles devront être appliquées.



Ça apportera quoi exactement, que n'apporte pas déjà le champ Path ?

Pour l'émetteur soucieux de bonne typographie : il insèrera de toute
façon des sauts de ligne, ne serait-ce que pour que la coupure ne
se fasse pas avant un « : » ou au milieu de « 20 h 30 ». S'il les
insère un tout petit peu trop loin par rapport à l'affichage de ceux
qui vont le lire, par exemple au bout de 90 caractères au lieu de
80, cela reproduira à l'affichage le bug d'Outlook Express : une
alternance de lignes longues et de lignes courtes.



Su un navigateur, la typographie se gère à l'affichage et pas à la
rédaction, c'est ce qui assure la compatibilité de lecture sur
différents médias.



Une page web est faite pour être affichée de plein de façons
différentes selon les préférences du lecteur, c'est pour ça que
l'auteur de cette page se doit d'utiliser des &nbsp; partout où
c'est nécessaire.

Un article de news est fait pour être affiché en texte, avec au
maximum 78 caractères par ligne, et de préférence dans une police
à espacement fixe. C'est sous ces conditions que l'on peut faire
un schéma en art-ascii, puisqu'on ne peut pas insérer une image.

Je ne comprends toujours pas ce qu'est ce format=flowed, que fait il
exactement, à quoi sert il, à qui est il destiné?



Ce n'est pas moi qui en ferai la pub. Il y a un RFC qui le décrit,
si ça t'intéresse d'en savoir plus.

J'ai trouvé comment traiter le cas où c'est le premier article qui
manque. Je n'ai pas encore testé, mais il suffit de rajouter une
dizaine de lignes dans mon code, sans rien changer d'autre. Dès
que j'ai le temps, je les écris ici (à moins que tu ne préfères
attendre que j'aie testé d'abord, et alors ce ne sera pas avant
cette nuit).



Pas de soucis, je n'ai pas encore eu le temps d'implémenter ton algo en
javascript, mais les choses avancent ...



Finalement ça vaut mieux, puisque j'avais oublié une ligne dans le code
d'origine. Voici la fonction modifiée.

function construis_arbo($liste)
{
$arbre = array("" => array());
$substitut = array();

while ($liste) {
foreach ($liste as $id => &$refs) {
// voyons un article non encore placé dans l'arbre
while ($refs) {
// on regarde la dernière référence de l'article
$ref = end($refs);
if (isset($arbre[$ref])) {
// l'article en référence est dans l'arbre :
// on peut placer le nouvel article.
$arbre[$ref][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
continue 3; /* while ($liste) */
}
if (isset($substitut[$ref])) {
// l'article en référence n'est dans l'arbre car
// il n'était pas dans la liste, mais un autre
// article le remplace : on peut donc placer le
// nouvel article aussi.
$arbre[$substitut[$ref]][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
continue 3; /* while ($liste) */
}
if (isset($liste[$ref])) {
// l'article en référence est encore à placer :
// voir un autre article, celui-ci sera traité
// plus tard.
continue 2; /* foreach ($liste) */
}
// l'article en référence n'existe pas : on le
// supprime de la liste des références.
array_pop($refs);
// si le premier article d'un fil de discussion
// n'existe pas, on lui choisit un substitut.
if (! $refs) {
$substitut[$ref] = $id;
}
}
// Cet article n'a pas (ou n'a plus) de références : on le
// place à la racine de l'arbre
$arbre[""][] = $id;
$arbre[$id] = array();
unset($liste[$id]);
continue 2; /* while ($liste) */
}

// S'il n'y a pas de références circulaires (a -> b -> a par
// exemple), $liste doit être vide. Sinon, on retire la dernière
// référence du premier article, qui existe forcément puisque
// tous les articles non traités le sont à cause d'une référence
// non résolue, et on repart pour un tour.
foreach ($liste as $id => &$refs) {
// Le fait d'utiliser foreach est une bidouille, en réalité
// on ne touche qu'au premier article avant de repartir au
// début.
array_pop($refs);
continue 2; /* while ($liste) */
}
}

return $arbre;
}
Avatar
Olivier Miakinen
Le 08/04/2013 19:21, Julien Arlandis a écrit :

Ah oui, j'ai vu sur fr.test que tu faisais des tests avec latex. Mais
quitte à envoyer autre chose que du text/plain, pourquoi ne pas passer
à HTML ?



On ne peut pas permettre à un utilisateur d'injecter du HTML, c'est la
porte ouverte aux failles XSS. Il faut nécessairement passer par un
langage de balisage léger dont on contrôle la transition vers HTML.



Alors tu vas devoir définir de nouveaux types MIME :
<http://fr.wikipedia.org/wiki/Type_MIME>
<http://www.iana.org/assignments/media-types/text>

Probablement text/latex et text/bbcode ?
1 2 3