Export topic as markdown

I found this UI: Topic and Category Export/Import but that does not cover what I was thinking about:

  • A means to export an entire public or DM topic as a single markdown document where the export action is UI-accessible to all the participants in said topic.

And maybe (but for me not required) to have this feature available for anyone on public topics.


I interact with many Discourse forums publicly and DM’ingly and have a need to archive discussions there in a personal markdown-based knowledge base. This is not only very time-consuming, but I can’t get the raw markdown of other people’s posts in forums where I’m not mod or admin (logically), so I have to recreate it manually.

7 « J'aime »

You can already access the raw markdown to topics:
Https://meta.discourse.org/raw/152185

2 « J'aime »

Thanks, that would be so cool. But it only returns the first post in the topic and not the entire conversation thread.

Edit: More doable, by iterating over each post in the thread in raw mode, but for a thread with 60 posts still a lot of work. Furthermore it contains only the body of the post and there is no information on who posted, and when.

You can use the print function on a topic and save the output to a pdf. It is not markdown but it is easy!

1 « J'aime »

Thank you, yes, I sometimes use that, but the content becomes ‘locked in’. It does not fit well with my knowledge base (create cross-links, etc.). Markdown is so simple and easy to work with, that I select all my tools around it. It is a great timesaver if you can just move MD snippets around all over the place.

2 « J'aime »

I was just asked that question yesterday. Are you referring to the print function of the browser? Or is there a Discourse feature to print the entire topic thread that I am not seeing?

https://meta.discourse.org/t/print-long-topic-to-pdf-redux-again/44639/37?u=falco

2 « J'aime »

Funny, I too would like something like this! So just another vote of support, I guess…

Bonjour,

Je viens de créer un compte ici pour dire que je pense aussi que ce type de fonctionnalité est très important !

L’impression (en PDF) ne fonctionne pas bien avec les fils de discussion qui contiennent des blocs de code, car ils ne s’enroulent pas ou ne s’étendent pas, ce qui fait que les choses sont coupées.

Je pense qu’un moyen fiable et assez facile d’extraire du contenu de Discourse, par exemple à des fins d’archivage, est vraiment important.

Un autre point à considérer : je participe à un forum qui vient de regrouper de nombreux utilisateurs d’une liste de diffusion qui a fermé. Lors des discussions de transition pour savoir s’il fallait maintenir la liste de diffusion active ou passer entièrement au forum, un membre aveugle a déclaré qu’il ne pourrait pas participer au forum en raison du manque de support pour les navigateurs textuels. Je pense qu’un mode brut approprié, avec attribution de l’auteur et tous les fils de discussion, contribuerait à une plus grande inclusion.

2 « J'aime »

Voyons voir. Je vais inclure un bloc de code ici avec pas mal de code et voir à quoi il ressemble à l’impression :

import java.util.Scanner;

/**
 * Jeu d'AceyDucey
 * 
 * Basé sur le jeu de base d'AceyDucey ici
 * https://github.com/coding-horror/basic-computer-games/blob/main/01%20Acey%20Ducey/aceyducey.bas
 * Remarque : L'idée était de créer une version du jeu Basic des années 1970 en Java, sans introduire
 * de nouvelles fonctionnalités - aucun texte supplémentaire, aucune vérification d'erreurs, etc. n'a été ajouté.
 */
public class AceyDucey {

    // Montant actuel de l'argent du joueur
    private int playerAmount;

    // Première carte tirée par le croupier
    private Card firstCard;

    // Deuxième carte tirée par le croupier
    private Card secondCard;

    // Carte tirée par le joueur
    private Card playersCard;

    // Utilisé pour afficher l'introduction/les instructions du jeu
    private boolean firstTimePlaying = true;

    // État du jeu pour déterminer si le jeu est terminé
    private boolean gameOver = false;

    // Utilisé pour l'entrée au clavier
    private final Scanner kbScanner;

    // Valeur constante pour les cartes d'un jeu - 2 le plus bas, 14 (As) le plus haut
    public static final int LOW_CARD_RANGE = 2;
    public static final int HIGH_CARD_RANGE = 14;

    public AceyDucey() {
        // Initialiser l'argent du joueur
        playerAmount = 100;

        // Initialiser le scanner du clavier
        kbScanner = new Scanner(System.in);
    }

