FastReport w Usłudze - czy działa?

FastReport w Usłudze - czy działa?
LP
  • Rejestracja:prawie 15 lat
  • Ostatnio:prawie 7 lat
0

Witam,
Czy używał ktoś Fast Report w usłudze?
Napisałem program, który generuje plik PDF.
Gdy chcę go zastosować w usłudze, to niestety nie działa.
Pytanie czy jest to możliwe? Jeżeli tak to może potrzebne są jakieś biblioteki?
Ma ktoś w tym doświadczenie?
Program ponadto dodaje informacje o dacie do pliku.txt.
Mamy metodę wątku

Kopiuj
T_BezWatku.ServiceExecute(Sender: TService);

w której wywoływana jest metoda generująca plik PDF

Kopiuj
report.PreviewReport(1); --Parametr zbędny

oraz zapis daty do pliku *.txt

Kopiuj
 _BezWatku.InsertInFile;

Przy uruchomieniu usługi, data jest zapisywana cały czas do pliku, a plik PDF nie jest generowany.
PONADTO nie mogę wyłączyć usługi. Przy pierwszej próbie zatrzymania stan jest cały czas "Uruchomiony" a przy następnej otrzymuję bład.

screenshot-20171220152724.png

Jeżeli ktoś wie coś na temat używania FastReport w usłudze (Delphi) proszę o informację.

KOD:

Kopiuj
unit MyServiceGood;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
    ExtCtrls, DB, ADODB, DBTables,ActiveX, frxClass, frxExportPDF,frxDBSet,frxBarcode ;

type

  TReportEngine = class(TObject)
  private
    procedure detalAfterScroll(DataSet: TDataSet);
  protected
    _showProps:boolean;
    procedure setVisible(_obj:WideString;param:boolean);
    procedure setHeight(_obj:WideString;val:extended);
    procedure setTop(_obj:WideString;val:extended);
    function getWidth(_obj:WideString):extended;
    procedure ConfigurePropsForPrint(AName,ACaption,ADSName:WideString; RowIdx,ColIdx, MaxRowIdx,MaxColIdx: Integer);
  public
    constructor create();
    procedure PreviewReport(_id:integer);
  end;

  T_BezWatku = class(TService)
    ADOConnection1: TADOConnection;
    SaveDialog1: TSaveDialog;
    frxReport1: TfrxReport;
    StringDS: TfrxUserDataSet;
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceExecute(Sender: TService);
        procedure InsertInFile(info: String = '');
  private
      ADOConnection: TADOConnection;
     ADOQuery2: TADOQuery;
     ADOQuery3: TADOQuery;
     dsHeader: TfrxDBDataset;
     dsDetails: TfrxDBDataset;
     frMy: TfrxReport;
     frCodeBar: TfrxBarCodeObject;
     SaveDialog2: TSaveDialog;
     frxPDFExport1: TfrxPDFExport;
    { Private declarations }


  public
     ADOQuery: TADOQuery;
    report:TReportEngine;
    function GetServiceController: TServiceController; override;

    { Public declarations }
  end;



var
  _BezWatku: T_BezWatku;

implementation

uses UWMSreport,UDMFastReport;

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  _BezWatku.Controller(CtrlCode);
end;

function T_BezWatku.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;


procedure T_BezWatku.InsertInFile(info: String = '');
const
  FileName = 'C:\_Moje_Projekty\Usługa\_PrawdilowaBezWatku\Log.txt';
var
  F : TextFile;
begin
  try
    AssignFile(F, FileName);
    try
      if FileExists(FileName) then
        Append(F)
      else
        Rewrite(F);
        if info <> '' then

         Writeln(F, info, ' ', DiskFree(0))
        else
        Writeln(F, DateTimeToStr(Now), ' ', DiskFree(0));

    finally
      CloseFile(F);
    end;
  except
  end;
end;

procedure TReportEngine.detalAfterScroll(DataSet: TDataSet);
var
  _ds : TDataSet;
  a: string;
  b: Integer;
   frx:TFrxComponent;
