Powiązania pomiędzy modułami

Powiązania pomiędzy modułami
AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 godziny
  • Postów:973
0

Jak zrobić żeby moduły nie były zbyt powiązane ze sobą np. w takim przypadku:

moduł Track
moduł Playlist

Playlista zawiera Track itd.

Mamy funkcję w module Track do pobierania Tracku ale potrzebujemy na tym etapie danych z Playlisty (np. czy track znajduje się w danej Playliscie, jej nazwę itd).
Przekazanie danych w funkcji (jako argumenty) odpada bo skoro Playlista jest typowana to chcielibyśmy to wykorzystać. A chcielibyśmy też uniknąć importowania Playlist na Track...

I jak tu żyć


Zdalna praca dla Senior Python Developerów --> PW
edytowany 1x, ostatnio: anonimowy
opiszon
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 godziny
  • Postów:779
3

Dlaczego track potrzebuje danych z playlisty?

Dane nt playlisty czytasz z playlisty, dane nt track czytasz z track.

Przecież 1 track może należeć do N playlist.

AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 godziny
  • Postów:973
0

@opiszon no po prostu wymaganie biznesowe żeby np. do metadanych dodać dane z playlist


Zdalna praca dla Senior Python Developerów --> PW
CosherJeepersCreepers
wstrzyknik sobie polityki playlist do domeny tracka i czytaj
AN
No tak ale to wtedy Track jest powiązany z Playlist (nie skasuję modułu Playlist bez modyfikacji Track w takim wypadku)
KR
  • Rejestracja:około 3 lata
  • Ostatnio:25 dni
  • Postów:53
1

Przekazanie danych w funkcji (jako argumenty) odpada bo skoro Playlista jest typowana to chcielibyśmy to wykorzystać. A chcielibyśmy też uniknąć importowania Playlist na Track...

Wprowadź strukturę danych TrackOutsideInfo, którą uzupełnisz danymi z Playlisty i zaimportujesz w obu klasach.

AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 godziny
  • Postów:973
0

@Krzemień O i takie podejście mi się podoba. W taki sposób w przyszłości mogę skasować moduł Playlist a moduł Track nadal pozostanie bez zmian i żadnych importów z Playlist.

Te moduły to tylko przykłady, chodzi mi o ogólne podejście i takie miałoby sens imo

A co jeśli chciałbym zrobić coś dla każdego Tracku jeśli coś w Playliście się zmieni? Do głowy przychodzi mi np. wysłanie sygnału to teortycznie też nie będzie powiązania


Zdalna praca dla Senior Python Developerów --> PW
edytowany 1x, ostatnio: anonimowy
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:minuta
  • Postów:4881
0

Jeśli te moduły są powiązane i tak, to może zrób je częścią jednej logiki - jakiegoś interfejsu, klasy?


AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 godziny
  • Postów:973
0

@lion137 tzn chodzi Ci o połączenie tego w jeden moduł? To jest tylko przykład ale bardzo często jednak logika biznesowa się przenika, rzadko jest tak, że jest sobie odrębny moduł nie powiązany z niczym


Zdalna praca dla Senior Python Developerów --> PW
Riddle
Administrator
  • Rejestracja:ponad 14 lat
  • Ostatnio:minuta
  • Lokalizacja:Laska, z Polski
  • Postów:10035
2
anonimowy napisał(a):

Jak zrobić żeby moduły nie były zbyt powiązane ze sobą np. w takim przypadku:

moduł Track
moduł Playlist

Playlista zawiera Track itd.

Mamy funkcję w module Track do pobierania Tracku ale potrzebujemy na tym etapie danych z Playlisty (np. czy track znajduje się w danej Playliscie, jej nazwę itd).
Przekazanie danych w funkcji (jako argumenty) odpada bo skoro Playlista jest typowana to chcielibyśmy to wykorzystać. A chcielibyśmy też uniknąć importowania Playlist na Track...

Na pierwszy rzut oka to wygląda jak jeden moduł, ja bym go raczej nie rozdzielał. Wygląda że playlista nie ma sensu bez track. Jesteś pewien że Track i Playlist to są moduły? Może łatwiej byłoby o nich myśleć jak o terminach biznesowych? 🤔

