Applet Java i biblioteki DLL

Applet Java i biblioteki DLL
0

Witam serdecznie.

Piszę właśnie mój pierwszy applet i oczywiście natrafiłem na problem.

Zadaniem appletu jest odczytanie z dysku użytkownika wybranego pliku, sprawdzenie czy jest plikiem video jednego z obsługiwanych typów i wyciągnięcie z niego tzw. Metadata czyli informacji nagłówkowych tj.: długość, rozdzielczość, fps.

Applet korzysta z biblioteki Mediainfo.dll i wrapperów java na nią tj.: MediaInfo.java oraz MediaInfoLibrary.java.

Applet jest self-signed wiec powinien po zatwierdzeniu wyjątków bezpieczeństwa przez użytkownika mieć prawa odczytu jego plików. Z tego co udało mi się wyczytać w internecie applet nie może skorzystać z biblioteki Mediainfo.dll zawartej bezpośrednio z pliku jar lub gdziekolwiek na zdalnym serwerze tylko musi ją umieścić w windows/system32 na maszynie użytkownika. Nie mam tego jeszcze w programie, ale żeby sprawdzić czy to ma sens ręcznie umieściłem bibliotekę w tym folderze, ale applet nadal nie działa. (póki był uruchamiany z eclipse jako java applet lokalnie wszystko działało i program robił co ma robić, tylko po wrzuceniu na serwer pojawiły się problemy).

Pomoże ktoś mi to ogarnąć? Nie mam w javie jeszcze takiego doświadczenia, żeby samemu rozwiązać ten problem.

Z góry dziękuję za ewentualne porady i pomoc. Pozdrawiam i załączam poniżej kod appletu oraz .jar spakowany rarem zawierający wszystkie pliki.
Działanie (lub raczej niedziałanie) appletu można obejrzeć tutaj: http://con3x.com/java/

Kopiuj
package video_inspector;

import java.applet.Applet;
import java.io.File;
import java.util.Arrays;
import java.awt.*;
import javax.swing.JOptionPane;
public class video_inspector extends Applet {
	private static final long serialVersionUID = 1L;
	static String[] allowed = {"avi", "mp4", "3gp", "mkv", "ogm", "rmvb", "rm", "mpeg", "mpg", "mpe", "mov", "qt", "wmv"};
	File f;
	public void init() {
        FileDialog fc = new FileDialog(new Frame(), "Wybierz plik wideo");
        fc.setVisible(true);
        fc.setMode(FileDialog.LOAD);
        String selectedFile = fc.getFile();
        String dir = fc.getDirectory();
        if(new File(dir+selectedFile).exists()) {
	        try {
	        	f = new File(dir+selectedFile);
	        	String mimetype = selectedFile.substring(selectedFile.lastIndexOf('.') +1);
        		if(Arrays.asList(allowed).contains(mimetype)) {
		        	MediaInfo info       = new MediaInfo();
		        	info.open(f);
		        	long length = 		f.length();
		        	//String format        = info.get(MediaInfo.StreamKind.Video, 0, "Format", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String duration      = info.get(MediaInfo.StreamKind.Video, 0, "Duration", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String frameRate     = info.get(MediaInfo.StreamKind.Video, 0, "FrameRate", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String width         = info.get(MediaInfo.StreamKind.Video, 0, "Width", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	String height        = info.get(MediaInfo.StreamKind.Video, 0, "Height", MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
		        	long seconds 		 = Long.parseLong(duration)/1000;
		            String formatx 		 = String.format("%%0%dd", 2);
		            String time			 = String.format(formatx, seconds/3600)+":"+String.format(formatx, (seconds%3600)/60)+":"+String.format(formatx, seconds%60);
		        	//System.out.println("Format: "+format);
		        	System.out.println("Filesize: "+length+" Bytes");
		        	System.out.println("Duration: "+time);
		        	System.out.println("FPS: "+frameRate);
		        	System.out.println("Resolution: "+width+"x"+height);
        		} else {
        			error("Nieprawidłowy format pliku! Tylko pliki wideo!");
        		}
	        } catch(Exception e) {
	        	if(selectedFile!=null) {
	        		error(e.getMessage());
	        	}
	        }
        } else {
        	if(selectedFile!=null) {
	        	error("Plik nie istnieje!");
        	}
        }
	}
	public void paint(Graphics g) {
		g.drawString("Witajcie wszyscy!", 20, 20);
	}
    public void error(String errorr) {
    	JOptionPane pane = new JOptionPane(errorr);
    	pane.setVisible(true);
    	Dialog err = pane.createDialog(this, "Błąd");
        err.setVisible(true);
    	init();
    	destroy();
    	stop();
    }
    public static void main(String args[]) throws java.io.IOException {
    }
}
lipkerson
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad 2 lata
0