begin
  _BezWatku.ADOQuery3.Close;
  _BezWatku.ADOQuery3.SQL.Clear;
  _BezWatku.ADOQuery3.SQL.Add('SELECT DO BAZY');

   _BezWatku.ADOQuery3.Open;
    _BezWatku.ADOQuery3.First;

    if (_BezWatku.ADOQuery3.RecordCount = 0) then
      Self.setVisible('DetailData1', false);

    while not _BezWatku.ADOQuery3.Eof do
    begin
              if _BezWatku.ADOQuery3.FieldByName('Visible').AsInteger = 1 then
          ConfigurePropsForPrint(
            _BezWatku.ADOQuery3.FieldByName('Name').AsWideString,
            _BezWatku.ADOQuery3.FieldByName('Caption').AsWideString,
            'WZDetails',
            _BezWatku.ADOQuery3.FieldByName('RowIdx').AsInteger,
            _BezWatku.ADOQuery3.FieldByName('ColIdx').AsInteger,
            _BezWatku.ADOQuery3.FieldByName('MaxRowIdx').AsInteger,
            _BezWatku.ADOQuery3.FieldByName('MaxColIdx').AsInteger
          );
      _BezWatku.ADOQuery3.Next;
    end;
end;

procedure TReportEngine.PreviewReport(_id:integer);
var
  LFileStream: TFileStream;
begin
  _BezWatku.frMy.PrepareReport();
    LFileStream := TFileStream.Create(_BezWatku.SaveDialog1.FileName + '.pdf', fmCreate or fmShareDenyNone);
       try
        _BezWatku.frxPDFExport1.Stream  := LFileStream;
      _BezWatku.frMy.Export(_BezWatku.frxPDFExport1)
    finally
      FreeAndNil(LFileStream);
      _BezWatku.frxPDFExport1.Stream := NIL;
    end;
end;





procedure TReportEngine.ConfigurePropsForPrint(AName, ACaption, ADSName: WideString; RowIdx,
  ColIdx, MaxRowIdx, MaxColIdx: Integer);
 var
    _lbl : TfrxMemoView;
    _frx : TFrxComponent;
    _lblWidth: extended;
    _lblHeight: extended;
    _BandPropsWidth: extended;
    _topEmptySpace: extended;
  begin
    _lbl:=nil;
    _frx:=_BezWatku.frMy.FindObject(AName);
    if _frx<>nil then
      _lbl:=(_frx as  TfrxMemoView);
    if _lbl=nil then exit;

    _lblWidth := 50 ;
    _lblHeight := 20;
    _BandPropsWidth := self.getWidth('DetailData1')-self.getWidth('Memo31');
    _topEmptySpace := 10;
    _lbl.Text := ACaption+': '+'['+ADSName+'."'+_lbl.datafield+'"]';
    _lbl.Top := (_topEmptySpace + (_lblHeight * RowIdx));
    _lbl.Left := ((_BandPropsWidth / (MaxColIdx+1)) * ColIdx)+10;
    _lbl.width := (_BandPropsWidth / (MaxColIdx+1));

    _lbl.Visible:=true;
    self.setHeight('DetailData1',_topEmptySpace + (_lblHeight * (MaxRowIdx+1)));
    self.setHeight('Memo39',_topEmptySpace + (_lblHeight * (MaxRowIdx+1)));
    self.setHeight('Line5',_topEmptySpace + (_lblHeight * (MaxRowIdx+1)));
    self.setTop('Line1',_topEmptySpace + (_lblHeight * (MaxRowIdx+1)));
end;


constructor TReportEngine.create();
var
  frFile:WideString;
begin
  frFile:='C:\_Moje_Projekty\Usługa\_PrawdilowaBezWatku\rwz.fr3';
  _BezWatku.frMy.LoadFromFile(frFile);
  _BezWatku.frxPDFExport1.filename:=_BezWatku.frMy.ReportOptions.Name;
  _BezWatku.ADOQuery2.AfterScroll:=detalAfterScroll;