No ale jeśli koniecznie chcesz je rozdzielić, to należy położyć pomiędzy nimi jakąś warstwę - np. to co proponuje @Krzemień, z przekazywaną dodatkowa strukturą. Tylko pytanie co w zasadzie chcesz osiągnąć tym rozdzieleniem? Chcesz używać tracków bez playlisty? Playlisty bez tracków (to chyba nie ma sensu)? Chcesz móc podmienić implementacje Tracków lub playlisty na inne? Bo jesli chcesz wprowadzić rozdzielenie modułów tylko po to żeby było albo "że tak trzeba", to raczej ja bym poczekał z tym.

AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 godziny
  • Postów:973
1

@Riddle dzięki, na Ciebie czekałem (serio :P)

Ogólnie chodzi o to, że Playlist czy Track to rozbudowane rzeczy w gruncie rzeczy. Są w pewien sposób ze sobą powiązane ale czy muszą?

Playlista ma mały sens bez Track - tu się zgadzam - większość, rzeczy w Playlist jest oparte na Track - z tym, że Track mógłby istnieć bez Playlist więc dlaczego z poziomu Track wiązać go z Playlist?

Tracki mają wiele różnych implementacji i działają bez Playlist, Playlista to tylko takie "rozszerzenie" funkcjonalności aplikacji. Po części zgadzam się, że chcę to zrobić "bo tak trzeba" ale też z tego względu, że mam złe doświadczenie z bardzo rozrośniętymi modułami i szukam sposobu na pogrupowanie tego


Zdalna praca dla Senior Python Developerów --> PW
HS
  • Rejestracja:10 miesięcy
  • Ostatnio:około 18 godzin
  • Postów:74
0

@anonimowy zrob totalny decouple modulow, a komunikacje miedzy modulami zepnij event'ami na jakims service/app event bus'ie.

Riddle
Administrator
  • Rejestracja:ponad 14 lat
  • Ostatnio:minuta
  • Lokalizacja:Laska, z Polski
  • Postów:10035
1
anonimowy napisał(a):

@Riddle dzięki, na Ciebie czekałem (serio :P)

Ogólnie chodzi o to, że Playlist czy Track to rozbudowane rzeczy w gruncie rzeczy. Są w pewien sposób ze sobą powiązane ale czy muszą?

Playlista ma mały sens bez Track - tu się zgadzam - większość, rzeczy w Playlist jest oparte na Track - z tym, że Track mógłby istnieć bez Playlist więc dlaczego z poziomu Track wiązać go z Playlist?

Tracki mają wiele różnych implementacji i działają bez Playlist, Playlista to tylko takie "rozszerzenie" funkcjonalności aplikacji. Po części zgadzam się, że chcę to zrobić "bo tak trzeba" ale też z tego względu, że mam złe doświadczenie z bardzo rozrośniętymi modułami i szukam sposobu na pogrupowanie tego

Rozumiem. Czyli track może być bez playlisty, ale może też ją mieć; chcemy uniezależnić track od playlisty, ale track chce mieć takie informacje jak czy nazwa playlisty w której się znajduje.

(np. czy track znajduje się w danej Playliscie, jej nazwę itd).

Ja w takim wypadku poleciłbym Ci wymyślenie nowego słowa, nowego konceptu które mogłoby być między playlistą a trackiem. Dobrze byłoby wymylić jakieś słowo/koncept żeby to określić. To może być nazwa w stylu: catalog, playlistItem, collection, tracklist, lineup, album, etc. Wtedy byłaby relacja:

Kopiuj
track -> PlaylistItem <- playlist

Taki PlaylistItem mógłby wyglądać np. tak: interface PlaylistItem { bool hasPlaylist; ?string playlistName; ?string playlistAuthor; string[] otherPlaylistsWithTrack }. Track mógłby zależeć od PlaylistItem - z niego brałby info w jakiej playliście jest i jak się nazywa ta playlista; a playlista dostarczałaby info o sobie i swojej nazwie do playlistItem. W wypadku tracku który nie jest w playlisćie, track mógłby dostać PlaylistItem który ma hasPlaylist=false a pozostałe atrybuty np. null albo pusty.

Oczywiście pola możesz zaprojektować do woli. W skrócie - wszystkie dane które mają "przejść" między playlistą a trackiem, wsadź do tego obiektu.

Tak na prawdę nie ma złotego środka na ten problem - wymaga to po prostu zaprojektowania relacji między elementami które masz 😊