A podpisałeś aplet?


Another jam from the world for the jam from the voices of the world......
Koziołek
przeca napisał, że "self-signed" ;)
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Stacktrace
  • Postów:6821
0

Pytanie czy patrzyłeś konsolę javy w przeglądarce?


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
0

Tak. Ale nie rozumiem o czym ona do mnie rozmawia :)

Kopiuj
Java Plug-in 10.3.1.255
Using JRE version 1.7.0_03-b05 Java HotSpot(TM) Client VM
User home directory = C:\Users\Emil Karolak
----------------------------------------------------
Logging set to : true ... completed.
Trace level set to 5: all ... completed.
basic: Added progress listener: sun.plugin.util.ProgressMonitorAdapter@129642c
basic: Plugin2ClassLoader.addURL parent called for http://con3x.com/java/N24video_inspector.jar
network: Cache entry found [url: http://con3x.com/java/N24video_inspector.jar, version: null] prevalidated=true/0
network: Connecting http://con3x.com/java/N24video_inspector.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/N24video_inspector.jar : 304
network: Encoding for http://con3x.com/java/N24video_inspector.jar : null
network: Disconnect connection to http://con3x.com/java/N24video_inspector.jar
cache: Reading Signers from 1066 http://con3x.com/java/N24video_inspector.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\51\16e2aeb3-18534221.idx
cache:  Read manifest for http://con3x.com/java/N24video_inspector.jar: read=649 full=649
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
security: Validate the certificate chain using CertPath API
security: The certificate hasnt been expired, no need to check timestamping info
security: Found jurisdiction list file
security: No need to checking trusted extension for this certificate
security: The CRL support is disabled
security: The OCSP support is disabled
security: This OCSP End Entity validation is disabled
security: Checking if certificate is in Deployment denied certificate store
security: Checking if certificate is in Deployment permanent certificate store
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 2866116 us, pluginInit dt 40597833 us, TotalTime: 43463949 us
network: Cache entry found [url: http://con3x.com/java/jna.jar, version: null] prevalidated=false/0
network: Connecting http://con3x.com/java/jna.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/jna.jar : 304
network: Encoding for http://con3x.com/java/jna.jar : null
network: Disconnect connection to http://con3x.com/java/jna.jar
cache: Reading Signers from 5 http://con3x.com/java/jna.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\14\34cc624e-70f4fbf1.idx
network: No certificate info for unsigned JAR file: http://con3x.com/java/jna.jar
cache:  Read manifest for http://con3x.com/java/jna.jar: read=241 full=241
security: resource name "com/sun/jna/Platform.class" in http://con3x.com/java/jna.jar : java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://con3x.com/java/jna.jar
java.lang.ExceptionInInitializerError
	at n24video_inspector.N24video_inspector.init(N24video_inspector.java:23)
	at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://con3x.com/java/jna.jar
	at com.sun.deploy.security.CPCallbackHandler$ParentCallback.check(Unknown Source)
	at com.sun.deploy.security.CPCallbackHandler$ParentCallback.access$1500(Unknown Source)
	at com.sun.deploy.security.CPCallbackHandler$ChildElement.checkResource(Unknown Source)
	at com.sun.deploy.security.DeployURLClassPath$JarLoader.checkResource(Unknown Source)
	at com.sun.deploy.security.DeployURLClassPath$JarLoader.getResource(Unknown Source)
	at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
	at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
	at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at n24video_inspector.MediaInfo.<clinit>(MediaInfo.java:21)
	... 4 more
basic: Removed progress listener: sun.plugin.util.ProgressMonitorAdapter@129642c
security: Reset deny session certificate store
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Stacktrace
  • Postów:6821
0

O... już wiadomo :) Po pierwsze jar nie jest podpisany tzn. domena z podpisu nijak ma się do domeny z której pobierany jest jar. W wyniku tego Applet jest uruchamiany jako niezaufany i tym samym nie może załadować biblioteki DLL.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
0

Aha. Dzięki za info.

A podpowiesz jak to zrobić dobrze?

Ja podpisuję korzystając z tej instrukcji: http://linuxpoison.blogspot.com/2008/06/how-to-create-self-signed-certificates.html

Nie mam pojęcia w jaki sposób podpisać dodając domenę zdalnego serwera :(

0

Dobra. Doczytałem że chodzi o dodatkowe jar z których korzysta applet i je też podpisałem. Teraz jest już właściwy błąd z brakiem dostępu do dll:

Kopiuj
basic: Added progress listener: sun.plugin.util.ProgressMonitorAdapter@1b911d2
basic: Plugin2ClassLoader.addURL parent called for http://con3x.com/java/N24video_inspector.jar
network: Cache entry found [url: http://con3x.com/java/N24video_inspector.jar, version: null] prevalidated=true/0
network: Connecting http://con3x.com/java/N24video_inspector.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/N24video_inspector.jar : 304
network: Encoding for http://con3x.com/java/N24video_inspector.jar : null
network: Disconnect connection to http://con3x.com/java/N24video_inspector.jar
cache: Reading Signers from 1066 http://con3x.com/java/N24video_inspector.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\51\16e2aeb3-18534221.idx
cache:  Read manifest for http://con3x.com/java/N24video_inspector.jar: read=649 full=649
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
security: Validate the certificate chain using CertPath API
security: The certificate hasnt been expired, no need to check timestamping info
security: Found jurisdiction list file
security: No need to checking trusted extension for this certificate
security: The CRL support is disabled
security: The OCSP support is disabled
security: This OCSP End Entity validation is disabled
security: Checking if certificate is in Deployment denied certificate store
security: Checking if certificate is in Deployment permanent certificate store
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 2866116 us, pluginInit dt 1110450549 us, TotalTime: 1113316665 us
network: Cache entry found [url: http://con3x.com/java/jna.jar, version: null] prevalidated=true/0
network: Connecting http://con3x.com/java/jna.jar with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
network: ResponseCode for http://con3x.com/java/jna.jar : 304
network: Encoding for http://con3x.com/java/jna.jar : null
network: Disconnect connection to http://con3x.com/java/jna.jar
cache: Reading Signers from 1066 http://con3x.com/java/jna.jar | C:\Users\Emil Karolak\AppData\LocalLow\Sun\Java\Deployment\cache\6.0\14\34cc624e-1a6cc1c8.idx
cache:  Read manifest for http://con3x.com/java/jna.jar: read=299 full=5196
basic: Plugin2ClassLoader.getPermissions CeilingPolicy allPerms
java.lang.UnsatisfiedLinkError: Unable to load library 'MediaInfo.dll': Nie mo?na odnale?? okre?lonego modu?
	at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:166)
	at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:239)
	at com.sun.jna.Library$Handler.<init>(Library.java:140)
	at com.sun.jna.Native.loadLibrary(Native.java:393)
	at n24video_inspector.MediaInfoLibrary.<clinit>(MediaInfoLibrary.java:14)
	at n24video_inspector.MediaInfo.<init>(MediaInfo.java:36)
	at n24video_inspector.N24video_inspector.init(N24video_inspector.java:23)
	at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
basic: Removed progress listener: sun.plugin.util.ProgressMonitorAdapter@1b911d2
security: Reset deny session certificate store
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Stacktrace
  • Postów:6821
0

keytool -genkey -keyalg RSA -keysize 2048 -dname "CN=www.yourdomain.com, O=Default, C=US" -keystore domain.keystore

jeżeli dobrze pamiętam...


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Stacktrace
  • Postów:6821
0

A ten dll to sam się zainstaluje w momencie pierwszego wywołania biblioteki czy trzeba samodzielnie System.load wołać?


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
0

Będzie się instalował, ale póki co go ręcznie wrzuciłem do system32 i nie działa ;)

0

YEAH! Podpisałem jak mówiłeś i dodatkowo dll wrzuciłem do program files/java/jre7/bin i DZIAŁA!

Dzięki :)