end;




 procedure TReportEngine.setVisible(_obj: WideString; param: boolean);
var
  frx:TFrxComponent;
begin
  frx:=_BezWatku.frMy.FindObject(_obj);
  if frx<>nil then
    frx.Visible:=param;
end;

procedure TReportEngine.setHeight(_obj: WideString; val: extended);
var
  frx:TFrxComponent;
begin
  frx:=_BezWatku.frMy.FindObject(_obj);
  if frx<>nil then
    frx.Height:=val;
end;

procedure TReportEngine.setTop(_obj: WideString; val: extended);
var
  frx:TFrxComponent;
begin
  frx:=_BezWatku.frMy.FindObject(_obj);
  if frx<>nil then
    frx.top:=val;
end;

 function TReportEngine.getWidth(_obj: WideString): extended;
var
  frx:TFrxComponent;
begin
  result:=0;
  frx:=_BezWatku.frMy.FindObject(_obj);
  if frx<>nil then
    result:=frx.Width;
end;
procedure T_BezWatku.ServiceStart(Sender: TService; var Started: Boolean);
const
  SQLStr ='SELECT DO BAZY';
    SQLStr2 ='SELECT DO BAZY';
begin
 CoInitialize(nil);
  try
    ADOconnection:=TADOConnection.Create(Nil);
    ADOconnection.ConnectionString :='STRING DO BAZY';
    ADOconnection.LoginPrompt := False;
    ADOQuery:=TADOQuery.Create(Nil);
    ADOQuery.Connection:=ADOConnection;
    fReportdm.ADOConnection1.ConnectionString :='STRING DO BAZY';
    ADOQuery.SQL.Text := SQLStr;


        ADOconnection:=TADOConnection.Create(Nil);
    ADOconnection.ConnectionString :='STRING DO BAZY';
    ADOconnection.LoginPrompt := False;
    ADOQuery:=TADOQuery.Create(Nil);
    ADOQuery.Connection:=ADOConnection;
    ADOQuery.SQL.Text := SQLStr;

    ADOQuery2:=TADOQuery.Create(Nil);
    ADOQuery2.Connection:=ADOConnection;
    ADOQuery2.SQL.Text := SQLStr2;

    ADOQuery3:=TADOQuery.Create(Nil);
    ADOQuery3.Connection:=ADOConnection;

    dsHeader := TfrxDBDataset.Create(nil);
   dsHeader.UserName := 'Header';
   dsHeader.CloseDataSource := False ;
   dsHeader.DataSet := ADOQuery;
   dsHeader. BCDToCurrency := False ;

  dsDetails :=  TfrxDBDataset.Create(NIL);
  dsDetails.UserName := 'Details';
  dsDetails.CloseDataSource := False;
  dsDetails.DataSet := ADOQuery2;
  dsDetails.BCDToCurrency := False;

  frMy := TfrxReport.Create(Nil);
  frMy.Version := '4.13.2';
  frMy.DotMatrixReport := False;
  frMy.IniFile := '\Software\Fast Reports';
  frMy.PreviewOptions.Buttons := [pbPrint, pbLoad, pbSave, pbExport, pbZoom, pbFind, pbOutline, pbPageSetup, pbTools, pbEdit, pbNavigator, pbExportQuick];
  frMy.PreviewOptions.Modal := False;
  frMy.PreviewOptions.Zoom := 1.000000000000000000;
  frMy.PrintOptions.Printer := 'Default';
  frMy.PrintOptions.PrintOnSheet := 0;
  frMy.ReportOptions.CreateDate := 42030.347937847200000000;
  frMy.ReportOptions.Name := 'WWW';
  frMy.ReportOptions.LastChange := 43089.560934537040000000;
  frMy.ScriptLanguage := 'PascalScript';



  frxPDFExport1 := TfrxPDFExport.Create(NIL);
  frxPDFExport1.UseFileCache := True;
  frxPDFExport1.ShowProgress := True;
  frxPDFExport1.OverwritePrompt := False;
  frxPDFExport1.DataOnly := False;
  frxPDFExport1.PrintOptimized := False;
  frxPDFExport1.Outline := False;
  frxPDFExport1.Background := False;
  frxPDFExport1.HTMLTags := True;
  frxPDFExport1.Quality := 95;
  frxPDFExport1.Title := 'WWW';
  frxPDFExport1.Author := 'FastReport';
  frxPDFExport1.Subject := 'FastReport PDF export';
  frxPDFExport1.ProtectionFlags := [ePrint, eModify, eCopy, eAnnot];
  frxPDFExport1.HideToolbar := False;
  frxPDFExport1.HideMenubar := False;
  frxPDFExport1.HideWindowUI := False;
  frxPDFExport1.FitWindow := False;
  frxPDFExport1.CenterWindow := False;
  frxPDFExport1.PrintScaling := False;


  SaveDialog2:= TSaveDialog.Create(NIL);
  SaveDialog2.DefaultExt := '*.PDF';
  SaveDialog2.FileName := 'TEST';
  SaveDialog2.Filter := 'PDF files|*.PDF';
  SaveDialog2.InitialDir := 'C:\_Moje_Projekty\Usługa\_PrawdilowaBezWatku';
             report:=TReportEngine.create();
  except
   on E: Exception do
    _BezWatku.InsertInFile(E.Message);

  end;