edytowany 1x, ostatnio: Riddle
HS
  • Rejestracja:10 miesięcy
  • Ostatnio:około 18 godzin
  • Postów:74
1

@Riddle w EU lekarstwem na nadmiar regulacji jest jeszcze wiecej regulacji.
W zasadzie okreslanie czegokolwiek modulem, co nie jest w pelni izolowane od reszty kodu jest bledem.
Ty proponujesz rozwiazanie ktore dodaje tylko dodatkowa abstrakcje, ktora trywialny problem de facto jeszcze bardziej komplikuje.

Ludziska wykorzystuja eventy na potege wewnatrz spojnego funkcjonalnie kodu (ktory ich nie potrzebuje) zwlaszcza i to nagminnie w symfony, a o przypadku tak oczywistym jak separowane moduly i komunikacja miedzy nimi (dla ktorych eventy sa wrecz stworzone) nawet nikt nie pomysli.

edytowany 1x, ostatnio: hyper-stack
loza_prowizoryczna
  • Rejestracja:ponad 2 lata
  • Ostatnio:dzień
  • Postów:1583
0
hyper-stack napisał(a):

@Riddle w EU lekarstwem na nadmiar regulacji jest jeszcze wiecej regulacji.
W zasadzie okreslanie czegokolwiek modulem, co nie jest w pelni izolowane od reszty kodu jest bledem.

W kontekście Pythona modułem jest wszystko co jest napisane w innym języku niż Python (bo musi działać wydajnie) i posiada eksporty dla Pythona. I wtedy to ma sens.

Wszystko inne co ma w nazwie moduł i jest pisane w tym samym języku powstało jak odpowiedź na odwieczny problem monolitu - skoro wszystko jest w tym samym języku ale mamy wiele zespołów to jak poradzić sobie z problemami konfliktu nazw/symboli/whatever?

Przykład analogiczny - skoro monorepo pozwala na łatwe współdzielenie kodu to dlaczego git się słabo sprawdza w tym modelu (i dlaczego git-submodules posysają po całości). Ten sam problem w innym opakowaniu.


Przetrzyma wszystko
RequiredNickname
Czy ty właśnie napisałeś, że enkapsulacja to próba rozwiązania problemu przestrzeni nazw?
loza_prowizoryczna
Przestrzeń nazw to już wyższy level abstrakcji. Nawet w matematyce niekiedy zaczyna brakować liter z różnych alfabetów. W IT zaczyna brakować słów.
HS
  • Rejestracja:10 miesięcy
  • Ostatnio:około 18 godzin
  • Postów:74
0
loza_prowizoryczna napisał(a):

W kontekście Pythona modułem jest wszystko co jest napisane w innym języku niż Python (bo musi działać wydajnie) i posiada eksporty dla Pythona. I wtedy to ma sens.

W kontekscie izolacji, o ktorej pisalem, zalozenie jak najbardziej sluszne, natomiast patrzac na to bardziej ogolnie cos takiego jest po prostu osobny serwisem.

loza_prowizoryczna napisał(a)

Wszystko inne co ma w nazwie moduł i jest pisane w tym samym języku powstało jak odpowiedź na odwieczny problem monolitu - skoro wszystko jest w tym samym języku ale mamy wiele zespołów to jak poradzić sobie z problemami konfliktu nazw/symboli/whatever?

Mozliwe ze w python'ie stanowi to jakies wyzwanie, natomiast w przypadku php (w ktorym ja przede wszystkim kodze) nie stanowi to w sumie zadnego problemu. Przykladowa struktura projektu monolitu:

Kopiuj
my-app
  *src
    *Controller
      - MyController.php 
- server.php

Hula sobie na trywialnym namespace'ie:

Kopiuj
"App\\": "src"

Przeksztalcenie tego w modularny monolit wyglada tak:

Kopiuj
my-app
  *src
    *Controller
      - MyController
  *Modul1
    *src
      *Controller
        - Controller1.php
  *Modul2
    *src
      *Controller
        - Controller2.php 
- server.php

Na rownie banalnych namespace'ach:

Kopiuj
"App\\": "src"
"Module1\\": "Module1/src"
"Module2\\": "Module1/src"