Teraz jeszcze muszę napisać kopiowanie dll z jara to tego folderu i finito :)

KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 21 godzin
  • Postów:2964
0

Po co tak kombinować. Nie możesz tego appletu przez webstart wrzucić? Tam jest opcja do dostarczania natywnych libów, raczej powinna działać.

http://lopica.sourceforge.net/faq.html#native

0

Moge potwierdzic ze dziala ;d

0

Już nie chciałbym bawić się w takie rozwiązania bo w tamtym się w ogóle nie orientuję.

Teraz juz problemem pozostało tylko poprawne skopiowanie biblioteki z serwera na dysk użytkownika.

Robię to tak:

W applecie przekazuję parametr file:

<applet code="n24video_inspector.N24video_inspector.class" codebase="http://con3x.com/java/" archive="N24video_inspector.jar" name="N24 Video Inspector" mayscript="MAYSCRIPT" scriptable="SCRIPTABLE" width="500" height="500"><param name="file" value="MediaInfo.dll" /></applet>

i wykorzystuję to w klasie tak:

Kopiuj
		String javaHome=System.getProperty("java.home");
		try {
			String file=getParameter("file");
			File inputFile = new File(javaHome+"\\lib\\ext");
			URL copyurl;
			InputStream outputFile;
			copyurl=new URL(getCodeBase(), file);
			outputFile=copyurl.openStream();
			FileOutputStream out=new FileOutputStream(inputFile);
			int c;
			while((c=outputFile.read())!=-1) {
				out.write(c);
			}
			outputFile.close();
			out.close();
		} catch(Exception e) {
			System.out.println("Nie udało się załadować biblioteki MediaInfo.dll");
		}