end;

procedure T_BezWatku.ServiceExecute(Sender: TService);

begin
  while not Terminated do
  Begin
      try
        ADOConnection1.Connected := True;
        ADOQuery.Active := True;
        ADOQuery.Open;

        report.PreviewReport(1);
      except
       on E: Exception do
        _BezWatku.InsertInFile(E.Message);
      end;

    _BezWatku.InsertInFile;
    ServiceThread.ProcessRequests(False);
    Sleep(100000);
  End;
end;

end.


edytowany 1x, ostatnio: lukasz_p92
0

Tu nie chodzi o wyświetlanie z FastReport, ale o wyświetlanie w ogóle. W bardzo dużym uproszczeniu service nie wyświetla na ekranie, który widzisz. Wyświetl sobie jakąś formę czy np ShowMessage. I przeczytaj np to: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683502(v=vs.85).aspx

edytowany 1x, ostatnio: flowCRANE
LA
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 14 godzin
  • Postów:470
0

paskudny kod, nie chce mi sie go w calosci analizowac, ale w usludze wystrzegaj sie wyswietlania czegokolwiek, np. masz tam przy eksporcie frxPDFExport1.ShowProgress := True; co pewnie chce pokazac jakis progresbar itp itd.
Nie wiem też co tam robi SaveDialog etc

LP
Paskudny bo na szybko przenoszony z działającej aplikacji (+ tworzę dynamicznie komponenty co jest zalecane w usłudze), która nic nie wyświetla a zapisuje raport do pliku.
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 10 godzin
0

@Sadam2, @lampasss
Generalnie zgoda, usługi nie powinny nić wyrzucać na ekran.
Ale technicznie jest to możliwe, o ile zezwoli się usłudze na interakcję z pulpitem.
Nie mam pewności czy taka interakcja zadziała jeśli usługa działa na koncie "SYSTEM".

LA
taa, jak na XP to ok.
GS
@lampasss: z XP masz rację. W dawnych czasach Windowsa XP napisałem coś takiego jak usługa z interakcją z pulpitem, ale to nie było dobre rozwiązanie. W nowszych systemach nawet nie próbowałem stosować tego rozwiązania ponieważ zrezygnowałem z jakiejkolwiek interakcji usługi z pulpitem
0
grzegorz_so napisał(a):

@Sadam2
Generalnie zgoda, usługi nie powinny nić wyrzucać na ekran.

Przecież napisałem "w dużym uproszczeniu". Oczywiście, że z usługi można wyświetlać. Ale pytacz powinien sobie więcej poczytać. To "więcej" też w uproszczeniu :-).