W razie koniecznosci calkowitej izolacji, jednego lub wszystkich modulow (powod dowolny), moduly na zasadzie cut & paste moga stac sie:

  • albo rozwijanymi w osobnych repozytoriach bibiliotekami ladowanymi composer'em do glownego projektu ktory de facto staje sie wylacznie rama
  • albo rozwijanymi w osobnych repozytoriach servisami
loza_prowizoryczna napisał(a)

Przykład analogiczny - skoro monorepo pozwala na łatwe współdzielenie kodu to dlaczego git się słabo sprawdza w tym modelu (i dlaczego git-submodules posysają po całości). Ten sam problem w innym opakowaniu.

W tej kwestii, dla przypadku php wypowiedzialem sie powyzej i jak widzisz nie mieszamy w to git-submodules.

Na koniec dodam tylko, ze od juz od jakiegos czasu, moj zespol pracuje w ten sposob i wyglada to tak ze w przypadku jesli modul jest po prostu dopinany do ramy jako biblioteka:

  • deployment ogranicza sie wylacznie do modulow, bez masakry mielenia calej kobylastej aplikacji/platformy przy kazdym release'ie
  • spinanie modulu z aplikacja (wlasciwie jej rama) ogranicza sie do jednego polecenia update wersji modulu composer update
  • pracuje sie wygodnie na hermetycznych zakresach kodu, bo kazdy modul/paczka to osobna biblioteka w swoim wlasnym repozytorium
  • a zlecajac komukolwiek z zewnatrz jakas robote nie jestes zmuszony dawac dostepow do calego kodu aplikacji/platformy
loza_prowizoryczna
  • Rejestracja:ponad 2 lata
  • Ostatnio:dzień
  • Postów:1583
0
hyper-stack napisał(a):

W kontekscie izolacji, o ktorej pisalem, zalozenie jak najbardziej sluszne, natomiast patrzac na to bardziej ogolnie cos takiego jest po prostu osobny serwisem.

To nie ma znaczenia czy moduł nazwiesz serwisem, usługą czy procesem. Wszystko to pochodna tego że większość projektów ma flow Ulissesa Joyce'a a ty zachowujesz się jak krytyk literacki i dopatrujesz się powiązań znaczeniowych w obrębie rozdziałów.

Mozliwe ze w python'ie stanowi to jakies wyzwanie, natomiast w przypadku php (w ktorym ja przede wszystkim kodze) nie stanowi to w sumie zadnego problemu. Przykladowa struktura projektu monolitu:
(...)
W razie koniecznosci calkowitej izolacji, jednego lub wszystkich modulow (powod dowolny), moduly na zasadzie cut & paste moga stac sie:

  • albo rozwijanymi w osobnych repozytoriach bibiliotekami ladowanymi composer'em do glownego projektu ktory de facto staje sie wylacznie rama
  • albo rozwijanymi w osobnych repozytoriach servisami

Dobra, dobra, nie czarujmy się - wszystko sprowadza się do tego czy potrzebujesz w pliku import czy też nie. Resztę wydelegujesz na jakiś menedżer pakietów w którym bezpiecznie będzie można robić burdel (bo wszystkie menedżery do tego tak naprawdę służą).

Na koniec dodam tylko, ze od juz od jakiegos czasu, moj zespol pracuje w ten sposob i wyglada to tak ze w przypadku jesli modul jest po prostu dopinany do ramy jako biblioteka:

  • deployment ogranicza sie wylacznie do modulow, bez masakry mielenia calej kobylastej aplikacji/platformy przy kazdym release'ie
  • spinanie modulu z aplikacja (wlasciwie jej rama) ogranicza sie do jednego polecenia update wersji modulu composer update
  • pracuje sie wygodnie na hermetycznych zakresach kodu, bo kazdy modul/paczka to osobna biblioteka w swoim wlasnym repozytorium
  • a zlecajac komukolwiek z zewnatrz jakas robote nie jestes zmuszony dawac dostepow do calego kodu aplikacji/platformy

Jak widzisz to co robisz to tylko delegacja burdelu wyżej.


Przetrzyma wszystko
HS
  • Rejestracja:10 miesięcy
  • Ostatnio:około 18 godzin
  • Postów:74
0
loza_prowizoryczna napisał(a):

To nie ma znaczenia czy moduł nazwiesz serwisem, usługą czy procesem. Wszystko to pochodna tego że większość projektów ma flow Ulissesa Joyce'a a ty zachowujesz się jak krytyk literacki i dopatrujesz się powiązań znaczeniowych w obrębie rozdziałów.

