Partage
  • Partager sur Facebook
  • Partager sur Twitter

Diviser un programme en fonctions

aide

    21 mai 2006 à 10:07:07

    bonjour,
    est ce que quelqu'un a des idées pour minimaliser ce code en fonction, car moi je vois pas trop ce que je vais changer :
    #include <stdio.h>
    #include <stdlib.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>

    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL,*image = NULL, *raquette = NULL,*brique = {NULL};
        SDL_Rect positionImage, positionRaquette , positionBrique;
        SDL_Event event;
        int continuer = 1,direction = 0 , hautbas = 0,condition = 0;


        SDL_Init(SDL_INIT_VIDEO);

        ecran = SDL_SetVideoMode(400 ,400 ,32, SDL_HWSURFACE | SDL_DOUBLEBUF);


        image = IMG_Load("balle.gif");

        brique = IMG_Load("brique.png");

        raquette = IMG_Load("raquette.jpg");
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
        SDL_WM_SetCaption("Gestion des évènements en SDL", NULL);

        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));

        positionRaquette.x = (ecran->w /2) - (raquette->w / 2);
        positionRaquette.y = 450;

        positionBrique.x = 200;
        positionBrique.y = 200;

        positionImage.x = 160;
        positionImage.y = 120;

        SDL_ShowCursor(SDL_DISABLE);

        while(continuer)
        {
            SDL_PollEvent(&event);

            if((ecran->h - image->h) == positionImage.y || (positionImage.y + image->h) == positionRaquette.y && (image->w + positionImage.x) >= positionRaquette.x && positionImage.x < (positionRaquette.x + raquette->w))
            {
            direction = 1;
            }

            if((image->w + positionImage.x) >= positionBrique.x && positionImage.x < (positionBrique.x + brique->w)  && positionBrique.y == ( positionImage.y + image->h) && condition < 3)
            {
            direction = 1;
            condition++;
            }
            if(positionImage.y == 0)
            {
            direction = 0;
            }
            if((ecran->w - image->w) == positionImage.x)
            {
            hautbas = 1;
            }
            if(positionImage.x == 0)
            {
            hautbas = 0;
            }
            switch(condition)
            {
            case 0:
            brique = IMG_Load("brique.png");
            break;
            case 1:
            brique = IMG_Load("brique1.png");
            break;
            case 2:
            brique = IMG_Load("brique2.png");
            break;
            }
            switch(direction)
            {
                case 1:
                positionImage.y -= 2;
                break;
                case 0:
                positionImage.y += 2;
                break;
            }
            switch(hautbas)
            {
                case 1:
                positionImage.x -= 2;
                break;
                case 0:
                positionImage.x += 2;
                break;
            }
            switch(event.type)
            {
                case SDL_QUIT :
                continuer = 0;
                break;
                case SDL_MOUSEMOTION:
                positionRaquette.x = event.motion.x;
                positionRaquette.y = 350;
                break;

            }


        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
        SDL_BlitSurface(image,NULL,ecran,&positionImage);
        SDL_BlitSurface(raquette,NULL,ecran,&positionRaquette);
        if(condition < 3)
        {
        SDL_BlitSurface(brique,NULL,ecran,&positionBrique);
        }
        SDL_Flip(ecran);
        }


        SDL_FreeSurface(image);
        SDL_FreeSurface(raquette);
        SDL_FreeSurface(brique);
        SDL_Quit();

        return EXIT_SUCCESS;

    }


    pas de moquerie :p , c'est un code banal pour une conseption d'un casse brique
    et merci d'avance pour les réponses
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      21 mai 2006 à 11:20:59

      Tu pourrais faire :

      Une fonction init() qui initialise SDL, les surfaces, et charge les images.
      Une fonction quit() qui free tout et quitte proprement.
      Une fonction de boucle principale qui traîte les évènements.
      Si besoins, des fonctions correspondant aux divers actions possibles (déplacements par exemple) ou aux teste (collisions).

      Le tout communique en se passant des struct en arguments. Ou alors en variable globales sinon.
      • Partager sur Facebook
      • Partager sur Twitter
        21 mai 2006 à 11:23:49

        yop

        bon ça parait judicieux de diviser tout ça en 2 ou 3 fonctions :)

        dans le main tu laisses les initialisations, dans une autre fonction tu mets le chargement des images, l'affichage et la boucle d'evenement, et dans une troisième la modification des positions.

        le mieux serait de mettre ces 2 dern,ières fonctions das un fichier à part et de créé vite fait le .h :)

        Voila bien sur il y a d'autre possibilité :)
        • Partager sur Facebook
        • Partager sur Twitter
          21 mai 2006 à 12:26:40

          #include <stdio.h>
          #include <stdlib.h>
          #include <SDL/SDL.h>
          #include <SDL/SDL_image.h>

          void init();

          int main(int argc, char *argv[])
          {
              init();

              SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
              SDL_WM_SetCaption("Gestion des évènements en SDL", NULL);

              SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));

              positionRaquette.x = (ecran->w /2) - (raquette->w / 2);
              positionRaquette.y = 450;

              positionBrique.x = 200;
              positionBrique.y = 200;

              positionImage.x = 160;
              positionImage.y = 120;

              SDL_ShowCursor(SDL_DISABLE);

              while(continuer)
              {
                  SDL_PollEvent(&event);

                  if((ecran->h - image->h) == positionImage.y || (positionImage.y + image->h) == positionRaquette.y && (image->w + positionImage.x) >= positionRaquette.x && positionImage.x < (positionRaquette.x + raquette->w))
                  {
                  direction = 1;
                  }

                  if((image->w + positionImage.x) >= positionBrique.x && positionImage.x < (positionBrique.x + brique->w)  && positionBrique.y == ( positionImage.y + image->h) && condition < 3)
                  {
                  direction = 1;
                  condition++;
                  }
                  if(positionImage.y == 0)
                  {
                  direction = 0;
                  }
                  if((ecran->w - image->w) == positionImage.x)
                  {
                  hautbas = 1;
                  }
                  if(positionImage.x == 0)
                  {
                  hautbas = 0;
                  }
                  switch(condition)
                  {
                  case 0:
                  brique = IMG_Load("brique.png");
                  break;
                  case 1:
                  brique = IMG_Load("brique1.png");
                  break;
                  case 2:
                  brique = IMG_Load("brique2.png");
                  break;
                  }
                  switch(direction)
                  {
                      case 1:
                      positionImage.y -= 2;
                      break;
                      case 0:
                      positionImage.y += 2;
                      break;
                  }
                  switch(hautbas)
                  {
                      case 1:
                      positionImage.x -= 2;
                      break;
                      case 0:
                      positionImage.x += 2;
                      break;
                  }
                  switch(event.type)
                  {
                      case SDL_QUIT :
                      continuer = 0;
                      break;
                      case SDL_MOUSEMOTION:
                      positionRaquette.x = event.motion.x;
                      positionRaquette.y = 350;
                      break;

                  }


              SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
              SDL_BlitSurface(image,NULL,ecran,&positionImage);
              SDL_BlitSurface(raquette,NULL,ecran,&positionRaquette);
              if(condition < 3)
              {
              SDL_BlitSurface(brique,NULL,ecran,&positionBrique);
              }
              SDL_Flip(ecran);
              }


              SDL_FreeSurface(image);
              SDL_FreeSurface(raquette);
              SDL_FreeSurface(brique);
              SDL_Quit();

              return EXIT_SUCCESS;

          }

          est ce que ca marcherais si je me débrouille pour faire la fonction init()?
          • Partager sur Facebook
          • Partager sur Twitter
            21 mai 2006 à 12:29:22

            c'est ce que je fais le plus souvent. tu met toute la partie initial du programme comme sa tu sais rapidement ou est ce que tu dois aller si tu veux changer quelque chose du depart :)
            • Partager sur Facebook
            • Partager sur Twitter
              21 mai 2006 à 12:34:14

              je me demandais justement:
              est ce que ce code marcherais si je me débrouillais pour faire la fonction init() sans faire des return dessus ??
              • Partager sur Facebook
              • Partager sur Twitter
                21 mai 2006 à 12:40:31

                ben prend par exemple un jeu ou tu a plein de caractéristique pour un personnage [ nombre de pv, puissance, precision, magie, ... (je prend sur exemple d'un jeu que j'ai fait moi) ]
                tu insères des variables globales et tu met dans ta fonction init() tout ce qui concerne le perso au debut du jeu.
                Pour les surfaces c'est pareil, mais toi par exemple tu peux mettre sa dedant
                    positionRaquette.x = (ecran->w /2) - (raquette->w / 2);
                    positionRaquette.y = 450;

                    positionBrique.x = 200;
                    positionBrique.y = 200;

                    positionImage.x = 160;
                    positionImage.y = 120;

                mais n'oubli pas de les mettre en variable global ou tu ne pourras pas les appeller de partout.
                • Partager sur Facebook
                • Partager sur Twitter
                  21 mai 2006 à 12:47:01

                  comment ca???
                  mettre des varibles dans une variable globale ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    21 mai 2006 à 13:04:43

                    ben dans ce cas variable n'est utilisable que dans main()

                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <SDL/SDL.h>
                    #include <SDL/SDL_image.h>


                    int main(int argc, char *argv[])
                    {
                              int variable;
                              /*reste du programme*/
                    }


                    Pour faire une variable global tu fais sa :

                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <SDL/SDL.h>
                    #include <SDL/SDL_image.h>

                    int variable;

                    int main(int argc, char *argv[])
                    {
                              /*reste du programme*/
                    }


                    Ici tu pourras appeler ta variable partout dans ton fichier sources.

                    Et si tu veux l'utilisé dans main.cpp et fonction.cpp par exemple tu crés une variable global dans main et dans fonction.cpp tu met
                    extrn int variable;


                    [pour cette information de plusieurs fichier sources je ne suis pas sur donc il se peut qu'il y ai des erreurs.]


                    donc pour en revenir a ton jeu tu peux créer des variables globales et dans une fonction init() tu leurs donne une valeur initial.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 mai 2006 à 13:18:15

                      oula :)

                      il vaut mieux éviter le plus possible les variables globales sinon ça devient vite le bordel

                      Il te suffit de déclarer les variables dans les fonctions et de les passer en argument aux autres fonctions :)

                      tu peux aussi créer des structures si tu passes souvent des arguments qui ont un rapport direct entre eux (genre abscisse/ordonnée ...)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        21 mai 2006 à 13:32:29

                        je ne comprends pas vraiment tout ca
                        est ce que quelqu'un peut m'expliquer clairement SVP
                        • Partager sur Facebook
                        • Partager sur Twitter
                          21 mai 2006 à 13:52:04

                          Binabik pence que les variables globales ne sont pas une bonne chose. personnelement je les trouve pratique sa evite de devoir passer des arguments.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            21 mai 2006 à 13:58:55

                            Il faut les utiliser dans des cas très particuliers.
                            Tu peut mettre l'ecran en variable globale, histoire de ne pas le passer a toutes tes fonction mais sinon..
                            • Partager sur Facebook
                            • Partager sur Twitter
                              21 mai 2006 à 14:18:53

                              disons cactO que sur un petit projet, ce n'est pas trop grave, mais sur un gros, tu te perds facilement

                              l'erreur la plus courrante étant de modifier une variable globale "par accident" ou d'oublier de la réinitialiser à la fin d'une portion de code quelconque.
                              Quelques autres problèmes aussi si tu travailles en équipe
                              • Partager sur Facebook
                              • Partager sur Twitter
                                21 mai 2006 à 14:27:40

                                oui mais poru dire une variable qui va gérer le placement dans un répère donc x,y,z qui s'apelle tout le temps dans toutes les fonctions c'est plus pratique de mettre 3variables globales et comme sa plus besoin devoir a passer les arguments...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  21 mai 2006 à 15:45:47

                                  pas encore répondu a ma question
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    21 mai 2006 à 19:02:24

                                    Citation : CactO_o's

                                    [...] Pour faire une variable global tu fais sa : [...]


                                    Très mauvaise idée, pour savoir, par exemple, quel est la valeur de la variable il devra chercher si c'est une globale ou non et ça, c'est déjà prise de tête.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      21 mai 2006 à 19:11:52

                                      ou alors tu t'invente un code personnelle et compréhensible:

                                      vie; //variable simple
                                      point_vie; // pour un pointeur
                                      glob_vie; // pour une variable global
                                      etc...
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        21 mai 2006 à 19:21:42

                                        Citation : CactO_o's

                                        ben dans ce cas variable n'est utilisable que dans main()


                                        Et alors ? Passage de paramètre, ça te dis quelque chose, ou tu en es resté à GWBASIC ?

                                        Citation : CactO_o's


                                        Pour faire une variable global tu fais sa :


                                        Merci de ne pas donner de mauvaises habitudes aux débutants.

                                        Il faut apprendre à programmer par contexte, et ce, dès le plus jeune age. Le code spaghetti, non merci.

                                        #include <stdio.h>

                                        struct data
                                        {
                                           int x;
                                           char const *y;
                                        };

                                        static void f(struct data *p_data)
                                        {
                                           p_data->x++;

                                           printf ("%s #%d\n", p_data->y, p_data ->x);
                                        }

                                        int main (void)
                                        {
                                           struct data data;

                                           data.x = 0;
                                           data.y = "Hello";

                                           f(&data);
                                           f(&data);

                                           return 0;
                                        }


                                        Hello #1
                                        Hello #2

                                        Press ENTER to continue.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Music only !
                                          21 mai 2006 à 19:25:10

                                          c'est peut etre pas la meilleure solution poru les gros programme mais au moins sa marche.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            21 mai 2006 à 19:29:09

                                            Citation : CactO_o's

                                            c'est peut etre pas la meilleure solution poru les gros programme mais au moins sa marche.


                                            Le passage par argument et la modification par pointeur aussi.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              21 mai 2006 à 19:32:58

                                              dirrectement plus compliquer.
                                              C'est clair que si c'ets poru programmer un jeu complet a titre public c'est surment mieu d'utilisé meilleurs methodes tel les pointeurs et passages d'arguments, mais pour des petits projet personnels, parfois c'est mieu, enfin je trouve sa plus rapide et plus pratique.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                22 mai 2006 à 0:40:44

                                                Citation : CactO_o&#039;s

                                                dirrectement plus compliquer.
                                                C'est clair que si c'ets poru programmer un jeu complet a titre public c'est surment mieu d'utilisé meilleurs methodes tel les pointeurs et passages d'arguments, mais pour des petits projet personnels, parfois c'est mieu, enfin je trouve sa plus rapide et plus pratique.



                                                Plus rapide et pratique seulement si tu veux tester des nouveaux trucs, mais même pour des petits projets personnels c'est toujours moins bien parce que ton code évolue alors plus difficilement...
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  22 mai 2006 à 18:56:42

                                                  une meilleur solution pour ce code
                                                  #include <stdlib.h>
                                                  #include <stdio.h>
                                                  #include <SDL/SDL.h>
                                                  #include <SDL/SDL_image.h>
                                                  #include <SDL/SDL_ttf.h>

                                                  void initialisation();

                                                  SDL_Surface *ecran = NULL;

                                                  int main(int argc, char *argv[])
                                                  {
                                                      SDL_Surface *zozor = NULL;
                                                      SDL_Rect positionZozor;
                                                      SDL_Event event;
                                                      int continuer = 1;
                                                      int tempsPrecedent = 0, tempsActuel = 0;

                                                      initialisation();
                                                      zozor = SDL_LoadBMP("zozor.bmp");
                                                      SDL_SetColorKey(zozor, SDL_SRCCOLORKEY, SDL_MapRGB(zozor->format, 255, 0, 0));

                                                      positionZozor.x = ecran->w / 2 - zozor->w / 2;
                                                      positionZozor.y = ecran->h / 2 - zozor->h / 2;

                                                      SDL_EnableKeyRepeat(10, 10);

                                                      while (continuer)
                                                      {
                                                          SDL_PollEvent(&event);
                                                          switch(event.type)
                                                          {
                                                              case SDL_QUIT:
                                                                  continuer = 0;
                                                                  break;
                                                          }
                                                          tempsActuel = SDL_GetTicks();
                                                          if (tempsActuel - tempsPrecedent > 30) /* Si 30 ms se sont écoulées */
                                                          {
                                                              positionZozor.x++; /* On bouge Zozor */
                                                              tempsPrecedent = tempsActuel; /* Le temps "actuel" devient le temps "precedent" pour nos futurs calculs */
                                                          }
                                                          else /* Si ça fait moins de 30ms depuis le dernier tour de boucle, on endort le programme le temps qu'il faut */
                                                          {
                                                              SDL_Delay(30 - (tempsActuel - tempsPrecedent));
                                                          }

                                                          SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
                                                          SDL_BlitSurface(zozor, NULL, ecran, &positionZozor);
                                                          SDL_Flip(ecran);
                                                      }

                                                      SDL_FreeSurface(zozor);
                                                      SDL_Quit();

                                                      return EXIT_SUCCESS;
                                                  }
                                                  void initialisation()
                                                  {

                                                      SDL_Init(SDL_INIT_VIDEO);

                                                      ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
                                                      SDL_WM_SetCaption("Gestion du temps en SDL", NULL);
                                                     
                                                  }


                                                  même si ce dernier marche très bien.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    22 mai 2006 à 20:27:01

                                                    Citation : oussama1305

                                                    une meilleur solution pour ce code

                                                    #include <stdlib.h>
                                                    #include <stdio.h>
                                                    #include <SDL/SDL.h>
                                                    #include <SDL/SDL_image.h>
                                                    #include <SDL/SDL_ttf.h>

                                                    void initialisation();

                                                    SDL_Surface *ecran = NULL;



                                                    Globale inutile...
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Music only !
                                                      22 mai 2006 à 22:56:00

                                                      pourquoi ca?
                                                      on en a besoin dans la fonction et dans le main :(
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        22 mai 2006 à 23:03:59

                                                        Citation : oussama1305

                                                        pourquoi ca?
                                                        on en a besoin dans la fonction et dans le main :(


                                                        Et ? On la définit dans le main() et on la passe à qui en a besoin.

                                                        Si il y en a beaucoup (>= de 2), on définit un contexte.
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Music only !
                                                          23 mai 2006 à 18:14:30

                                                          #include <stdlib.h>
                                                          #include <stdio.h>
                                                          #include <SDL/SDL.h>
                                                          #include <SDL/SDL_image.h>
                                                          #include <SDL/SDL_ttf.h>

                                                          int initialisation(SDL_Surface *ecran);

                                                          int main(int argc, char *argv[])
                                                          {
                                                              SDL_Surface *zozor = NULL, *ecran = NULL;
                                                              SDL_Rect positionZozor;
                                                              SDL_Event event;
                                                              int continuer = 1;
                                                              int tempsPrecedent = 0, tempsActuel = 0;

                                                              initialisation(ecran);
                                                              zozor = SDL_LoadBMP("zozor.bmp");
                                                              SDL_SetColorKey(zozor, SDL_SRCCOLORKEY, SDL_MapRGB(zozor->format, 255, 0, 0));

                                                              positionZozor.x = ecran->w / 2 - zozor->w / 2;
                                                              positionZozor.y = ecran->h / 2 - zozor->h / 2;

                                                              SDL_EnableKeyRepeat(10, 10);

                                                              while (continuer)
                                                              {
                                                                  SDL_PollEvent(&event);
                                                                  switch(event.type)
                                                                  {
                                                                      case SDL_QUIT:
                                                                          continuer = 0;
                                                                          break;
                                                                  }
                                                                  tempsActuel = SDL_GetTicks();
                                                                  if (tempsActuel - tempsPrecedent > 30) /* Si 30 ms se sont écoulées */
                                                                  {
                                                                      positionZozor.x++; /* On bouge Zozor */
                                                                      tempsPrecedent = tempsActuel; /* Le temps "actuel" devient le temps "precedent" pour nos futurs calculs */
                                                                  }
                                                                  else /* Si ça fait moins de 30ms depuis le dernier tour de boucle, on endort le programme le temps qu'il faut */
                                                                  {
                                                                      SDL_Delay(30 - (tempsActuel - tempsPrecedent));
                                                                  }

                                                                  SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
                                                                  SDL_BlitSurface(zozor, NULL, ecran, &positionZozor);
                                                                  SDL_Flip(ecran);
                                                              }

                                                              SDL_FreeSurface(zozor);
                                                              SDL_Quit();

                                                              return EXIT_SUCCESS;
                                                          }
                                                          int initialisation(SDL_Surface *ecran)
                                                          {

                                                              SDL_Init(SDL_INIT_VIDEO);

                                                              ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
                                                              SDL_WM_SetCaption("Gestion du temps en SDL", NULL);

                                                          }

                                                          avec ce code mon code plante et je vois une fenêtre qui apparait et disparait a la vitesse de la lumière. et puis :

                                                          Citation : -ed-

                                                          Si il y en a beaucoup (>= de 2), on définit un contexte.


                                                          je n'ai pas bien compris ce que tu veux dire par là
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            23 mai 2006 à 19:17:35

                                                            Citation : oussama1305

                                                            int initialisation(SDL_Surface *ecran);


                                                            avec ce code mon code plante


                                                            Normal, ton interface est incorrecte. La fonction initialisation() modifie le pointeur 'ecran'. Il faut donc
                                                            • soit passer l'adresse du pointeur
                                                            int initialisation(SDL_Surface **pp_ecran);
                                                            soit retourner sa valeur
                                                            SDL_Surface *initialisation(void);
                                                            </ul>

                                                            Citation : oussama1305


                                                            Citation : -ed-

                                                            Si il y en a beaucoup (>= de 2), on définit un contexte.


                                                            je n'ai pas bien compris ce que tu veux dire par là


                                                            Un contexte, c'est une structure qui contient les paramètres :

                                                            struct contexte
                                                            {
                                                               int parametre_a;
                                                               char *parametre_b;
                                                            };

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            Music only !

                                                            Diviser un programme en fonctions

                                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                            • Editeur
                                                            • Markdown