{"id":306,"date":"2017-04-12T15:31:25","date_gmt":"2017-04-12T13:31:25","guid":{"rendered":"http:\/\/antek.atthost24.pl\/?p=306"},"modified":"2017-04-10T01:27:46","modified_gmt":"2017-04-09T23:27:46","slug":"tokenizacja-kodu-zrodlowego","status":"publish","type":"post","link":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/","title":{"rendered":"Tokenizacja kodu \u017ar\u00f3d\u0142owego"},"content":{"rendered":"<p>W tym wpisie opisz\u0119 pierwszy etap w wykrywaniu plagiat\u00f3w w Plag-Detectorze.<\/p>\n<h3>O co w\u0142a\u015bciwie chodzi?<\/h3>\n<p>Tokenizacja jest terminem wyst\u0119puj\u0105cym cz\u0119sto w tematyce zwi\u0105zanej z bezpiecze\u0144stwem czy te\u017c szyfrowaniem. W tym przypadku chodzi o co\u015b troch\u0119 innego. Wspomnia\u0142em o tym w jednym z <a href=\"http:\/\/antek.atthost24.pl\/index.php\/2017\/04\/04\/wykrywanie-plagiatow-wybor-algorytmu\/\">poprzednich wpis\u00f3w<\/a>.<\/p>\n<p>Poni\u017cej u\u017cyj\u0119 tego samego przyk\u0142adu, kt\u00f3rego u\u017cy\u0142em w tamtym wpisie.<\/p>\n<pre class=\"lang:default decode:true\">String var;           VARIABLE_DECLARATION\r\nint i;                VARIABLE_DECLARATION\r\ni = 3;                IDENTIFIER\r\n                      ASSIGN\r\n                      IDENTIFIER\r\nif (i &gt; 2) {          IF_SWITCH_STATEMENT_BEGIN\r\n                      OPEN_PARENTHESIS\r\n                      IDENTIFIER\r\n                      CONDITION\r\n                      IDENTIFIER\r\n                      CLOSE_PARENTHESIS\r\n var = \"more than 2\"; IDENTIFIER\r\n                      ASSIGN\r\n                      STRING\r\n}                     IF_SWITCH_STATEMENT_END\r\nelse {                IF_SWITCH_STATEMENT_BEGIN\r\n var = \"less than 2\"; IDENTIFIER\r\n                      ASSIGN\r\n                      STRING\r\n}                     IF_SWITCH_STATEMENT_END<\/pre>\n<p>Ide\u0105 tokenizacji jest zamiana kodu \u017ar\u00f3d\u0142owego na ci\u0105g token\u00f3w. W listingu powy\u017cej mo\u017cna zobaczy\u0107 jak mo\u017ce wygl\u0105da\u0107 przyk\u0142adowa tokenizacja kawa\u0142ka kodu.<\/p>\n<h3>Jak to zrobi\u0107 w praktyce?<\/h3>\n<p>Oczywi\u015bcie mo\u017cna by samemu napisa\u0107 tokenizer, ale by\u0142aby to do\u015b\u0107 skomplikowana i d\u0142uga robota. Oczywi\u015bcie zak\u0142adaj\u0105c, \u017ce tokenizer powinien uwzgl\u0119dnia\u0107 gramatyk\u0119 danego j\u0119zyka. Z pomoc\u0105 przychodzi nam <a href=\"http:\/\/www.antlr.org\/\">ANTLR<\/a>, czyli\u00a0ANother Tool for Language Recognition.<\/p>\n<p>Dla ANTLRa mo\u017cemy zdefiniowa\u0107 gramatyk\u0119, wed\u0142ug kt\u00f3rej b\u0119dzie przeprowadzona tokenizacja. Zdefiniowanie gramatyki dla ka\u017cdego j\u0119zyki r\u00f3wnie\u017c by\u0142oby dosy\u0107 karko\u0142omnym zadaniem. Na szcz\u0119\u015bcie wi\u0119kszo\u015b\u0107 gramatyk dla popularnych j\u0119zyk\u00f3w programowania zosta\u0142a ju\u017c zdefiniowana i jest dost\u0119pna tutaj: <a href=\"https:\/\/github.com\/antlr\/grammars-v4\">https:\/\/github.com\/antlr\/grammars-v4<\/a>.<\/p>\n<h3>Konfiguracja i u\u017cycie ANTLRa<\/h3>\n<p>Poniewa\u017c jeste\u015bmy leniwi, chcemy \u017ceby wszystko nam si\u0119 robi\u0142o automatycznie. I tak jest w tym przypadku \ud83d\ude42<\/p>\n<h4>Zale\u017cno\u015bci<\/h4>\n<p>Konfiguracje musimy standardowo zacz\u0105\u0107 od dodania zale\u017cno\u015bci do naszego pliku pom.xml.<\/p>\n<pre class=\"lang:default decode:true\">&lt;dependency&gt;\r\n\t&lt;groupId&gt;org.antlr&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;antlr4&lt;\/artifactId&gt;\r\n\t&lt;version&gt;4.7&lt;\/version&gt;\r\n&lt;\/dependency&gt;<\/pre>\n<h4>Gramatyka<\/h4>\n<p>Nast\u0119pnie musimy znale\u017a\u0107 interesuj\u0105c\u0105 nas gramatyk\u0119 i wrzuci\u0107 ja do folderu antlr4, kt\u00f3ry umieszczamy w katalogu serc\/main. Dodatkowo, je\u017celi chcemy, \u017ceby kod wygenerowany na podstawie naszej gramatyki by\u0142 w konkretnym pakiecie to musimy gramatyk\u0119 wrzuci\u0107 w\u0142a\u015bnie pod tak\u0105 \u015bcie\u017ck\u0105. Czyli np. je\u017celi chc\u0119, \u017ceby klasy zwi\u0105zane z gramatyk\u0105 by\u0142y w pakiecie\u00a0pl.lantkowiak.plagdetector.algorithm.grammar, to powinienem mie\u0107 tak\u0105 struktur\u0119 katalog\u00f3w jak przedstawiona poni\u017cej.<\/p>\n<pre class=\"lang:default decode:true\">src\r\n|- main\r\n |- antlr4\r\n  |- pl\r\n   |- lantkowiak\r\n    |- algorithm\r\n     |- grammar<\/pre>\n<h4>Pluginy<\/h4>\n<p>Teraz potrzebujemy doda\u0107 do naszego poma kolejne dwa pluginy.<\/p>\n<p><em>antlr4-maven-plugin<\/em><\/p>\n<pre class=\"lang:default decode:true \">&lt;plugin&gt;\r\n\t&lt;groupId&gt;org.antlr&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;antlr4-maven-plugin&lt;\/artifactId&gt;\r\n\t&lt;version&gt;4.7&lt;\/version&gt;\r\n\t&lt;executions&gt;\r\n\t\t&lt;execution&gt;\r\n\t\t\t&lt;id&gt;antlr-generate&lt;\/id&gt;\r\n\t\t\t&lt;phase&gt;generate-sources&lt;\/phase&gt;\r\n\t\t\t&lt;goals&gt;\r\n\t\t\t\t&lt;goal&gt;antlr4&lt;\/goal&gt;\r\n\t\t\t&lt;\/goals&gt;\r\n\t\t&lt;\/execution&gt;\r\n\t&lt;\/executions&gt;\r\n&lt;\/plugin&gt;<\/pre>\n<p>Plugin ten b\u0119dzie odpowiedzialny za wygenerowanie klas zwi\u0105zanych z nasz\u0105 gramatyk\u0105.<\/p>\n<p><em>build-helper-maven-plugin<\/em><\/p>\n<pre class=\"lang:default decode:true\">&lt;plugin&gt;\r\n\t&lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;build-helper-maven-plugin&lt;\/artifactId&gt;\r\n\t&lt;version&gt;3.0.0&lt;\/version&gt;\r\n\t&lt;executions&gt;\r\n\t\t&lt;execution&gt;\r\n\t\t\t&lt;id&gt;add-source&lt;\/id&gt;\r\n\t\t\t&lt;phase&gt;generate-sources&lt;\/phase&gt;\r\n\t\t\t&lt;goals&gt;\r\n\t\t\t\t&lt;goal&gt;add-source&lt;\/goal&gt;\r\n\t\t\t&lt;\/goals&gt;\r\n\t\t\t&lt;configuration&gt;\r\n\t\t\t\t&lt;sources&gt;\r\n\t\t\t\t\t&lt;source&gt;${project.build.directory}\/generated-sources\/antlr\/&lt;\/source&gt;\r\n\t\t\t\t&lt;\/sources&gt;\r\n\t\t\t&lt;\/configuration&gt;\r\n\t\t&lt;\/execution&gt;\r\n\t&lt;\/executions&gt;\r\n&lt;\/plugin&gt;<\/pre>\n<p>Ten plugin sprawia, \u017ce nasze wygenerowane \u017ar\u00f3d\u0142a b\u0119d\u0105 widoczne w Eclipsie jako klasy, kt\u00f3rych mo\u017cemy u\u017cy\u0107.<\/p>\n<h4>Ma\u0142y hack<\/h4>\n<p>Je\u017celi b\u0119dziemy wykorzysta\u0107 wygenerowane klasy w naszym kodzie Kotlinowym to nasz projekt niestety si\u0119 nie zbuduje. Maven nie b\u0119dzie widzia\u0142 wygenerowanych \u017ar\u00f3de\u0142. Aby to naprawi\u0107 musimy w naszym pomie zamieni\u0107 kolejno\u015bci\u0105 pluginy odpowiedzialne za kompilacje Javy i Kotlina. W wpisie <a href=\"http:\/\/antek.atthost24.pl\/index.php\/2017\/04\/07\/hello-kotlin\/\">Hello Kotlin<\/a> pisa\u0142em, \u017ce plugin do kompilacji kodu Kotlina powinien by\u0107 przed pluginem Javovym, \u017ceby kod kotlina m\u00f3g\u0142 by\u0107 u\u017cyty w Javie. Niestety p\u00f3ki co musia\u0142em z tego zrezygnowa\u0107, aby m\u00f3c zautomatyzowa\u0107 proces generacji kod\u00f3w \u017ar\u00f3d\u0142owych dla gramatyk ANTLRowych.<\/p>\n<h4>U\u017cycie w kodzie<\/h4>\n<p>Dla np. gramatyki dla Java 8 ANTLR wygeneruje nast\u0119puj\u0105ce pliki:<\/p>\n<pre class=\"lang:default decode:true \">Java8.tokens\r\nJava8Lexer.tokens\r\nJava8BaseListener.java\r\nJava8Lexer.java\r\nJava8Listener.java\r\nJava8Parser.java<\/pre>\n<p>Klasa, kt\u00f3ra b\u0119dzie nas interesowa\u0142a do przeprowadzenia tokenizacji to\u00a0Java8Lexer.<\/p>\n<p>Poniewa\u017c Plag-Detector b\u0119dzie wspiera\u0142 wiele j\u0119zyk\u00f3w programowania stworzy\u0142em enuma, kt\u00f3ry b\u0119dzie zawiera\u0142 wszystkie wspierane j\u0119zyki.<\/p>\n<pre class=\"lang:default decode:true \">enum class LexerType(val title: String) {\r\n\tJAVA_8(\"Java 8\")\r\n}<\/pre>\n<p>Nast\u0119pnie stworzy\u0142em prost\u0105 fabryk\u0119, kt\u00f3ra na podstawie przekazanego enuma zwr\u00f3ci mi instancje oczekiwanego leexera.<\/p>\n<pre class=\"lang:default decode:true \">class LexerFactory {\r\n\tfun getLexer(type: LexerType, cs: CharStream): Lexer {\r\n\t\twhen (type) {\r\n\t\t\tLexerType.JAVA_8 -&gt; return Java8Lexer(cs)\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>Klasa\u00a0Lexer jest klas\u0105 abstrakcyjn\u0105, po kt\u00f3rej dziedzicz\u0105 wszystkie lexery wygenerowane przez ANTLRa.<\/p>\n<p>Sama tokenizacja jest ju\u017c bardzo prosta:<\/p>\n<pre class=\"lang:default decode:true\">class TokenizerImpl : Tokenizer {\r\n\toverride fun tokenize(lexerType: LexerType, input: String): List&lt;Int&gt; {\r\n\t\tval lexer = LexerFactory().getLexer(lexerType, CharStreams.fromString(input))\r\n\r\n\t\treturn lexer.allTokens.map { t -&gt; t.type }\r\n\t}\r\n}<\/pre>\n<p>W pierwszej linii metody tworze instancje fabryki, a nast\u0119pnie pobieram lexer. Nast\u0119pnie wywo\u0142uj\u0119 metod\u0119 getallTokens(), kt\u00f3ra zwraca mi list\u0119 wszystkich token\u00f3w z przetworzonego kodu \u017ar\u00f3d\u0142owego. Poniewa\u017c do dalszych potrzeb\u00a0istotne s\u0105 dla mnie tylko typy token\u00f3w, a nie ca\u0142e obiekty z nadmiarowymi danymi, mapuj\u0119 tokeny na ich typ, czyli int. Tak\u0105 list\u0119 int\u00f3w jest zwracana przez metod\u0119 i b\u0119dzie dalej u\u017cyta w procesie wykrywania plagiat\u00f3w.<\/p>\n<h3>Podsumowanie<\/h3>\n<p>W tym wpisie przedstawi\u0142em ANTLRa oraz pokaza\u0142em jak go skonfigurowa\u0107. Dodatkowo pokaza\u0142em w jaki spos\u00f3b mo\u017cna u\u017cy\u0107 ANTLRa, aby dokona\u0107 tokenizacji ci\u0105gu znak\u00f3w na wej\u015bciu &#8211; w naszym przypadku kodu \u017ar\u00f3d\u0142owego.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>W tym wpisie opisz\u0119 pierwszy etap w wykrywaniu plagiat\u00f3w w Plag-Detectorze. O co w\u0142a\u015bciwie chodzi? Tokenizacja jest terminem wyst\u0119puj\u0105cym cz\u0119sto w tematyce zwi\u0105zanej z bezpiecze\u0144stwem czy te\u017c szyfrowaniem&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":311,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,20,19],"tags":[],"class_list":["post-306","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dsp2017","category-kotlin","category-plagdetector"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Tokenizacja kodu \u017ar\u00f3d\u0142owego - Lukasz Antkowiak&#039;s blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/\" \/>\n<meta property=\"og:locale\" content=\"pl_PL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tokenizacja kodu \u017ar\u00f3d\u0142owego - Lukasz Antkowiak&#039;s blog\" \/>\n<meta property=\"og:description\" content=\"W tym wpisie opisz\u0119 pierwszy etap w wykrywaniu plagiat\u00f3w w Plag-Detectorze. O co w\u0142a\u015bciwie chodzi? Tokenizacja jest terminem wyst\u0119puj\u0105cym cz\u0119sto w tematyce zwi\u0105zanej z bezpiecze\u0144stwem czy te\u017c szyfrowaniem....\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukasz Antkowiak&#039;s blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-12T13:31:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-04-09T23:27:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.lantkowiak.pl\/wp-content\/uploads\/2017\/04\/tokenization.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"600\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"\u0141ukasz Antkowiak\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Napisane przez\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u0141ukasz Antkowiak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Szacowany czas czytania\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minut\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/\",\"url\":\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/\",\"name\":\"Tokenizacja kodu \u017ar\u00f3d\u0142owego - Lukasz Antkowiak&#039;s blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.lantkowiak.pl\/#website\"},\"datePublished\":\"2017-04-12T13:31:25+00:00\",\"dateModified\":\"2017-04-09T23:27:46+00:00\",\"author\":{\"@id\":\"https:\/\/blog.lantkowiak.pl\/#\/schema\/person\/009bfc4db220c225786c59b1748ba1e6\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/#breadcrumb\"},\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\u0142\u00f3wna\",\"item\":\"https:\/\/blog.lantkowiak.pl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tokenizacja kodu \u017ar\u00f3d\u0142owego\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.lantkowiak.pl\/#website\",\"url\":\"https:\/\/blog.lantkowiak.pl\/\",\"name\":\"Lukasz Antkowiak&#039;s blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.lantkowiak.pl\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pl-PL\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.lantkowiak.pl\/#\/schema\/person\/009bfc4db220c225786c59b1748ba1e6\",\"name\":\"\u0141ukasz Antkowiak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/blog.lantkowiak.pl\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e18e2bfe319da9b5757cf7f7ae1bfecf?s=96&d=monsterid&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e18e2bfe319da9b5757cf7f7ae1bfecf?s=96&d=monsterid&r=g\",\"caption\":\"\u0141ukasz Antkowiak\"},\"description\":\"dd\",\"url\":\"https:\/\/blog.lantkowiak.pl\/index.php\/author\/antek\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tokenizacja kodu \u017ar\u00f3d\u0142owego - Lukasz Antkowiak&#039;s blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/","og_locale":"pl_PL","og_type":"article","og_title":"Tokenizacja kodu \u017ar\u00f3d\u0142owego - Lukasz Antkowiak&#039;s blog","og_description":"W tym wpisie opisz\u0119 pierwszy etap w wykrywaniu plagiat\u00f3w w Plag-Detectorze. O co w\u0142a\u015bciwie chodzi? Tokenizacja jest terminem wyst\u0119puj\u0105cym cz\u0119sto w tematyce zwi\u0105zanej z bezpiecze\u0144stwem czy te\u017c szyfrowaniem....","og_url":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/","og_site_name":"Lukasz Antkowiak&#039;s blog","article_published_time":"2017-04-12T13:31:25+00:00","article_modified_time":"2017-04-09T23:27:46+00:00","og_image":[{"width":600,"height":300,"url":"https:\/\/blog.lantkowiak.pl\/wp-content\/uploads\/2017\/04\/tokenization.jpg","type":"image\/jpeg"}],"author":"\u0141ukasz Antkowiak","twitter_card":"summary_large_image","twitter_misc":{"Napisane przez":"\u0141ukasz Antkowiak","Szacowany czas czytania":"5 minut"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/","url":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/","name":"Tokenizacja kodu \u017ar\u00f3d\u0142owego - Lukasz Antkowiak&#039;s blog","isPartOf":{"@id":"https:\/\/blog.lantkowiak.pl\/#website"},"datePublished":"2017-04-12T13:31:25+00:00","dateModified":"2017-04-09T23:27:46+00:00","author":{"@id":"https:\/\/blog.lantkowiak.pl\/#\/schema\/person\/009bfc4db220c225786c59b1748ba1e6"},"breadcrumb":{"@id":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/#breadcrumb"},"inLanguage":"pl-PL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.lantkowiak.pl\/index.php\/2017\/04\/12\/tokenizacja-kodu-zrodlowego\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/blog.lantkowiak.pl\/"},{"@type":"ListItem","position":2,"name":"Tokenizacja kodu \u017ar\u00f3d\u0142owego"}]},{"@type":"WebSite","@id":"https:\/\/blog.lantkowiak.pl\/#website","url":"https:\/\/blog.lantkowiak.pl\/","name":"Lukasz Antkowiak&#039;s blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.lantkowiak.pl\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pl-PL"},{"@type":"Person","@id":"https:\/\/blog.lantkowiak.pl\/#\/schema\/person\/009bfc4db220c225786c59b1748ba1e6","name":"\u0141ukasz Antkowiak","image":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/blog.lantkowiak.pl\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e18e2bfe319da9b5757cf7f7ae1bfecf?s=96&d=monsterid&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e18e2bfe319da9b5757cf7f7ae1bfecf?s=96&d=monsterid&r=g","caption":"\u0141ukasz Antkowiak"},"description":"dd","url":"https:\/\/blog.lantkowiak.pl\/index.php\/author\/antek\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/posts\/306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/comments?post=306"}],"version-history":[{"count":10,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions"}],"predecessor-version":[{"id":361,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions\/361"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/media\/311"}],"wp:attachment":[{"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/media?parent=306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/categories?post=306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lantkowiak.pl\/index.php\/wp-json\/wp\/v2\/tags?post=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}