    // Méthode pour rejouer - méthode publique appelée par la classe qui lance le jeu
    // Si le joueur entre OUI, le jeu peut être rejoué (retourne vrai)
    // sinon non (retourne faux)
    public boolean playAgain() {
        System.out.println();
        System.out.println("DÉSOLÉ, AMI, MAIS VOUS AVEZ ÉTÉ DÉPOUILLÉ.");
        System.out.println();
        System.out.println();
        System.out.print("ESSAYEZ ENCORE (OUI OU NON) ");
        String playAgain = kbScanner.next().toUpperCase();
        System.out.println();
        System.out.println();
        if (playAgain.equals("OUI")) {
            return true;
        } else {
            System.out.println("OK, J'ESPÈRE QUE VOUS VOUS ÊTES AMUSÉ !");
            return false;
        }
    }

    // Méthode de boucle de jeu

    public void play() {

        // Continuer à jouer des mains jusqu'à ce que le joueur n'ait plus d'argent
        do {
            if (firstTimePlaying) {
                intro();
                firstTimePlaying = false;
            }
            displayBalance();
            drawCards();
            displayCards();
            int betAmount = getBet();
            playersCard = randomCard();
            displayPlayerCard();
            if (playerWon()) {
                System.out.println("VOUS GAGNEZ !!");
                playerAmount += betAmount;
            } else {
                System.out.println("DÉSOLÉ, VOUS PERDEZ");
                playerAmount -= betAmount;
                // Le joueur a-t-il manqué d'argent ?
                if (playerAmount <= 0) {
                    gameOver = true;
                }
            }

        } while (!gameOver); // Continuer à jouer jusqu'à ce que le joueur manque d'argent
    }

    // Méthode pour déterminer si le joueur a gagné (retourne vrai) ou perdu (retourne faux)
    // pour gagner, la carte du joueur doit être dans la plage de la première et de la deuxième carte du croupier
    // tirées, y compris les première et deuxième cartes.
    private boolean playerWon() {
        // gagnant
        return (playersCard.getValue() >= firstCard.getValue())
                && playersCard.getValue() <= secondCard.getValue();

    }

    private void displayPlayerCard() {
        System.out.println(playersCard.getName());
    }

    // Obtenir la mise du joueur et retourner le montant
    // 0 est considéré comme une mise valide, mais mieux vaut plus que ce que le joueur a disponible n'est pas
    // la méthode bouclera jusqu'à ce qu'une mise valide soit saisie.
    private int getBet() {
        boolean validBet = false;
        int amount;
        do {
            System.out.print("QUELLE EST VOTRE MISE ");
            amount = kbScanner.nextInt();
            if (amount == 0) {
                System.out.println("POULE !");
                validBet = true;
            } else if (amount > playerAmount) {
                System.out.println("DÉSOLÉ, MON AMI, MAIS VOUS AVEZ MISÉ TROP.");
                System.out.println("VOUS N'AVEZ QUE " + playerAmount + " DOLLARS À MISER.");
            } else {
                validBet = true;
            }
        } while (!validBet);

        return amount;
    }

    private void displayBalance() {
        System.out.println("VOUS AVEZ MAINTENANT " + playerAmount + " DOLLARS.");
    }

    private void displayCards() {
        System.out.println("VOICI VOS DEUX PROCHAINES CARTES : ");
        System.out.println(firstCard.getName());
        System.out.println(secondCard.getName());
    }

    // Tirer deux cartes de croupier et les sauvegarder pour une utilisation ultérieure.
    // s'assurer que la première carte a une valeur inférieure à la seconde
    private void drawCards() {

        do {
            firstCard = randomCard();
            secondCard = randomCard();
        } while (firstCard.getValue() >= secondCard.getValue());
    }

    // Crée une carte aléatoire
    private Card randomCard() {
        return new Card((int) (Math.random()
                * (HIGH_CARD_RANGE - LOW_CARD_RANGE + 1) + LOW_CARD_RANGE));
    }

    public void intro() {
        System.out.println("JEU DE CARTES ACEY DUCEY");
        System.out.println("CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY");
        System.out.println();
        System.out.println();
        System.out.println("ACEY-DUCEY SE JOUE DE LA MANIÈRE SUIVANTE");
        System.out.println("LE CROUPIER (ORDINATEUR) DISTRIBUE DEUX CARTES FACE VERS LE HAUT");
        System.out.println("VOUS AVEZ LA POSSIBILITÉ DE MISER OU DE NE PAS MISER SELON");
        System.out.println("QUE VOUS ESTIMIEZ OU NON QUE LA CARTE AURA");
        System.out.println("UNE VALEUR ENTRE LES DEUX PREMIÈRES.");
        System.out.println("SI VOUS NE VOULEZ PAS MISER, ENTREZ : 0");
    }
}