Wynik na konsoli:

Kopiuj
basic: Starting applet teardown
basic: Finished applet teardown
basic: Removed progress listener: sun.plugin.util.ProgressMonitorAdapter@b41cfa
plugin2manager.parentwindowDispose
basic: Added progress listener: sun.plugin.util.ProgressMonitorAdapter@6aacbf
basic: Plugin2ClassLoader.addURL parent called for http://con3x.com/java/N24video_inspector.jar
security: Validate the certificate chain using CertPath API
security: The certificate hasnt been expired, no need to check timestamping info
security: Found jurisdiction list file
security: No need to checking trusted extension for this certificate
security: The CRL support is disabled
security: The OCSP support is disabled
security: This OCSP End Entity validation is disabled
security: Checking if certificate is in Deployment denied certificate store
security: Checking if certificate is in Deployment permanent certificate store
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 1315439 us, pluginInit dt 16516693 us, TotalTime: 17832132 us
network: Cache entry not found [url: http://con3x.com/java/MediaInfo.dll, version: null]
network: Connecting http://con3x.com/java/MediaInfo.dll with proxy=DIRECT
network: Connecting http://con3x.com:80/ with proxy=DIRECT
Nie udało się załadować biblioteki MediaInfo.dll

Czyli tak jakby się łączy z serwerem a potem wywala od razu błąd. (a plik na serwerze istnieje). Jakieś porady? Proszę uprzejmie o pomoc.

0

Uściśliłem błąd:

Kopiuj
Nie udało się załadować biblioteki MediaInfo.dll 
java.io.FileNotFoundException: C:\Program Files (x86)\Java\jre7\lib\ext (Odmowa dostępu)
	at java.io.FileOutputStream.open(Native Method)
	at java.io.FileOutputStream.<init>(Unknown Source)
	at java.io.FileOutputStream.<init>(Unknown Source)
	at n24video_inspector.N24video_inspector.init(N24video_inspector.java:24)
	at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Dlaczego jest odmowa dostępu? :(

edytowany 1x, ostatnio: Koziołek
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Stacktrace
  • Postów:6821
0

a czy katalog na pewno istnieje? IMO znacznie lepszą metodą jest "instalacja" w system32 choć antywirus będzie miał uprzedzenia co do tej metody.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
0

Nie wiem jak to jest na windowsach, ale system plikow tez ma jakies uprawnienia. Tzn. jesli ty uruchamiasz applet (firefoxa) jako Koziolek, i aplet jest podpisany i mozesz pisac w swoich katalogach, niekoniecznie oznacza to ze mozesz pisac w c:/program files. Z tego co pamietam to vista i 7 wlasnie maja takie zabezpieczenia. Tak samo u mnie: nie zapiszesz nic w /usr/lib/jvm/java7/ext bo tam pisac moze tylko root. Podpisanie apletu tu nie pomoze bo jest uruchamiany z innym uid i guid.
Wierz mi, deploy appletu z jnlp jest o wiele lepszym trwalszym i poprawnym rozwiazaniem. Ja jako user bym w zyciu nie pozwolil wrzucac mi jakichs dll do katalogu javy, przeciez to jest luka jak skurwysyn...

0

Poradizłem sobie z tymi problemami.

Został już naprawdę ostatni: jak pobrać ścieżkę do java.home dla różnych jre. Mam zainstalowane jre6 i jre7, aplikacja odpala się w jre7 ale System.getProperty("java.home"); wskazuje na folder programfiles/java/jre6 i tam też zapisuje mi plik dll a jre7 go tam nie może znaleźć. Mogę jakoś decydować w któym jre zapiszę plik? (chodzi o to, że by w tym które jest używane do uruchomienia aplikacji to się zapisało albo najlepiej w KAŻDYM jre i po sprawie).

Kod:

Kopiuj
		try {
			String file=getParameter("file");
			File inputFile=new File(javaHome+"\\lib\\ext\\MediaInfo.dll");
			boolean success=inputFile.createNewFile();
		    if(success) {
				URL copyurl;
				InputStream outputFile;
				copyurl=new URL(getCodeBase(), file);
				outputFile=copyurl.openStream();
				FileOutputStream out=new FileOutputStream(inputFile);
				int c;
				while((c=outputFile.read())!=-1) {
					out.write(c);
				}
				outputFile.close();
				out.close();
		    }
		} catch(Exception e) {
			System.out.println("Nie udało się załadować biblioteki MediaInfo.dll ");
			e.printStackTrace();
		}
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Stacktrace
  • Postów:6821
0

mućka, tylko pamiętaj, że "odmowa dostępu" może oznaczać np. brak określonego katalogu. To jest taki feature javy dzięki któremu można się naciąć na szukanie błędu w innym miejscu.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
0

Witam ponownie.

Tamte problemy już rozwiązane ale pojawił się kolejny. A raczej kolejne pytanie.

Czy i jak da się z apletu Java w wybranym momencie np. po policzeniu kilku rzeczy zmodyfikować wartość wybranego pola input w formularzu HTML na stronie z apletem? (może być przy użyciu JS)

Da się?

Pzdr.

0

Dzięki wielkie!
Bardzo mi to pomogło :)

Dziękuję wszystkim za pomoc. Pozdrawiam.

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)