Program liczący słowa w tekście

Program liczący słowa w tekście
Manna5
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Kraków
  • Postów:636
0

Dziś jako ćwiczenie napisałem prosty program zliczający wystąpienia słów w pliku tekstowym i chciałbym się nim podzielić w celu uzyskania komentarzy (a może nawet ktoś użyje tego programu).

Kopiuj
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORDLEN 16
struct  wordent
{       char    word[WORDLEN];
        int     count;
        struct  wordent *next;
};
struct  wordent *wordlist = NULL;
void    regword (char *word)
{       struct  wordent *ent;
        for (ent = wordlist; ent; ent = ent->next)
                if (!strcmp (word, ent->word))
                {       ++(ent->count);
                        return;
                }
        ent = malloc (sizeof (struct wordent));
        strcpy (ent->word, word);
        ent->count = 1;
        ent->next = wordlist;
        wordlist = ent;
}
void    freelist (struct wordent *top)
{       if (top)
        {       freelist (top->next);
                free (top);
        }
}
int     main (int argc, char **argv)
{       FILE    *fp = stdin;
        char    c, wordbuf[WORDLEN], wlen = 0;
        int     maxcount, n = 0;
        struct  wordent *ent, *maxent;
        if (argc > 1)
                fp = fopen (argv[1], "r");
        if (!fp)
        {       puts ("Can't read the input file.");
                return 1;
        }
        do
        {       c = fgetc (fp);
                if (c >= 'A' && c <= 'Z')
                        c |= 32;
                if (c >= 'a' && c <= 'z')
                {       if (wlen < (WORDLEN - 1))
                                wordbuf[wlen++] = c;
                } else if (wlen)
                {       wordbuf[wlen] = 0;
                        regword (wordbuf);
                        wlen = 0;
                }
        }       while (c != EOF);
        list:
                maxent = NULL; maxcount = 0;
                for (ent = wordlist; ent; ent = ent->next)
                        if (ent->count > maxcount)
                        {       maxent = ent;
                                maxcount = maxent->count;
                        }
                if (maxent)
                {       printf ("Word \"%s\" %d times.\n", maxent->word, maxcount);
                        maxent->count = 0;
                        ++n;
                        goto list;
                }
        printf ("Total %d unique words.\n", n);
        freelist (wordlist);
        return 0;
}

edytowany 1x, ostatnio: Manna5
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:19 dni
  • Postów:105
1
Kopiuj
goto hell;

Cześć, mam pytanie, dlaczego tak często korzystasz z goto? Trochę pachnie to spaghetti code :(


Jak/czym to kompilujesz?
screenshot-20230224195453.png


Poniżej podsyłam Ci jak ja bym to zrobił :)

Kopiuj
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <iostream>
#include <unordered_map>
#include <chrono>

int main(const int argc, char** argv) {
    if (argc < 2) {
        std::cout << "Can't read the input file." << std::endl;

        return EXIT_FAILURE;
    }

    std::ifstream input_file(argv[1], std::ios_base::in);
    std::unordered_map<std::string, int> dictionary = {};
    std::vector<char> break_character { '\r', '\n', '\t', 32 };

    std::cout << "File '"<< argv[1] << "' processing started." << std::endl;
    const auto start = std::chrono::high_resolution_clock::now();

    char c;
    std::string buffer;
    while (input_file.get(c)) {
        if (std::ranges::find(break_character, c) != break_character.end()) {
            if (auto dictionary_element = dictionary.find(buffer); dictionary_element != dictionary.end()) {
                dictionary_element->second++;
            } else {
                dictionary.insert(std::make_pair(buffer, 1));
            }

            buffer = {};
        }
        else {
            if (std::isalpha(c)) {
                buffer.push_back(c);
            }
        }
    }

    if(!buffer.empty())
    {
        if (const auto dictionary_element = dictionary.find(buffer); dictionary_element != dictionary.end()) {
            dictionary_element->second++;
        }
        else {
            dictionary.insert(std::make_pair(buffer, 1));
        }
    }

    const auto stop = std::chrono::high_resolution_clock::now();
    std::cout << "File '" << argv[1] << "' processing finished in "<< duration_cast<std::chrono::milliseconds>(stop - start).count() <<"ms." << std::endl << std::endl;

    for (auto [key, value] : dictionary) {
        std::cout << "Word \"" << key << "\" " << " occurred " << value << " times." << std::endl;
    }

    std::cout << "Total " << dictionary.size() << " unique words." << std::endl;
}
edytowany 5x, ostatnio: Deltech
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10051
0