LP
  • Rejestracja:prawie 15 lat
  • Ostatnio:prawie 7 lat
0

@Sadam2 @lampasss @grzegorz_so
Ale ja nie chce wyświetlać raportu.
Ja chcę aby usługa mi go tylko zapisywała do pliku *.PDF.
I tak on działą, lecz nie w usłudze.

woolfik
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 10 godzin
  • Postów:1595
0

Nie testowałem tego ale jak Ci się uda to pochwal się na formum bo sam mam gdzieś to na liście "todo" ;)
Gdyby Ci się jednak nie udało to zrób sobie apkę działającą w tray'y i ustaw ją na autostart ;)

JU
  • Rejestracja:około 22 lata
  • Ostatnio:około miesiąc
  • Postów:5042
0
lukasz_p92 napisał(a):

@Sadam2 @lampasss @grzegorz_so
Ale ja nie chce wyświetlać raportu.

To przeczytaj, co dokładnie robi metoda PreviewReport.
To, co chcesz a to, co robisz, to dwie różne sprawy. I tak, jak Ci pisali - usługa nie może wyświetlać GUI, a PreviewReport chce pokazać gui.

Po prawdzie, można zmusić usługę do wyświetlenia GUI (przynajmniej na Windows 7), ale to nie do końca działa i jest mocno upierdliwe.

LP
  • Rejestracja:prawie 15 lat
  • Ostatnio:prawie 7 lat
0
Juhas napisał(a):
lukasz_p92 napisał(a):

@Sadam2 @lampasss @grzegorz_so
Ale ja nie chce wyświetlać raportu.

To przeczytaj, co dokładnie robi metoda PreviewReport.
To, co chcesz a to, co robisz, to dwie różne sprawy. I tak, jak Ci pisali - usługa nie może wyświetlać GUI, a PreviewReport chce pokazać gui.

Po prawdzie, można zmusić usługę do wyświetlenia GUI (przynajmniej na Windows 7), ale to nie do końca działa i jest mocno upierdliwe.

O czym ty mówisz... o procedurze którą sam napisałem i ją tak nazwałem? Chyba coś Ci się pomyliło z jakąś systemową metodą, bo MOJA procedura PreviewReport tylko buduje raport i go eksportuje jako PDF, bez ŻADNEGO wyświetlania zawartości...

@woolfik
Jak na razie udało mi się uruchamiać usługę i ja zatrzymywać beż żadnego błędu.
Musiałem wyłączyć możliwość używania globalnego Dataset

Kopiuj
frMy.EngineOptions.UseGlobalDataSetList := False;

Niestety raport dalej nie jest tworzony. Jeżeli uda mi się wygenerować taki raport, dam znać.

woolfik
Chłopaki chyba mówią o TfrxRaport.PreviewReport (to faktycznie wyświetla raport), a ty o TReportEngine.PreviewReport(_id:integer) czyli Twojej procedurze ;)
woolfik
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 10 godzin
  • Postów:1595
1

Weź jeszcze jedną rzecz pod uwagę ... w przypadku jakiegoś błędu przy generowaniu lub "przygotowywaniu" raportu FR ma swoją własną obsługę błędów (wyskakujące okienka). Niestety w usłudze może to powodować problem i wywalać usługę całkowicie. Jest natomiast któraś metoda (nie pamiętam nazwy), która powoduje "wyciszenie" wyjątków i np zrzut do loga. Weź to pod uwagę przy końcowej wersji ;)

LP
  • Rejestracja:prawie 15 lat
  • Ostatnio:prawie 7 lat
1

Udało się napisać usługę która to realizuje. I jak już wspomniałem, usługa nic nie wyświetlała a tylko tworzyła i zapisywała plik w formacie PDF. ;)

@woolfik
Muszę poprawić kod i podeślę.

Dzięki chłopaki za odzew, zawsze co "dwie" głowy to nie jedna :)

edytowany 1x, ostatnio: lukasz_p92
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)