Notez que nous avons une prise en charge assez complète de l’accessibilité, je serais donc intéressé d’entendre spécifiquement ce qui ne fonctionne pas pour votre utilisateur aveugle @thresholdpeople .

De plus, le bloc de code ci-dessus me semble correct dans la version imprimée. J’ai simplement appuyé sur « imprimer » dans Chrome, puis sur « enregistrer sous PDF » pour générer une version PDF de ce sujet :

Exporter le sujet en markdown - fonctionnalité - Discourse Meta.pdf (249,9 Ko)

Je ne vois pas de problème. Veuillez indiquer les zones spécifiques du PDF qui ne sont pas correctes si vous en voyez un. Merci !

Merci de vous pencher sur la question.

J’utilise Vivaldi, mais j’ai aussi utilisé Chrome, sur divers ordinateurs, pas tous avec des paramètres de navigateur synchronisés, mais lorsque j’utilise l’impression, votre bloc de code est rogné à :

     // Players drawn card
     private Card playersCard;

ce qui est aussi tout ce que je peux voir jusqu’à présent lorsque je visualise votre publication en ligne (je dois faire défiler vers le bas à l’intérieur du cadre de code pour en voir plus). Je posterais ma version, mais je n’ai pas assez de publications pour télécharger des fichiers, mais vous voyez l’idée.

Votre version imprimée semble certainement meilleure, je ne suis pas sûr pourquoi elle est différente, mais elle n’est pas parfaite non plus. Les lignes de code ne reviennent pas à la ligne et sont donc rognées, et toutes les pages ont un rectangle bleu flottant en bas à gauche qui obstrue également du texte. Malheureusement, dans cet état, ce n’est pas vraiment utilisable non plus.

Quelqu’un sur le forum SuperCollider a fourni la solution consistant à insérer le bloc CSS suivant dans l’inspecteur du navigateur, ou lors de l’utilisation d’un plugin de navigateur (actuellement, j’ai l’extension Chrome Stylish, et elle l’ajoute automatiquement lorsque je suis sur ce forum) :

pre code {
    white-space: 	pre-wrap;
    max-height: 	none;
    background: 	#fafafa;
}

L’utilisation de ceci rend l’impression tout à fait fonctionnelle pour moi. Et avec l’extension de navigateur, il n’est pas nécessaire d’intervenir à chaque fois que je veux sauvegarder quelque chose, c’est la vraie solution… sinon c’est trop de travail.

Néanmoins, j’aimerais qu’il y ait un moyen plus simple d’archiver des fils de discussion, ou plutôt, j’aimerais qu’il y ait un moyen de ne pas avoir besoin de ces étapes supplémentaires.

Surtout que la plupart des fonctionnalités existent déjà : soit visualiser une publication brute, soit pouvoir imprimer. Mais bon, il n’est pas possible de voir l’intégralité du fil de discussion en mode brut, juste une seule publication, et l’impression ne fonctionne pas très bien.

Cela dit, les signets sont une fonctionnalité de forum géniale et je les utilise tout le temps, mais cela maintient tout à l’intérieur de Discourse.

1 « J'aime »

Nous pourrions ajouter une route qui renvoie le sujet entier en brut @falco ? Cela pourrait être utile, bien que nous devions faire attention aux méga-sujets…

Nous avons certainement déjà cela pour les messages individuels, par exemple

https://meta.discourse.org/raw/152185/12

3 « J'aime »

C’est tout à fait réalisable, bien que ce soit un cas d’utilisation assez spécifique.

Le format serait quelque chose comme :

nom d'utilisateur | horodatage | numéro de message

corps du message

---

nom d'utilisateur | horodatage | numéro de message

corps du message

---

nom d'utilisateur | horodatage | numéro de message

corps du message

?

2 « J'aime »

Oui, je le soutiens cependant. Si nous avons un itinéraire /raw/ pour les publications, pourquoi pas un pour un sujet ?

2 « J'aime »

Actuellement, la route https://meta.discourse.org/raw/152185 ne retourne que l’OP. Est-il acceptable de modifier le comportement de cette route ? Les utilisateurs devront explicitement appeler https://meta.discourse.org/raw/152185/1 pour obtenir uniquement l’OP.

2 « J'aime »

Ce que vous jugerez le mieux me convient.

2 « J'aime »

Ceci est maintenant en ligne : https://meta.discourse.org/raw/152185

Faites-moi savoir si c’est ce que vous aviez en tête @here

8 « J'aime »

J’adore ! Ça me semble parfait ! :heart_eyes:

3 « J'aime »

C’est vraiment super. Merci :pray:

3 « J'aime »

Merci beaucoup ! et plus de personnages !

2 « J'aime »