A on liczy np czerwono-zielony jako pojedyncze słowo czy dwa słowa?

Manna5
Dwa, bo rozdziela je nie-litera.
Manna5
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Kraków
  • Postów:636
0

Używam strcpy, gdyż na etapie przekazania ciągu znaków do funkcji regword (z main) jest pewne, że ciąg ma poniżej WORDLEN znaków, tak więc nie trzeba tego sprawdzać dwa razy.
Typ void dla pliku - rzeczywiście miałem źle, zmieniam na FILE. Co do innych (przy alokacji) to trzeba by dodać explicit casty, wydawało mi się, że standard ANSI rzutuje typy domyślnie przy wywołaniu funkcji i powinno się skompilować. Na screenie widać, że kompilujesz to jako C++, może dlatego są błędy.
Jeśli chodzi o tę instrukcję goto to istnienie maxent warunkuje zarówno operacje z linii 62-64 jak i powtórzenie pętli. W przypadku użycia strukturalnego do-while warunek byłby sprawdzany dwa razy - raz w instrukcji if i drugi raz by zdecydować o powtórzeniu pętli.


edytowany 1x, ostatnio: Manna5
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10051
0

Odmianę słów, jak Otworzyłem youtube'a, to youtube'a to powinno być jedno słowo, też zaliczysz je jako osobne?

Manna5
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Kraków
  • Postów:636
0

Odmiana słów jest inna dla każdego języka (a w j. polskim wyjątkowo kłopotliwa), nie jest zaimplementowana. W tym konkretnym przykładzie apostrof nie jest literą, więc rozdzieli to na słowa youtube i a.


Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10051
1
Manna5 napisał(a):

Odmiana słów jest inna dla każdego języka (a w j. polskim wyjątkowo kłopotliwa), nie jest zaimplementowana. W tym konkretnym przykładzie apostrof nie jest literą, więc rozdzieli to na słowa youtube i a.

To dla jakiego języka to zrobiłeś? Angielskiego?

Bo jeśli tak to np Let's go też rozdzieli? Albo Mark's books?

cerrato
Albo Mary's boobs ;)
Manna5
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Kraków
  • Postów:636
0

Z angielskim działa w miarę poprawnie, bo tam raczej nie ma jako takiej odmiany. Właściwie to forma skrócona 's' jest semantycznie innym słowem.


ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1

Jakbym miał grymasić, struktura danych byłaby Map / Dictionary a nie List.
Powiem wiecej, oprócz technologii wyodrębniania słów z ciagu literek - jeśli nie zajmujemy się odmianami i gramatyką - to BYŁABY wiodąca część pokazania poweru progrmaisty

Choć rozumiem, że w szkolnym C (mam na myśli ze sam jezyk ma poziom szkolny, niezależnie od użytkownika ) Map /Dictionary jest przerażająco złożone, i (w tym wypadku naprawdę) szkolna lista nasuwa sie jako ratunek.
Szkolna m.in. w tym sensie, że na stałej długości pola itd... profesjonalna by była na zmienną

Generalnie w C złożoność wystrzela w niebo z każdym współczesnym kontenerem. Modlitwy i palenie świętych kadzidełek aby symetrycznie do pary alokować - zwolnić itd...
Drzewa ? Dla mnie osobiście przerażenie (i to wcale nie w sensie nie istniejace w bibliotece / istniejące gotowce, tylko możliwość napisania, zdebugowania, konserwacji i nie wylądowania w Tworkach)

Dobry projekt, aby dostrzec, jak szybko ten język się kończy w swojej ekspresji, i coś z ta nowa wiedzą zrobić.


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
edytowany 1x, ostatnio: ZrobieDobrze
ZD
Drugie MOCNE uzasadnienie, że ta lista nie przekracza tzw "szkolnej", to że jest jedna w całym programie
SA
  • Rejestracja:około 12 lat
  • Ostatnio:7 minut
  • Postów:1427
3

Jesli ten projekt ma czegos nauczyć to tego, żeby nie robić tego w C.

Dlaczego nie splitujesz na białych znakach? To wydaje się bardziej naturalne.

Manna5
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Kraków
  • Postów:636
0

Dlaczego nie splitujesz na białych znakach? To wydaje się bardziej naturalne.