O czym ty czlowieku "do mnie rozmawiasz"?

loza_prowizoryczna napisał(a):

Dobra, dobra, nie czarujmy się - wszystko sprowadza się do tego czy potrzebujesz w pliku import czy też nie. Resztę wydelegujesz na jakiś menedżer pakietów w którym bezpiecznie będzie można robić burdel (bo wszystkie menedżery do tego tak naprawdę służą).

loza_prowizoryczna napisał(a):

Jak widzisz to co robisz to tylko delegacja burdelu wyżej.

Moge ci tylko wspolczuc przezytych traum i zyczyc szybkiego powrotu do zdrowia.

loza_prowizoryczna
  • Rejestracja:ponad 2 lata
  • Ostatnio:dzień
  • Postów:1583
1
hyper-stack napisał(a):

O czym ty czlowieku "do mnie rozmawiasz"?

O tym że idea modularyzacji i izolacji to koncept fajny na papierze ale w dużych projektach jego całość sprowadza się do tego że zamiast zastanawiać się jak prefiksować nazwy funkcji i struktur wszystko sprowadza się do tego że srasz importami w nagłówkach i aliasujesz skonfliktowane przestrzenie nazw licząc na to że kompilator/interpreter/vm domyśli się reszty.

A powiązania między modułami najlepiej śledzić w dojrzałych menedżerach pakietów np. npm gdzie już chyba stosują heurystyki oparte o AI żeby wykryć cykle w grafie powiązań i rozwiązać ten bigos.

Moge ci tylko wspolczuc przezytych traum i zyczyc szybkiego powrotu do zdrowia.

Ty nie współczuj tylko przyjrzyj się współczesnym menedżerom pakietów bo to one dostarczają rozwiązań na problem wspomniany w tytule wątku.


Przetrzyma wszystko
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 2 godziny
  • Postów:2363
1

Moje 0.02 PLN.

Staram się myśleć w terminach: komponent, interfejs komponentu, dane wymieniane przez interfejs. Są to terminy które sprawdzają się dobrze zarówno na poziomie kodu jak i architektury, nie są przywiązane do metodyki wytwórczej czy technologii.

Po co wywołujemy jakiś komponent? Zapewne, żeby zrealizować przypadek użycia. Niektóry z nich mogą być proste, inne wymagają nieco więcej pracy i wywołania kilku komponentów, pożenienia rezultatów. Jak to się ma do Track i Playlisty? Ano tak, że można przypadek użycia można zaimplementować jako osobną klasę/funkcję/serwis/etc. która będzie miała uchwyty (referencja do obiektu, czy port do komunikacji z komponentem) do Track i Playlisty i logikę zaszytą wewnątrz, np. klasa/funkcja AktualizujMetadane(modTrack, modPlaylist) ).

Wracając do pytania, Jak zrobić, żeby moduły nie były ze sobą powiązane? Dla każdego modułu zdefiniować interfejs(y) modułu, dane wejściowe interfejsu i dane wyjściowe. Co zrobić w przypadku Track i Playlisty? Nie mam pojęcia, nie wiem jaki problem rozwiązują :-)

HS
  • Rejestracja:10 miesięcy
  • Ostatnio:około 18 godzin
  • Postów:74
0
loza_prowizoryczna napisał(a):

O tym że idea modularyzacji i izolacji to koncept fajny na papierze ale w dużych projektach jego całość sprowadza się do tego że zamiast zastanawiać się jak prefiksować nazwy funkcji i struktur wszystko sprowadza się do tego że srasz importami w nagłówkach i aliasujesz skonfliktowane przestrzenie nazw licząc na to że kompilator/interpreter/vm domyśli się reszty.

Dobrze, to inaczej, co ty czlowieku p...olisz? W czym ty kodzisz? W Basic'u na ZX-Spectrum?

edytowany 1x, ostatnio: hyper-stack
loza_prowizoryczna
  • Rejestracja:ponad 2 lata
  • Ostatnio:dzień
  • Postów:1583
0
hyper-stack napisał(a):

Dobrze, to inaczej, co ty czlowieku p...olisz? W czym ty kodzisz? W Basic'u na ZX-Spectrum?

Basic C64. I jak kodziłem to pamiętam głównie komendę run.


Przetrzyma wszystko
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)