Gdyby tak robić, program zaliczyłby np. słowo znakach? - ze znakiem zapytania, który jest niebiały. Pewne znaki (myślnik, apostrof) rzeczywiście można by rozważyć jako część słowa.

Szkolna m.in. w tym sensie, że na stałej długości pola itd... profesjonalna by była na zmienną

Zmienny bufor słowa trzeba by na etapie przetwarzania pliku realokować co pewną porcję liter (chyba że powinno się to zrobić w jescze inny sposób), spróbuję to dodać w ramach ćwiczenia.


ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1
Manna5 napisał(a):

Szkolna m.in. w tym sensie, że na stałej długości pola itd... profesjonalna by była na zmienną

Zmienny bufor słowa trzeba by na etapie przetwarzania pliku realokować co pewną porcję liter (chyba że powinno się to zrobić w jescze inny sposób), spróbuję to dodać w ramach ćwiczenia.

Skoro podjąłeś moją wypowiedź: w stosunku do innych problemów tego projektu, to naprawdę detal *)

Dosłysz to, z @Saalin chcemy ci powiedzieć: to nie projekt na C. Można mieć do C stosunek religijny niezaleznie od dopasowania do projektu, ale z inżynierią to nie ma ci wspólnego.
W RAMACH ĆWICZENIA - jeśli ma być naprawdę pożyteczne, zrób ten temat w innym języku (obojętne: C++, Python, Java, C#, i zrób sobie analizę porównawczą).

Jak jednak uparcie C, zamiast kopiowania szkolnej listy zrób wytestowane drzewo, za to uzyskasz mój szacunek (choć ze 20x łatwiej to bezpieczniej zrobić w C++)

*) mina, jaką trawą przysypałem: ciekawe jak elegancko to będziesz zwalniał.


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
Zobacz pozostały 1 komentarz
Althorion
Tak. 🤷 Bo nie zyskuje na tym, gdzie C ma przewagę nad C++, a traci tam, gdzie C++ ma przewagę nad C.
JB
Althorion
Przewagi C++ nad C, które byłyby użyteczne w tym projekcie? 1. Dużo łatwiej ogarnąć różne błędne ścieżki wykonania — gwarantowany destruktor jest trudniejszy w błędnym użyciu niż goto clean, czy inne takie. 2. Dużo łatwiej ogarnąć abstrakcję nad przechowywanymi typami danych — templatki są trudniejsze w błędnym użyciu niż void *. 3. Dużo łatwiej zapewnić, że struktura danych będzie zawsze w używalnym stanie — gwarantowany konstruktor i możliwość łatwego ograniczania dostępu do szczegółów implementacji ułatwia kontrolę wszystkich niezbędnych niezmienników.
Althorion
To nie jest projekt typu sterownik sprzętowy, gdzie luźne podejście do typowania czy łatwość w „bitologii stosowanej” się przydają częściej, niż szkodzą.
JB
Jego projekt jest trochę jakiś zagmatwany. On użył listy, ja bym zrobił tablicę wskaźników. "goto" nie będę komentował bo nigdy nie potrzebowałem użyć. Jak chcesz ja dopiszę brakujące fragmenty w tym moim poniżej (tam brakuje alokacji pamięci i zapewne jednego strcmp() i wtedy mi pokażesz co tam jest groźnego. 2 wpis poniżej. Bo nie ogarniam co tam może się wysypać. A co niby ma się stać ze strukturą danych, że przestanie być "używalna"? Bo jeszcze w życiu nie przejechałem wskaźnikiem z jakimiś danymi po strukturze. To by trzeba użyć pętli, i wskazać na tą strukturę.
SA
  • Rejestracja:około 12 lat
  • Ostatnio:7 minut
  • Postów:1427
0
Manna5 napisał(a):

Dlaczego nie splitujesz na białych znakach? To wydaje się bardziej naturalne.

Gdyby tak robić, program zaliczyłby np. słowo znakach? - ze znakiem zapytania, który jest niebiały. Pewne znaki (myślnik, apostrof) rzeczywiście można by rozważyć jako część słowa.

znakach? to jedno słowo. To nie wpływa na liczbę słów przecież czy znaki takie jak kropka, przecinek czy znak zapytania zaliczymy do słowa.

JB
  • Rejestracja:około 2 lata
  • Ostatnio:3 dni
  • Lokalizacja:Holandia
  • Postów:843
0

FILE *fp = stdin;

*fp?

Tak powinna wyglądać nazwa wg Ciebie?

Zobacz poniżej jakie ja dawałem nazwy zmiennych i funkcji.

void freelist (struct wordent *top)

Dajesz rade po polsku widzę. to freelist mi brzmi jak "new" "malloc" "int".

Będziesz dawał polskie nazwy albo chociaż z "_" w nazwie to szybciej ludzie się domyślą co do czego służy.

Ładnie te nawiasy klamrowe dajesz

Kopiuj
void    freelist (struct wordent *top)
{       if (top)
       {       freelist (top->next);
               free (top);
       }
}

Ja to raczej robię tak

Kopiuj
void    freelist (struct wordent *top){
                                       if (top){
                                               freelist (top->next);
                                               free (top);}}

Tak ładnie to porobiłeś, że strach literki zmieniać.

Twój sposób chyba czytelniejszy.
Rzadko miewam kłopoty z oceną.

Dałbyś jakiś plik tekstowy przykładowy i wynik użycia to mógłbym spróbować to zrobić dużo prościej, a tak ...

Wbrew temu co wypisują wyżej C ma wszystko czego potrzebujesz.

Staraj się dzielić zadania na mniejsze części.

Ja bym zaczął tak:

Kopiuj
#include <stdio.h>
#include <string.h>

int ilosc_zdan;
char tablica[300][500];
int tablica_slow[300];
char tekst[500];

int wczytaj_zdania(){
                    char znak;
                    int pozycja=0;
                    int pozycja_nowa=0;
                    znak=tekst[0];

                        do{
                            znak=tekst[pozycja];
   
                            if(znak==46){ilosc_zdan++;pozycja_nowa=0;}else{tablica[ilosc_zdan][pozycja_nowa]=znak;pozycja_nowa++;}
  
                            pozycja++;
                            
                            
                            }while(znak!='\0');
                            return 0;}


void wylicz_slowa(){
                    int znak;   
                    int pozycja=0;    
    
                    for(int i=0;i<ilosc_zdan;i++){
                                                    tablica_slow[i]=0; 
                                                    pozycja=0; 
     
                                                do{
            
                                                    znak=tablica[i][pozycja];
        
                                                    if(znak==32){tablica_slow[i]++;}
                                                    pozycja++;
                                                    }while(znak!='\0');
                                                    tablica_slow[i]++;}
    
    
    
    
}

int main(){
    
ilosc_zdan=0;
// przykladowy tekst wczytany z pliku (normalnie odczytujemy rozmiar, alokujemy pamiec i tam wczytujemy jego zawartosc)
strcpy(tekst,"Ala ma kota.Janusz ma psa.Heniek lubi kasztany jesienia.");


printf("%c%s%c\n\n",34,tekst,34);

wczytaj_zdania();
wylicz_slowa();

printf("ilosc zdan to %d\n",ilosc_zdan);


for(int i=0;i<ilosc_zdan;i++){
    
    printf("\nzdanie numer %d  to %c%s%c  ilosc slow w zdaniu to %d",i,34,tablica[i],34,tablica_slow[i]);}



return 0;}

Tutaj masz tekst w tablicy (którą w swojej wersji możesz zaalokować przez malloc i do niej wczytać plik).

Z tego co na to patrzę to już porobiłem zdania, i policzyłem słowa w nich.

Czyli już wiesz ile razy po zdaniu pętlą potrzebujesz po każdym zdaniu przejechać.

Czyli jedna pętla uruchomiona tyle razy ile jest zdań, druga wewnętrzna tyle razy ile jest słów.

Masz policzone słowa i zdania, to chyba już Ci pozwala na stworzenie tablicy wskaźników o określonej wielkości.
(właściwie to struktur, bo chcesz coś tam sobie policzyć).

Bo jak tworzysz listę to każdy węzeł to wskaźnik do następnego + wskaźnik na słowo + int na przechowanie rozmiaru.

Kopiuj
// o to mi dokładnie chodziło - a tutaj masz 16 bajtowe słowo tak?
struct  wordent
{       char    word[WORDLEN];
        int     count;
        struct  wordent *next;
};

Tutaj masz tylko wskaźnik na słowo + rozmiar.

Kopiuj
struct lista_slow{
            char* slowo; 
            int   ilosc;
            };

To już chyba połowa sukcesu.

Listy łączone są super, kiedy nie wiesz czego będziesz potrzebował.

Zaraz zaczną marudzić że po co to dzielić na zdania, ale np. analizie występowania określonych słów czasem potrzebny jest kontekst, tutaj już go masz, właśnie poprzez przechowanie zdan w tablicy.

Wtedy możesz do struktury dodać typ int do wskazania którego zdania dane słowo dotyczy.
(wskaźnik może lepiej żeby tworzyć tylko tablice które mają coś oznaczać)

To tylko jedna możliwość. Jest ich ogromna ilość.

Nie przejmuj się moją surową krytyką, pierwsze kroki w technikach masowej inwigilacji bywają trudne, a i ludzie na to jakoś niechętnie patrzą. Ważne się nie przejmować i wszystko zapisywać.

Dobra, wygrałeś, możesz na początku przejechać po pliku bez kopiowania zdań, po prostu wszystko policzyć i wtedy zaalokować tablicę zdań takimi wartościami jakie odczytasz.

Tam dalej, są już jedynie metody kompresji, ale je lepiej przećwicz oddzielnie.

Ostatnio pytałem kogoś na priv czy wie co potrzebuje pisać, ten się spytał 'w sensie?'.

Tutaj widzisz, że np. list się powinno uczyć na przykładach które są odpowiednie.

I tak jest ze wszystkim.

Wszystko co "właściwe" w C jest proste, przejrzyste, estetyczne.

Takie powinny być nazwy zmiennych, nazwy struktur, nazwy funkcji.

Im bardziej przejrzyście napisane, tym większe projekty można bezproblemowo wdrozyć.

Jak ktoś tego nie rozumie znaczy, że nie zna tego języka.


edytowany 11x, ostatnio: johnny_Be_good
AK
Toksyczny przykład
AK
I toksyczna ideologia
ZD
Życzę (obu) powodzenia z tym freelist przy 10tys elementów.
Alley Cat
  • Rejestracja:około 2 lata
  • Ostatnio:prawie 2 lata
0
johnny_Be_good napisał(a):

FILE *fp = stdin;

*fp?

Tak powinna wyglądać nazwa wg Ciebie?

Dobre nazwy, czego od niego chcesz?

FILE - nazwa standardowa
stdin - nazwa standardowa
fp - nazwa zgodna z powszechnie przyjętą konwencją

Jakbyś nie wiedział: * przed fp nie jest częścią nazwy zmiennej...


W Internecie nikt nie wie, że jesteś kotem.
JB
Czy czepiałem się FILE? *fp mi nie podpasowało. Czego od niego chcę? Poprosił o ocenę. A czego od niego mogę chcieć czy będę chciał to zależy już ode mnie. Jeszcze sam nie wiem. I od tego jak będzie reagował na moje sugestie. Czyli nie odbieram mu realnego wpływu na swoje życie, wolności wyboru, samo decydowania. Dzięki, że zadałeś to pytanie, zwykle działam na "czuja", tutaj mogłem się określić, upewniłem się, że wszystko jest tak jak ma być.
JB
I teraz przez to co napisałeś wyszedłeś na obrońcę uciśnionych a ja na tego złego. Zaraz pomyśli, że gramy w "dobrego i złego glinę" nie zaufa ani mi ani tobie. Myśl człowieku co robisz, bo jak piszesz obok to odpryski idą na mnie.
Alley Cat
Zaraz pomyśli, że gramy w "dobrego i złego glinę" XDDDDD
KS
  • Rejestracja:prawie 4 lata
  • Ostatnio:3 dni
  • Postów:581
0

Te rady w większości które Ci udzielono niestety nie są z tych najlepszych.

Masz tu najgłupsze rozwianie, tak.testujesz:

Kopiuj
./program < plik
wc -w < plik
Kopiuj
#include <stdio.h>
#include <string.h>

int main( void ) {
		
  size_t count = 0;
  char word[8192] = {0};
  while( scanf( "%8191s", word ) == 1  )  {

    count++;
    if( strlen( word ) == 8191u )
      perror( "too big word!!" );

  }
					
  if( ferror( stdin ))  printf( "scanf fail" );
  printf( "%zu\n", count );

  return 0;

}

Gdybyś np. chciał inaczej traktować pewne znaki to robisz swoją analizę na końcu pętli albo np innym programem.
Co może być lepsze bo Twój wyliczacz słów robi się wszechstronniejszy.

Kopiuj
tr -s  "'" ' ' < plik | ./program

pzdr.

edytowany 2x, ostatnio: Riddle
Riddle
@ksh: Pamiętaj żeby osadzać tekst wpisywany w konsoli w znaczniki ```.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)