diff --git a/devel/osx/Modest.xcodeproj/project.pbxproj b/devel/osx/Modest.xcodeproj/project.pbxproj index f3bee92..1cc1e95 100644 --- a/devel/osx/Modest.xcodeproj/project.pbxproj +++ b/devel/osx/Modest.xcodeproj/project.pbxproj @@ -111,14 +111,18 @@ 0E7510041D9AF27F00337E9B /* mctree.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E750FE21D9AF27F00337E9B /* mctree.c */; }; 0E7510051D9AF27F00337E9B /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E750FE51D9AF27F00337E9B /* utils.c */; }; 0E79EE951DC8E270004FF5DC /* stack.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E79EE931DC8E270004FF5DC /* stack.c */; }; - 0E7F782D1DD3DF6C003B6053 /* layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F782B1DD3DF6C003B6053 /* layout.c */; }; 0E7F78351DD3E0D5003B6053 /* begin.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F78331DD3E0D5003B6053 /* begin.c */; }; 0E7F78381DD3E2E5003B6053 /* glue.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F78361DD3E2E5003B6053 /* glue.c */; }; 0E7F783A1DD3FE2C003B6053 /* layer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F78391DD3FE2C003B6053 /* layer.c */; }; - 0E7F783D1DD4AFAA003B6053 /* binding.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F783B1DD4AFAA003B6053 /* binding.c */; }; 0E818EF61DAE6F8F005B0C77 /* serialization.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E818EF41DAE6F8F005B0C77 /* serialization.c */; }; 0EA033771DB6AFBA009CB2B9 /* raw.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA033751DB6AFBA009CB2B9 /* raw.c */; }; 0EE852811DC94891003BB21C /* parser_background.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EE8527F1DC94891003BB21C /* parser_background.c */; }; + 0EF2D5E81E01DFD5000570B6 /* binding.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2D5E21E01DFD5000570B6 /* binding.c */; }; + 0EF2D5E91E01DFD5000570B6 /* tree_node.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2D5E41E01DFD5000570B6 /* tree_node.c */; }; + 0EF2D5EA1E01DFD5000570B6 /* tree.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2D5E61E01DFD5000570B6 /* tree.c */; }; + 0EF2D5ED1E01E04A000570B6 /* declaration.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2D5EB1E01E04A000570B6 /* declaration.c */; }; + 0EF2D5F21E01E089000570B6 /* default.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2D5F01E01E089000570B6 /* default.c */; }; + 0EF2D5F71E01E0BD000570B6 /* default.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF2D5F51E01E0BD000570B6 /* default.c */; }; 0EF68DCE1DBF6CF000B0DEA4 /* color_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF68DCC1DBF6CF000B0DEA4 /* color_parser.c */; }; 0EF808A31D9FF3BC001AF6EF /* sheet.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF808A11D9FF3BC001AF6EF /* sheet.c */; }; 0EF808A61DA08BBE001AF6EF /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EF808A41DA08BBE001AF6EF /* map.c */; }; @@ -372,21 +376,34 @@ 0E750FE61D9AF27F00337E9B /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utils.h; path = ../../source/myhtml/utils.h; sourceTree = ""; }; 0E79EE931DC8E270004FF5DC /* stack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stack.c; path = ../../source/mycss/stack.c; sourceTree = ""; }; 0E79EE941DC8E270004FF5DC /* stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stack.h; path = ../../source/mycss/stack.h; sourceTree = ""; }; - 0E7F782B1DD3DF6C003B6053 /* layout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = layout.c; path = ../../../source/modest/layer/layout.c; sourceTree = ""; }; 0E7F782C1DD3DF6C003B6053 /* layer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = layer.h; path = ../../../source/modest/layer/layer.h; sourceTree = ""; }; 0E7F78331DD3E0D5003B6053 /* begin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = begin.c; path = ../../../source/modest/render/begin.c; sourceTree = ""; }; 0E7F78341DD3E0D5003B6053 /* begin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = begin.h; path = ../../../source/modest/render/begin.h; sourceTree = ""; }; 0E7F78361DD3E2E5003B6053 /* glue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = glue.c; path = ../../../source/modest/glue.c; sourceTree = ""; }; 0E7F78371DD3E2E5003B6053 /* glue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glue.h; path = ../../../source/modest/glue.h; sourceTree = ""; }; 0E7F78391DD3FE2C003B6053 /* layer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = layer.c; path = ../../../source/modest/layer/layer.c; sourceTree = ""; }; - 0E7F783B1DD4AFAA003B6053 /* binding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = binding.c; path = ../../../source/modest/layer/binding.c; sourceTree = ""; }; - 0E7F783C1DD4AFAA003B6053 /* binding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = binding.h; path = ../../../source/modest/layer/binding.h; sourceTree = ""; }; 0E818EF41DAE6F8F005B0C77 /* serialization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = serialization.c; sourceTree = ""; }; 0E818EF51DAE6F8F005B0C77 /* serialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serialization.h; sourceTree = ""; }; 0E818EF71DAE6FEE005B0C77 /* serialization_resources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = serialization_resources.h; sourceTree = ""; }; 0EA033751DB6AFBA009CB2B9 /* raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw.c; sourceTree = ""; }; 0EA033761DB6AFBA009CB2B9 /* raw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = raw.h; sourceTree = ""; }; 0EE8527F1DC94891003BB21C /* parser_background.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = parser_background.c; sourceTree = ""; }; + 0EF2D5E21E01DFD5000570B6 /* binding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = binding.c; path = ../../../source/modest/render/binding.c; sourceTree = ""; }; + 0EF2D5E31E01DFD5000570B6 /* binding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = binding.h; path = ../../../source/modest/render/binding.h; sourceTree = ""; }; + 0EF2D5E41E01DFD5000570B6 /* tree_node.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tree_node.c; path = ../../../source/modest/render/tree_node.c; sourceTree = ""; }; + 0EF2D5E51E01DFD5000570B6 /* tree_node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tree_node.h; path = ../../../source/modest/render/tree_node.h; sourceTree = ""; }; + 0EF2D5E61E01DFD5000570B6 /* tree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tree.c; path = ../../../source/modest/render/tree.c; sourceTree = ""; }; + 0EF2D5E71E01DFD5000570B6 /* tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tree.h; path = ../../../source/modest/render/tree.h; sourceTree = ""; }; + 0EF2D5EB1E01E04A000570B6 /* declaration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = declaration.c; path = ../../../source/modest/declaration.c; sourceTree = ""; }; + 0EF2D5EC1E01E04A000570B6 /* declaration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = declaration.h; path = ../../../source/modest/declaration.h; sourceTree = ""; }; + 0EF2D5EE1E01E089000570B6 /* default_entries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default_entries.h; sourceTree = ""; }; + 0EF2D5EF1E01E089000570B6 /* default_resources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default_resources.h; sourceTree = ""; }; + 0EF2D5F01E01E089000570B6 /* default.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = default.c; sourceTree = ""; }; + 0EF2D5F11E01E089000570B6 /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = ""; }; + 0EF2D5F31E01E0BD000570B6 /* default_entries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default_entries.h; sourceTree = ""; }; + 0EF2D5F41E01E0BD000570B6 /* default_resources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default_resources.h; sourceTree = ""; }; + 0EF2D5F51E01E0BD000570B6 /* default.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = default.c; sourceTree = ""; }; + 0EF2D5F61E01E0BD000570B6 /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = ""; }; 0EF68DCC1DBF6CF000B0DEA4 /* color_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = color_parser.c; sourceTree = ""; }; 0EF68DCD1DBF6CF000B0DEA4 /* color_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = color_parser.h; sourceTree = ""; }; 0EF808A11D9FF3BC001AF6EF /* sheet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sheet.c; sourceTree = ""; }; @@ -410,6 +427,10 @@ 0E02397C1D9FE8920084A81A /* style */ = { isa = PBXGroup; children = ( + 0EF2D5EE1E01E089000570B6 /* default_entries.h */, + 0EF2D5EF1E01E089000570B6 /* default_resources.h */, + 0EF2D5F01E01E089000570B6 /* default.c */, + 0EF2D5F11E01E089000570B6 /* default.h */, 0EF808A21D9FF3BC001AF6EF /* sheet.h */, 0EF808A11D9FF3BC001AF6EF /* sheet.c */, 0EA033761DB6AFBA009CB2B9 /* raw.h */, @@ -467,6 +488,8 @@ 0E0239861D9FEBE10084A81A /* modest.c */, 0E7F78371DD3E2E5003B6053 /* glue.h */, 0E7F78361DD3E2E5003B6053 /* glue.c */, + 0EF2D5EC1E01E04A000570B6 /* declaration.h */, + 0EF2D5EB1E01E04A000570B6 /* declaration.c */, 0E750EED1D9AF25300337E9B /* finder */, 0E02397C1D9FE8920084A81A /* style */, 0E0239821D9FEA950084A81A /* node */, @@ -652,6 +675,10 @@ 0E818EF51DAE6F8F005B0C77 /* serialization.h */, 0E818EF41DAE6F8F005B0C77 /* serialization.c */, 0E818EF71DAE6FEE005B0C77 /* serialization_resources.h */, + 0EF2D5F61E01E0BD000570B6 /* default.h */, + 0EF2D5F51E01E0BD000570B6 /* default.c */, + 0EF2D5F41E01E0BD000570B6 /* default_resources.h */, + 0EF2D5F31E01E0BD000570B6 /* default_entries.h */, ); name = declaration; path = ../../source/mycss/declaration; @@ -799,9 +826,6 @@ children = ( 0E7F782C1DD3DF6C003B6053 /* layer.h */, 0E7F78391DD3FE2C003B6053 /* layer.c */, - 0E7F782B1DD3DF6C003B6053 /* layout.c */, - 0E7F783C1DD4AFAA003B6053 /* binding.h */, - 0E7F783B1DD4AFAA003B6053 /* binding.c */, ); name = layer; sourceTree = ""; @@ -809,6 +833,12 @@ 0E7F78321DD3E0B9003B6053 /* render */ = { isa = PBXGroup; children = ( + 0EF2D5E21E01DFD5000570B6 /* binding.c */, + 0EF2D5E31E01DFD5000570B6 /* binding.h */, + 0EF2D5E41E01DFD5000570B6 /* tree_node.c */, + 0EF2D5E51E01DFD5000570B6 /* tree_node.h */, + 0EF2D5E61E01DFD5000570B6 /* tree.c */, + 0EF2D5E71E01DFD5000570B6 /* tree.h */, 0E7F78341DD3E0D5003B6053 /* begin.h */, 0E7F78331DD3E0D5003B6053 /* begin.c */, ); @@ -873,6 +903,7 @@ buildActionMask = 2147483647; files = ( 0EA033771DB6AFBA009CB2B9 /* raw.c in Sources */, + 0EF2D5E91E01DFD5000570B6 /* tree_node.c in Sources */, 0E750FF71D9AF27F00337E9B /* tag.c in Sources */, 0E750FF21D9AF27F00337E9B /* perf.c in Sources */, 0E750FFF1D9AF27F00337E9B /* mchar_async.c in Sources */, @@ -902,6 +933,7 @@ 0E750F1F1D9AF26300337E9B /* myfont.c in Sources */, 0E750FF81D9AF27F00337E9B /* thread.c in Sources */, 0E750FE71D9AF27F00337E9B /* callback.c in Sources */, + 0EF2D5EA1E01DFD5000570B6 /* tree.c in Sources */, 0E79EE951DC8E270004FF5DC /* stack.c in Sources */, 0E750F8D1D9AF27200337E9B /* parser.c in Sources */, 0E750F971D9AF27200337E9B /* pseudo.c in Sources */, @@ -958,11 +990,12 @@ 0E750FA01D9AF27200337E9B /* units.c in Sources */, 0E750F211D9AF26300337E9B /* name.c in Sources */, 0E750F241D9AF26300337E9B /* vhea.c in Sources */, + 0EF2D5F71E01E0BD000570B6 /* default.c in Sources */, 0E750F831D9AF27200337E9B /* entry.c in Sources */, 0E750FF31D9AF27F00337E9B /* rules.c in Sources */, 0E750FFD1D9AF27F00337E9B /* tokenizer.c in Sources */, + 0EF2D5E81E01DFD5000570B6 /* binding.c in Sources */, 0E750FF41D9AF27F00337E9B /* serialization.c in Sources */, - 0E7F783D1DD4AFAA003B6053 /* binding.c in Sources */, 0EF808A61DA08BBE001AF6EF /* map.c in Sources */, 0E750F8F1D9AF27200337E9B /* parser.c in Sources */, 0E750FA11D9AF27200337E9B /* values.c in Sources */, @@ -971,6 +1004,7 @@ 0E750F821D9AF27200337E9B /* convert.c in Sources */, 0E750FE91D9AF27F00337E9B /* data_process.c in Sources */, 0E4B525C1DC13BBB0095026A /* parser_text_decoration.c in Sources */, + 0EF2D5F21E01E089000570B6 /* default.c in Sources */, 0E7510011D9AF27F00337E9B /* mcobject_async.c in Sources */, 0E750FE81D9AF27F00337E9B /* charef.c in Sources */, 0EE852811DC94891003BB21C /* parser_background.c in Sources */, @@ -979,8 +1013,8 @@ 0E750F1E1D9AF26300337E9B /* maxp.c in Sources */, 0E750F8A1D9AF27200337E9B /* mycss.c in Sources */, 0E750FEB1D9AF27F00337E9B /* encoding.c in Sources */, - 0E7F782D1DD3DF6C003B6053 /* layout.c in Sources */, 0E0C91921DAED0F5007A0501 /* serialization.c in Sources */, + 0EF2D5ED1E01E04A000570B6 /* declaration.c in Sources */, 0E7F78381DD3E2E5003B6053 /* glue.c in Sources */, 0E750F1D1D9AF26300337E9B /* loca.c in Sources */, 0E750F9C1D9AF27200337E9B /* tokenizer_global.c in Sources */, diff --git a/devel/osx/Modest.xcodeproj/project.xcworkspace/xcuserdata/alexanderborisov.xcuserdatad/UserInterfaceState.xcuserstate b/devel/osx/Modest.xcodeproj/project.xcworkspace/xcuserdata/alexanderborisov.xcuserdatad/UserInterfaceState.xcuserstate index a4f7059..e0e4c30 100644 Binary files a/devel/osx/Modest.xcodeproj/project.xcworkspace/xcuserdata/alexanderborisov.xcuserdatad/UserInterfaceState.xcuserstate and b/devel/osx/Modest.xcodeproj/project.xcworkspace/xcuserdata/alexanderborisov.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/examples/Makefile b/examples/Makefile index 3e09a22..d008f63 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -32,7 +32,7 @@ endif find_files_h = $(wildcard $(dir)/*.h) find_files_c = $(wildcard $(dir)/*.c) -SUBDIRS := selectors declarations font modest +SUBDIRS := selectors declarations font modest mycss myhtml HDRS += $(foreach dir,$(SUBDIRS),$(find_files_h)) SRCS += $(foreach dir,$(SUBDIRS),$(find_files_c)) diff --git a/examples/mycss/css_low_level.c b/examples/mycss/css_low_level.c new file mode 100644 index 0000000..0732853 --- /dev/null +++ b/examples/mycss/css_low_level.c @@ -0,0 +1,125 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +struct res_data { + char *data; + size_t size; +}; + +struct res_data load_data_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *data = (char*)malloc(size + 1); + if(data == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(data, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_data res = {data, (size_t)size}; + return res; +} + +void serialization_callback(const char* data, size_t len, void* ctx) +{ + printf("%.*s", (int)len, data); +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: css_low_level \n"); + exit(EXIT_FAILURE); + } + + struct res_data res = load_data_file(path); + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // parse selectors + status = mycss_parse(entry, MyHTML_ENCODING_UTF_8, res.data, res.size); + + if(status) { + fprintf(stderr, "Parse error!\n"); + exit(EXIT_FAILURE); + } + + /* print result */ + printf("Result:\n"); + mycss_namespace_serialization_stylesheet(&entry->stylesheet->ns_stylesheet, serialization_callback, NULL); + mycss_stylesheet_serialization(entry->stylesheet, serialization_callback, NULL); + printf("\n"); + + // destroy all + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + free(res.data); + + return 0; +} + + diff --git a/examples/mycss/declaration_low_level.c b/examples/mycss/declaration_low_level.c new file mode 100644 index 0000000..030da3b --- /dev/null +++ b/examples/mycss/declaration_low_level.c @@ -0,0 +1,70 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include +#include + +void serialization_callback(const char* data, size_t len, void* ctx) +{ + printf("%.*s", (int)len, data); +} + +int main(int argc, const char * argv[]) +{ + const char *declaration = "width : 100%; height: 1.2em"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // parse selectors + printf("Input data:\n"); + printf("\t%s", declaration); + printf("\n"); + + mycss_status_t out_status; + mycss_declaration_entry_t *dec_entry = mycss_declaration_parse(entry->declaration, MyHTML_ENCODING_UTF_8, + declaration, strlen(declaration), &out_status); + + /* print result */ + printf("Result:\n\t"); + mycss_declaration_serialization_entries(entry, dec_entry, serialization_callback, NULL); + printf("\n"); + + // destroy all + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + + diff --git a/source/modest/layer/binding.c b/examples/mycss/detect_charset_encoding_high_level.c similarity index 64% rename from source/modest/layer/binding.c rename to examples/mycss/detect_charset_encoding_high_level.c index a1a026a..247adda 100644 --- a/source/modest/layer/binding.c +++ b/examples/mycss/detect_charset_encoding_high_level.c @@ -18,17 +18,25 @@ Author: lex.borisov@gmail.com (Alexander Borisov) */ -#include "modest/layer/binding.h" +#include +#include +#include -modest_layer_t * modest_layer_binding(modest_t* modest, myhtml_tree_t* html_tree) -{ - modest_layer_t *root = modest_layer_create(modest->layout); - return root; -} +#include -void modest_layer_binding_html_node(modest_t* modest, myhtml_tree_node_t* html_node) +int main(int argc, const char * argv[]) { - modest_node_t *m_node = html_node->data; + char *css = "@charset \"cp1251\"; #best-id {}"; - //m_node->layer + myhtml_encoding_t encoding = mycss_encoding_check_charset_rule(css, strlen(css)); + + if(encoding == MyHTML_ENCODING_WINDOWS_1251) + printf("Detected Encoding: windows-1251\n"); + else + printf("Detected Encoding: something wrong\n"); + + return 0; } + + + diff --git a/examples/mycss/incoming_buffer_high_level.c b/examples/mycss/incoming_buffer_high_level.c new file mode 100644 index 0000000..dc63fba --- /dev/null +++ b/examples/mycss/incoming_buffer_high_level.c @@ -0,0 +1,119 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +// see tokenizer_buffer_high_level + +mycss_token_t * token_ready_callback(mycss_entry_t* entry, mycss_token_t* token) +{ + // print token name + size_t tokens_count = mycss_entry_token_count(entry); + mycss_token_type_t token_type = mycss_token_type(token); + + printf("Token %zu; %s; \"", tokens_count, mycss_token_name_by_type(token_type)); + + // print data + myhtml_incoming_buffer_t *buffer = mycss_entry_incoming_buffer_current(entry); + buffer = myhtml_incoming_buffer_find_by_position(buffer, mycss_token_begin(token)); + + // + size_t absolute_begin = mycss_token_begin(token); + size_t relative_begin = absolute_begin - myhtml_incoming_buffer_offset(buffer); + size_t length = mycss_token_length(token); + + // if token data length in one buffer then print them all at once + if((relative_begin + length) <= myhtml_incoming_buffer_size(buffer)) + { + const char *data = myhtml_incoming_buffer_data(buffer); + printf("%.*s\"\n", (int)length, &data[relative_begin]); + + return token; + } + + // if the data are spread across multiple buffers that join them + while(buffer) { + const char *data = myhtml_incoming_buffer_data(buffer); + + if((relative_begin + length) > myhtml_incoming_buffer_size(buffer)) + { + size_t relative_end = (myhtml_incoming_buffer_size(buffer) - relative_begin); + length -= relative_end; + + printf("%.*s", (int)relative_end, &data[relative_begin]); + + relative_begin = 0; + buffer = myhtml_incoming_buffer_next(buffer); + } + else { + printf("%.*s", (int)length, &data[relative_begin]); + break; + } + } + + printf("\"\n"); + + return token; +} + +int main(int argc, const char * argv[]) +{ + char *css_chunk_1 = "#ident [name=\"best"; + char *css_chunk_2 = "-nam"; + char *css_chunk_3 = "e\"] {rgba(0, 0"; + char *css_chunk_4 = ", 0, 0.1);}"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // set custom callback for token is ready + mycss_entry_token_ready_callback(entry, token_ready_callback); + + // this is example, you can not specify, dy default MyHTML_ENCODING_UTF_8 + mycss_encoding_set(entry, MyHTML_ENCODING_UTF_8); + + // parse css chunks + mycss_parse_chunk(entry, css_chunk_1, strlen(css_chunk_1)); + mycss_parse_chunk(entry, css_chunk_2, strlen(css_chunk_2)); + mycss_parse_chunk(entry, css_chunk_3, strlen(css_chunk_3)); + mycss_parse_chunk(entry, css_chunk_4, strlen(css_chunk_4)); + mycss_parse_chunk_end(entry); + + // release resurces + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + + diff --git a/examples/mycss/selectors_low_level.c b/examples/mycss/selectors_low_level.c new file mode 100644 index 0000000..df91be8 --- /dev/null +++ b/examples/mycss/selectors_low_level.c @@ -0,0 +1,69 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include +#include + +void serialization_callback(const char* data, size_t len, void* ctx) +{ + printf("%.*s", (int)len, data); +} + +int main(int argc, const char * argv[]) +{ + const char *selector = "#hash.class >> [class ~= bebebe]:has( :not( p:last-child ):nth-child(2n+1))"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // parse selectors + printf("Input data:\n"); + printf("\t%s", selector); + printf("\n"); + + mycss_status_t out_status; + mycss_selectors_list_t *list = mycss_selectors_parse(entry->selectors, MyHTML_ENCODING_UTF_8, selector, strlen(selector), &out_status); + + /* print result */ + printf("Result:\n\t"); + mycss_selectors_serialization_list(entry->selectors, list, serialization_callback, NULL); + printf("\n"); + + // destroy all + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + + diff --git a/examples/mycss/stylesheet_low_level.c b/examples/mycss/stylesheet_low_level.c new file mode 100644 index 0000000..2e19abe --- /dev/null +++ b/examples/mycss/stylesheet_low_level.c @@ -0,0 +1,71 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +void serialization_callback(const char* data, size_t len, void* ctx) +{ + printf("%.*s", (int)len, data); +} + +int main(int argc, const char * argv[]) +{ + const char *css = +"@namespace html \"http://www.w3.org/1999/xhtml\";\n\ +div > html|span:has(~ [class~=best i]) {width: 30%; height: 120.46px}\n\ +:not(h1, h2, h3, h4, h5) {}\n\ +body > div[id*=mu i]:not(:nth-child(2n+1)) {width: 1.4%}"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // parse selectors + printf("Input data:\n"); + printf("%s", css); + printf("\n\n"); + + status = mycss_parse(entry, MyHTML_ENCODING_UTF_8, css, strlen(css)); + + /* print result */ + printf("Result:\n"); + mycss_namespace_serialization_stylesheet(&entry->stylesheet->ns_stylesheet, serialization_callback, NULL); + mycss_stylesheet_serialization(entry->stylesheet, serialization_callback, NULL); + printf("\n"); + + // destroy all + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + diff --git a/examples/mycss/token_type_convert_high_level.c b/examples/mycss/token_type_convert_high_level.c new file mode 100644 index 0000000..9767854 --- /dev/null +++ b/examples/mycss/token_type_convert_high_level.c @@ -0,0 +1,84 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +mycss_token_t * token_ready_callback(mycss_entry_t* entry, mycss_token_t* token) +{ + myhtml_string_t str; + mycss_token_data_to_string(entry, token, &str, true); + + if(mycss_token_type(token) == MyCSS_TOKEN_TYPE_NUMBER) + { + double return_num; + mycss_convert_data_to_double(myhtml_string_data(&str), myhtml_string_length(&str), &return_num, NULL); + + printf("Number %s: %f\n", myhtml_string_data(&str), return_num); + } + else if(mycss_token_type(token) == MyCSS_TOKEN_TYPE_UNICODE_RANGE) + { + size_t start, end; + mycss_convert_unicode_range_to_codepoint(myhtml_string_data(&str), myhtml_string_length(&str), + &start, &end); + + if(end) + printf("Unicode range U+%s: %zu-%zu\n", myhtml_string_data(&str), start, end); + else + printf("Unicode range U+%s: %zu\n", myhtml_string_data(&str), start); + } + + myhtml_string_destroy(&str, false); + + return token; +} + +int main(int argc, const char * argv[]) +{ + char *css = "U+0A, U+12??, U+0030-127 1035 -3.14E+6"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // set custom callback for token is ready + mycss_entry_token_ready_callback(entry, token_ready_callback); + + // parse css + mycss_parse(entry, MyHTML_ENCODING_UTF_8, css, strlen(css)); + + // release resurces + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + diff --git a/examples/mycss/tokenizer_buffer_high_level.c b/examples/mycss/tokenizer_buffer_high_level.c new file mode 100644 index 0000000..b47f254 --- /dev/null +++ b/examples/mycss/tokenizer_buffer_high_level.c @@ -0,0 +1,82 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +mycss_token_t * token_ready_callback(mycss_entry_t* entry, mycss_token_t* token) +{ + // print token name + size_t tokens_count = mycss_entry_token_count(entry); + mycss_token_type_t token_type = mycss_token_type(token); + + myhtml_string_t str; + mycss_token_data_to_string(entry, token, &str, true); + + printf("Token %zu; %s; \"%s\"\n", tokens_count, + mycss_token_name_by_type(token_type), + myhtml_string_data(&str)); + + myhtml_string_destroy(&str, false); + + return token; +} + +int main(int argc, const char * argv[]) +{ + char *css_chunk_1 = "#ident [name=\"best"; + char *css_chunk_2 = "-name\"] {rgba(0, 0"; + char *css_chunk_3 = ", 0, 0.1);}"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // set custom callback for token is ready + mycss_entry_token_ready_callback(entry, token_ready_callback); + + // this is example, you can not specify, dy default MyHTML_ENCODING_UTF_8 + mycss_encoding_set(entry, MyHTML_ENCODING_UTF_8); + + // parse css chunks + mycss_parse_chunk(entry, css_chunk_1, strlen(css_chunk_1)); + mycss_parse_chunk(entry, css_chunk_2, strlen(css_chunk_2)); + mycss_parse_chunk(entry, css_chunk_3, strlen(css_chunk_3)); + mycss_parse_chunk_end(entry); + + // release resurces + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + + diff --git a/examples/mycss/tokenizer_chunk_high_level.c b/examples/mycss/tokenizer_chunk_high_level.c new file mode 100644 index 0000000..e319095 --- /dev/null +++ b/examples/mycss/tokenizer_chunk_high_level.c @@ -0,0 +1,74 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +mycss_token_t * token_ready_callback(mycss_entry_t* entry, mycss_token_t* token) +{ + size_t tokens_count = mycss_entry_token_count(entry); + mycss_token_type_t token_type = mycss_token_type(token); + + printf("Token %zu: <%s>\n", tokens_count, mycss_token_name_by_type(token_type)); + + return token; +} + +int main(int argc, const char * argv[]) +{ + char *css_chunk_1 = "#ident [name=\"best"; + char *css_chunk_2 = "-name\"] {rgba(0, 0"; + char *css_chunk_3 = ", 0, 0.1);}"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // set custom callback for token is ready + mycss_entry_token_ready_callback(entry, token_ready_callback); + + // this is example, you can not specify, dy default MyHTML_ENCODING_UTF_8 + mycss_encoding_set(entry, MyHTML_ENCODING_UTF_8); + + // parse css chunks + mycss_parse_chunk(entry, css_chunk_1, strlen(css_chunk_1)); + mycss_parse_chunk(entry, css_chunk_2, strlen(css_chunk_2)); + mycss_parse_chunk(entry, css_chunk_3, strlen(css_chunk_3)); + mycss_parse_chunk_end(entry); + + // release resurces + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + + diff --git a/examples/mycss/tokenizer_high_level.c b/examples/mycss/tokenizer_high_level.c new file mode 100644 index 0000000..a42282d --- /dev/null +++ b/examples/mycss/tokenizer_high_level.c @@ -0,0 +1,66 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +mycss_token_t * token_ready_callback(mycss_entry_t* entry, mycss_token_t* token) +{ + size_t tokens_count = mycss_entry_token_count(entry); + mycss_token_type_t token_type = mycss_token_type(token); + + printf("Token %zu: <%s>\n", tokens_count, mycss_token_name_by_type(token_type)); + + return token; +} + +int main(int argc, const char * argv[]) +{ + char *css = "#ident [name=\"best-name\"] {rgba(0, 0, 0, 0.1);}"; + + // basic init + mycss_t *mycss = mycss_create(); + mycss_status_t status = mycss_init(mycss); + + // check initialization + if (MyCSS_FAILED(status)) return EXIT_FAILURE; + + // current entry work init + mycss_entry_t *entry = mycss_entry_create(); + status = mycss_entry_init(mycss, entry); + + // set custom callback for token is ready + mycss_entry_token_ready_callback(entry, token_ready_callback); + + // parse css + mycss_parse(entry, MyHTML_ENCODING_UTF_8, css, strlen(css)); + + // release resurces + mycss_entry_destroy(entry, true); + mycss_destroy(mycss, true); + + return 0; +} + + + diff --git a/examples/myhtml/attributes_high_level.c b/examples/myhtml/attributes_high_level.c new file mode 100644 index 0000000..d796651 --- /dev/null +++ b/examples/myhtml/attributes_high_level.c @@ -0,0 +1,78 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include +#include + + +int main(int argc, const char * argv[]) +{ + char html[] = "
"; + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse_fragment(tree, MyHTML_ENCODING_UTF_8, html, strlen(html), MyHTML_TAG_DIV, MyHTML_NAMESPACE_HTML); + + // get first DIV from index + myhtml_tag_index_t *tag_index = myhtml_tree_get_tag_index(tree); + myhtml_tag_index_node_t *index_node = myhtml_tag_index_first(tag_index, MyHTML_TAG_DIV); + + myhtml_tree_node_t *node = myhtml_tag_index_tree_node(index_node); + + // print original tree + printf("Original tree:\n"); + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + printf("For a test; Create and delete 100000 attrs...\n"); + for(size_t j = 0; j < 100000; j++) { + myhtml_tree_attr_t *attr = myhtml_attribute_add(tree, node, "key", 3, "value", 5, MyHTML_ENCODING_UTF_8); + myhtml_attribute_delete(tree, node, attr); + } + + // add first attr in first div in tree + myhtml_attribute_add(tree, node, "key", 3, "value", 5, MyHTML_ENCODING_UTF_8); + + printf("Modified tree:\n"); + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + // get attr by key name + myhtml_tree_attr_t *gets_attr = myhtml_attribute_by_key(node, "key", 3); + const char *attr_char = myhtml_attribute_value(gets_attr, NULL); + + printf("Get attr by key name \"key\": %s\n", attr_char); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + diff --git a/examples/myhtml/callback_tree_node_high_level.c b/examples/myhtml/callback_tree_node_high_level.c new file mode 100644 index 0000000..c0fe589 --- /dev/null +++ b/examples/myhtml/callback_tree_node_high_level.c @@ -0,0 +1,131 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include + +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +void callback_node_insert(myhtml_tree_t* tree, myhtml_tree_node_t* node, void* ctx) +{ + const char *tag_name = myhtml_tag_name_by_id(tree, myhtml_node_tag_id(node), NULL); + const char *tag_name_parent = myhtml_tag_name_by_id(tree, myhtml_node_tag_id( myhtml_node_parent(node) ), NULL); + + printf("Insert %s to parent %s\n", tag_name, tag_name_parent); +} + +void callback_node_remove(myhtml_tree_t* tree, myhtml_tree_node_t* node, void* ctx) +{ + const char *tag_name = myhtml_tag_name_by_id(tree, myhtml_node_tag_id(node), NULL); + const char *tag_name_parent = myhtml_tag_name_by_id(tree, myhtml_node_tag_id( myhtml_node_parent(node) ), NULL); + + printf("Remove %s from parent %s\n", tag_name, tag_name_parent); +} + + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: callback_tree_node_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // set callbacks + myhtml_callback_tree_node_insert_set(tree, callback_node_insert, NULL); + myhtml_callback_tree_node_remove_set(tree, callback_node_remove, NULL); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + + + diff --git a/examples/myhtml/chunks_high_level.c b/examples/myhtml/chunks_high_level.c new file mode 100644 index 0000000..6a952e5 --- /dev/null +++ b/examples/myhtml/chunks_high_level.c @@ -0,0 +1,81 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include +#include + +int main(int argc, const char * argv[]) +{ + char html[][64] = { + "", + "", + "HTML chun", + "ks parsing", + "
", + "good for me", + "
", + "\0" + }; + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + myhtml_encoding_set(tree, MyHTML_ENCODING_UTF_8); + + for(size_t i = 0; html[i][0]; i++) + { + printf("Parse chunk: %s\n", html[i]); + + // parse html + myhtml_parse_chunk(tree, html[i], strlen(html[i])); + } + + // call to the end + myhtml_parse_chunk_end(tree); + + // print fragment + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + + diff --git a/examples/myhtml/custom_tree_high_level.c b/examples/myhtml/custom_tree_high_level.c new file mode 100644 index 0000000..179ca47 --- /dev/null +++ b/examples/myhtml/custom_tree_high_level.c @@ -0,0 +1,81 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +int main(int argc, const char * argv[]) +{ + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + printf("Init tree\n"); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + myhtml_encoding_set(tree, MyHTML_ENCODING_UTF_8); + + // create nodes + printf("Create DIV element\n"); + myhtml_tree_node_t* base_node = myhtml_node_create(tree, MyHTML_TAG_DIV, MyHTML_NAMESPACE_HTML); + myhtml_node_insert_to_appropriate_place(tree, myhtml_tree_get_document(tree), base_node); + + printf("Create and append to DIV element 100 000 P elements\n"); + char tmp_buf_key[128]; + char tmp_buf_value[128]; + char tmp_buf_text[128]; + + for (size_t i = 1; i < 100001; i++) { + myhtml_tree_node_t* new_p_node = myhtml_node_create(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML); + myhtml_node_append_child(tree, base_node, new_p_node); + + myhtml_tree_node_t* new_text_node = myhtml_node_create(tree, MyHTML_TAG__TEXT, MyHTML_NAMESPACE_HTML); + myhtml_node_append_child(tree, new_p_node, new_text_node); + + sprintf(tmp_buf_key, "best_key_for_%zu", i); + sprintf(tmp_buf_value, "for best value %zu", i); + sprintf(tmp_buf_text, "Text! Entity &#%zu = &#%zu", i, i); + + myhtml_node_text_set_with_charef(tree, new_text_node, + tmp_buf_text, strlen(tmp_buf_text), MyHTML_ENCODING_UTF_8); + + myhtml_attribute_add(tree, new_p_node, + tmp_buf_key, strlen(tmp_buf_key), + tmp_buf_value, strlen(tmp_buf_value), MyHTML_ENCODING_UTF_8); + } + + // print + printf("Print result:\n"); + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + diff --git a/examples/myhtml/detect_encoding_high_level.c b/examples/myhtml/detect_encoding_high_level.c new file mode 100644 index 0000000..73b8a18 --- /dev/null +++ b/examples/myhtml/detect_encoding_high_level.c @@ -0,0 +1,128 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +void print_encoding(myhtml_encoding_t encoding) +{ + printf("Character encoding is "); + + switch (encoding) { + case MyHTML_ENCODING_UTF_8: printf("UTF-8"); break; + case MyHTML_ENCODING_UTF_16LE: printf("UTF_16LE"); break; + case MyHTML_ENCODING_UTF_16BE: printf("UTF_16BE"); break; + case MyHTML_ENCODING_KOI8_R: printf("KOI8_R"); break; + case MyHTML_ENCODING_WINDOWS_1251: printf("WINDOWS_1251"); break; + case MyHTML_ENCODING_X_MAC_CYRILLIC: printf("X_MAC_CYRILLIC"); break; + case MyHTML_ENCODING_IBM866: printf("IBM866"); break; + case MyHTML_ENCODING_ISO_8859_5: printf("ISO_8859_5"); break; + default: + printf("UNKNOWN"); + break; + } + + printf("\n"); +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: detect_encoding_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + myhtml_encoding_t encoding; + + // try detect by BOM + if (myhtml_encoding_detect_bom(res.html, res.size, &encoding)) { + print_encoding(encoding); + } else if (myhtml_encoding_detect(res.html, res.size, &encoding)) { + print_encoding(encoding); + } else if (encoding != MyHTML_ENCODING_DEFAULT) { + printf("It is possible that "); + print_encoding(encoding); + } else { + printf("I could not identify character encoding\n"); + } + + free(res.html); + return 0; +} + + + + diff --git a/examples/myhtml/encoding_by_name_high_level.c b/examples/myhtml/encoding_by_name_high_level.c new file mode 100644 index 0000000..4e669b0 --- /dev/null +++ b/examples/myhtml/encoding_by_name_high_level.c @@ -0,0 +1,47 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +int main(int argc, const char * argv[]) +{ + const char *name = "cp1251"; + myhtml_encoding_t encoding; + + if(myhtml_encoding_by_name(name, strlen(name), &encoding)) + { + if(encoding == MyHTML_ENCODING_WINDOWS_1251) { + printf("Detected Encoding: windows-1251\n"); + return 0; + } + } + + printf("Detected Encoding: something wrong\n"); + + return 0; +} + + + + diff --git a/examples/myhtml/fragment_high_level.c b/examples/myhtml/fragment_high_level.c new file mode 100644 index 0000000..8c032f0 --- /dev/null +++ b/examples/myhtml/fragment_high_level.c @@ -0,0 +1,54 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include +#include + + +int main(int argc, const char * argv[]) +{ + char html[] = "
Best of Fragmentsclick to make happy
"; + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse_fragment(tree, MyHTML_ENCODING_UTF_8, html, strlen(html), MyHTML_TAG_DIV, MyHTML_NAMESPACE_HTML); + + // print fragment + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + + diff --git a/examples/myhtml/get_by_index_high_level.c b/examples/myhtml/get_by_index_high_level.c new file mode 100644 index 0000000..c15512d --- /dev/null +++ b/examples/myhtml/get_by_index_high_level.c @@ -0,0 +1,64 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include + +#include + +int main(int argc, const char * argv[]) +{ + char html[] = "
oneBest of Fragmentsclick to make happy
two
three
"; + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, html, (sizeof(html) - 1)); + + myhtml_tag_index_t *tag_index = myhtml_tree_get_tag_index(tree); + myhtml_tag_index_node_t *index_node = myhtml_tag_index_first(tag_index, MyHTML_TAG_DIV); + + printf("Count of DIV nodes in index: %zu\n", myhtml_tag_index_entry_count(tag_index, MyHTML_TAG_DIV)); + printf("Get all DIV nodes from index:\n"); + + while (index_node) { + // print node + myhtml_tree_print_node(tree, myhtml_tag_index_tree_node(index_node), stdout); + + // get next node from index + index_node = myhtml_tag_index_next(index_node); + } + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + + diff --git a/examples/myhtml/get_title_high_level.c b/examples/myhtml/get_title_high_level.c new file mode 100644 index 0000000..a05fdd0 --- /dev/null +++ b/examples/myhtml/get_title_high_level.c @@ -0,0 +1,124 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: get_title_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + // parse html + myhtml_collection_t *collection = myhtml_get_nodes_by_tag_id(tree, NULL, MyHTML_TAG_TITLE, NULL); + + if(collection && collection->list && collection->length) { + myhtml_tree_node_t *text_node = myhtml_node_child(collection->list[0]); + + if(text_node) { + const char* text = myhtml_node_text(text_node, NULL); + + if(text) + printf("Title: %s\n", text); + } + } + + // release resources + myhtml_collection_destroy(collection); + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + + + diff --git a/examples/myhtml/get_title_low_level.c b/examples/myhtml/get_title_low_level.c new file mode 100644 index 0000000..911b021 --- /dev/null +++ b/examples/myhtml/get_title_low_level.c @@ -0,0 +1,119 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: get_title_low_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + // get title from index + if(tree->indexes) + { + myhtml_tag_index_node_t *node_index = myhtml_tag_index_first(tree->indexes->tags, MyHTML_TAG_TITLE); + + if(node_index && node_index->node) { + myhtml_tree_print_by_node(tree, node_index->node, stdout, 0); + } + } + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + + + diff --git a/examples/myhtml/html2sexpr.c b/examples/myhtml/html2sexpr.c new file mode 100644 index 0000000..92669ad --- /dev/null +++ b/examples/myhtml/html2sexpr.c @@ -0,0 +1,178 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Authors: insoreiges@gmail.com (Evgeny Yakovlev) + + html2sexpr + Convert html tag tree into s-expression string in stdout +*/ + +#include +#include +#include +#include + +#include + +#define DIE(msg, ...) do { fprintf(stderr, msg, ##__VA_ARGS__); exit(EXIT_FAILURE); } while(0) + +static bool filter_node(myhtml_tree_node_t* node) +{ + assert(node); + myhtml_tag_id_t tag = myhtml_node_tag_id(node); + return (tag != MyHTML_TAG__TEXT) && (tag != MyHTML_TAG__END_OF_FILE) && (tag != MyHTML_TAG__COMMENT) && (tag != MyHTML_TAG__UNDEF); +} + +/* depth-first lefthand tree walk */ +static void walk_subtree(myhtml_tree_t* tree, myhtml_tree_node_t* root, int level) +{ + if (!root) { + return; + } + + /* Check if we handle this node type */ + if (!filter_node(root)) { + return; + } + + /* start sexpr */ + putchar('('); + + /* print this node */ + printf("%s", myhtml_tag_name_by_id(tree, myhtml_node_tag_id(root), NULL)); + myhtml_tree_attr_t* attr = myhtml_node_attribute_first(root); + while (attr != NULL) { + /* attribute sexpr (name value)*/ + const char *key = myhtml_attribute_key(attr, NULL); + const char *value = myhtml_attribute_value(attr, NULL); + + if(key == NULL) + printf("(KEY IS NULL)"); + else if (value) + printf("(%s \'%s\')", key, value); + else + printf("(%s)", key); + + attr = myhtml_attribute_next(attr); + } + + /* left hand depth-first recoursion */ + myhtml_tree_node_t* child = myhtml_node_child(root); + while (child != NULL) { + walk_subtree(tree, child, level + 1); + child = myhtml_node_next(child); + } + + /* close sexpr */ + putchar(')'); +} + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + DIE("Can't open html file: %s\n", filename); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + DIE("Can't set position (fseek) in file: %s\n", filename); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + DIE("Can't set position (fseek) in file: %s\n", filename); + } + + if(size <= 0) { + fclose(fh); + + struct res_html res = {NULL, 0}; + return res; + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + DIE("Can't allocate mem for html file: %s\n", filename); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + DIE("could not read %ld bytes (%zu bytes done)\n", size, nread); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +static void usage(void) +{ + fprintf(stderr, "html2sexpr \n"); +} + +int main(int argc, char** argv) +{ + if (argc != 2) { + usage(); + DIE("Invalid number of arguments\n"); + } + + struct res_html data = load_html_file(argv[1]); + myhtml_status_t res; + + // basic init + myhtml_t* myhtml = myhtml_create(); + if (!myhtml) { + DIE("myhtml_create failed\n"); + } + + res = myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + if (MYHTML_FAILED(res)) { + DIE("myhtml_init failed with %d\n", res); + } + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + if (!tree) { + DIE("myhtml_tree_create failed\n"); + } + + res = myhtml_tree_init(tree, myhtml); + if (MYHTML_FAILED(res)) { + DIE("myhtml_tree_init failed with %d\n", res); + } + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, data.html, data.size); + + walk_subtree(tree, myhtml_tree_get_node_html(tree), 0); + printf("\n"); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + free(data.html); + + return EXIT_SUCCESS; +} diff --git a/examples/myhtml/insert_in_appropriate_place_high_level.c b/examples/myhtml/insert_in_appropriate_place_high_level.c new file mode 100644 index 0000000..212a534 --- /dev/null +++ b/examples/myhtml/insert_in_appropriate_place_high_level.c @@ -0,0 +1,66 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include +#include + + +int main(int argc, const char * argv[]) +{ + char html[] = "
text
table
"; + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse_fragment(tree, MyHTML_ENCODING_UTF_8, html, strlen(html), MyHTML_TAG_DIV, MyHTML_NAMESPACE_HTML); + + // get text node by index + myhtml_collection_t *collection = myhtml_get_nodes_by_tag_id(tree, NULL, MyHTML_TAG_TABLE, NULL); + + if(collection && collection->list && collection->length) + { + myhtml_tree_node_t *table = collection->list[0]; + + myhtml_tree_node_t* node_a = myhtml_node_create(tree, MyHTML_TAG_A, MyHTML_NAMESPACE_HTML); + myhtml_node_insert_to_appropriate_place(tree, table, node_a); + } + + // print fragment + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + // release resources + myhtml_collection_destroy(collection); + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + + diff --git a/examples/myhtml/modify_and_serialize.c b/examples/myhtml/modify_and_serialize.c new file mode 100644 index 0000000..8966492 --- /dev/null +++ b/examples/myhtml/modify_and_serialize.c @@ -0,0 +1,92 @@ +/** + * modify_and_serialize.c + * + * Test script that checks whether a document can be read, modified and + * serialized + * + * @author Emiel Bruijntjes + * @copyright 2016 Copernica BV + */ + +/** + * Dependencies + */ +#include +#include +#include +#include + +/** + * Write output + * @param buffer + * @param size + * @param ptr + */ +void write_output(const char *buffer, size_t size, void *ptr) +{ + fwrite(buffer, 1, size, stdout); +} + +/** + * Main procedure + * @return int + */ +int main() +{ + // initalize html engine + myhtml_t *myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t *tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // input string + const char *input = ""; + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, input, strlen(input)); + + // collection of links + myhtml_collection_t *collection = myhtml_get_nodes_by_name(tree, NULL, "a", 1, NULL); + + // iterate over all nodes + for (size_t i = 0; i < collection->length; ++i) + { + // add attribute + myhtml_attribute_add(tree, collection->list[i], "title", 5, "my value", 8, MyHTML_ENCODING_UTF_8); + } + + + // write the document again + myhtml_serialization_tree_callback(tree, myhtml_tree_get_document(tree), write_output, NULL); + + /* + + // parse html + myhtml_collection_t *collection = myhtml_get_nodes_by_tag_id(tree, NULL, MyHTML_TAG_TITLE, NULL); + + if(collection && collection->list && collection->length) { + myhtml_tree_node_t *text_node = myhtml_node_child(collection->list[0]); + + if(text_node) { + const char* text = myhtml_node_text(text_node, NULL); + + if(text) + printf("Title: %s\n", text); + } + } + + // release resources + myhtml_collection_destroy(collection); + * + * + */ + myhtml_collection_destroy(collection); + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + // done + return 0; +} + diff --git a/examples/myhtml/nodes_by_attr_key_high_level.c b/examples/myhtml/nodes_by_attr_key_high_level.c new file mode 100644 index 0000000..7787031 --- /dev/null +++ b/examples/myhtml/nodes_by_attr_key_high_level.c @@ -0,0 +1,120 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + const char* attr_key; + + if (argc == 3) { + attr_key = argv[1]; + path = argv[2]; + } + else { + printf("Bad ARGV!\nUse: nodes_by_attr_key_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + // get and print + myhtml_collection_t *collection = myhtml_get_nodes_by_attribute_key(tree, NULL, NULL, attr_key, strlen(attr_key), NULL); + + for(size_t i = 0; i < collection->length; i++) + myhtml_tree_print_node(tree, collection->list[i], stdout); + + printf("Total found: %zu\n", collection->length); + + myhtml_collection_destroy(collection); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + diff --git a/examples/myhtml/nodes_by_attr_value_high_level.c b/examples/myhtml/nodes_by_attr_value_high_level.c new file mode 100644 index 0000000..587252f --- /dev/null +++ b/examples/myhtml/nodes_by_attr_value_high_level.c @@ -0,0 +1,246 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include +#include +#include + +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_argv { + bool is_insensitive; + + const char* key; + size_t key_length; + + size_t search_type; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +void print_usage(void) +{ + printf("Bad ARGV!\nUse:\n"); + printf("\tnodes_by_attr_value_high_level [--type ~= --key key_name -i]\n"); + printf("\t--type: One of: =, ~=, ^=, $=, *=, |=; Default: =; Optional\n"); + printf("\t--key: search value in key; Optional\n"); + printf("\t-i: search value in case-insensitive mode; any value; Optional\n"); +} + +struct res_argv get_argv(int len, int argc, const char ** argv) +{ + struct res_argv rargv; + memset(&rargv, 0, sizeof(struct res_argv)); + + while(len < argc) + { + if(strcmp("-i", argv[len]) == 0) { + rargv.is_insensitive = true; + } + else if(strcmp("--key", argv[len]) == 0) { + len++; + + if(len >= argc) { + print_usage(); + exit(EXIT_FAILURE); + } + + rargv.key = argv[len]; + rargv.key_length = strlen(argv[len]); + } + else if(strcmp("--type", argv[len]) == 0) { + len++; + + if(len >= argc) { + print_usage(); + exit(EXIT_FAILURE); + } + + if(strcmp("=", argv[len]) == 0) { + rargv.search_type = 0; + } + else if(strcmp("~=", argv[len]) == 0) { + rargv.search_type = 1; + } + else if(strcmp("^=", argv[len]) == 0) { + rargv.search_type = 2; + } + else if(strcmp("$=", argv[len]) == 0) { + rargv.search_type = 3; + } + else if(strcmp("*=", argv[len]) == 0) { + rargv.search_type = 4; + } + else if(strcmp("|=", argv[len]) == 0) { + rargv.search_type = 5; + } + else { + print_usage(); + exit(EXIT_FAILURE); + } + } + else { + print_usage(); + exit(EXIT_FAILURE); + } + + len++; + } + + return rargv; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + const char* attr_value; + + struct res_argv rargv; + + if(argc > 2) { + path = argv[1]; + attr_value = argv[2]; + + rargv = get_argv(3, argc, argv); + } + else { + print_usage(); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + // get and print + myhtml_collection_t* collection = NULL; + + switch (rargv.search_type) { + case 0: + collection = myhtml_get_nodes_by_attribute_value(tree, NULL, NULL, rargv.is_insensitive, + rargv.key, rargv.key_length, + attr_value, strlen(attr_value), NULL); + break; + case 1: + collection = myhtml_get_nodes_by_attribute_value_whitespace_separated(tree, NULL, NULL, rargv.is_insensitive, + rargv.key, rargv.key_length, + attr_value, strlen(attr_value), NULL); + break; + case 2: + collection = myhtml_get_nodes_by_attribute_value_begin(tree, NULL, NULL, rargv.is_insensitive, + rargv.key, rargv.key_length, + attr_value, strlen(attr_value), NULL); + break; + case 3: + collection = myhtml_get_nodes_by_attribute_value_end(tree, NULL, NULL, rargv.is_insensitive, + rargv.key, rargv.key_length, + attr_value, strlen(attr_value), NULL); + break; + case 4: + collection = myhtml_get_nodes_by_attribute_value_contain(tree, NULL, NULL, rargv.is_insensitive, + rargv.key, rargv.key_length, + attr_value, strlen(attr_value), NULL); + break; + case 5: + collection = myhtml_get_nodes_by_attribute_value_hyphen_separated(tree, NULL, NULL, rargv.is_insensitive, + rargv.key, rargv.key_length, + attr_value, strlen(attr_value), NULL); + break; + + default: + print_usage(); + exit(EXIT_FAILURE); + } + + if(collection) { + for(size_t i = 0; i < collection->length; i++) + myhtml_tree_print_node(tree, collection->list[i], stdout); + + printf("Total found: %zu\n", collection->length); + } + + myhtml_collection_destroy(collection); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + diff --git a/examples/myhtml/parse_without_whitespace.c b/examples/myhtml/parse_without_whitespace.c new file mode 100644 index 0000000..3eab61d --- /dev/null +++ b/examples/myhtml/parse_without_whitespace.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include + +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: get_title_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // set parse flags + myhtml_tree_parse_flags_set(tree, + MyHTML_TREE_PARSE_FLAGS_SKIP_WHITESPACE_TOKEN| + MyHTML_TREE_PARSE_FLAGS_WITHOUT_DOCTYPE_IN_TREE); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + if(myhtml_tree_get_node_html(tree)) + myhtml_tree_print_by_node(tree, myhtml_tree_get_node_html(tree), stdout, 0); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + diff --git a/examples/myhtml/print_tree_high_level.c b/examples/myhtml/print_tree_high_level.c new file mode 100644 index 0000000..fbdba87 --- /dev/null +++ b/examples/myhtml/print_tree_high_level.c @@ -0,0 +1,171 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +void print_node_attr(myhtml_tree_node_t *node) +{ + myhtml_tree_attr_t *attr = myhtml_node_attribute_first(node); + + while (attr) { + const char *name = myhtml_attribute_key(attr, NULL); + + if(name) { + printf(" %s", name); + + const char *value = myhtml_attribute_value(attr, NULL); + + if(value) + printf("=\"%s\"", value); + } + + attr = myhtml_attribute_next(attr); + } +} + +void print_tree(myhtml_tree_t* tree, myhtml_tree_node_t *node, size_t inc) +{ + while (node) + { + for(size_t i = 0; i < inc; i++) + printf("\t"); + + // print current element + const char *tag_name = myhtml_tag_name_by_id(tree, myhtml_node_tag_id(node), NULL); + + if(tag_name) + printf("<%s", tag_name); + else + // it can not be + printf(": %s\n", node_text); + } + else { + printf(">\n"); + } + + // print children + print_tree(tree, myhtml_node_child(node), (inc + 1)); + node = myhtml_node_next(node); + } +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: print_tree_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + // print tree + myhtml_tree_node_t *node = myhtml_tree_get_document(tree); + print_tree(tree, myhtml_node_child(node), 0); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + + + diff --git a/examples/myhtml/serialization_high_level.c b/examples/myhtml/serialization_high_level.c new file mode 100644 index 0000000..5f1c816 --- /dev/null +++ b/examples/myhtml/serialization_high_level.c @@ -0,0 +1,122 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: serialization_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + myhtml_string_raw_t str_raw; + myhtml_string_raw_clean_all(&str_raw); + + if(myhtml_serialization_tree_buffer(tree, myhtml_tree_get_document(tree), &str_raw)) { + /* + or myhtml_tree_get_node_html(tree) or myhtml_tree_get_node_head(tree) + or myhtml_tree_get_node_body(tree) or some node + */ + + printf("%s", str_raw.data); + myhtml_string_raw_destroy(&str_raw, false); + } + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + + + diff --git a/examples/myhtml/string_manipulate_high_level.c b/examples/myhtml/string_manipulate_high_level.c new file mode 100644 index 0000000..5e515ee --- /dev/null +++ b/examples/myhtml/string_manipulate_high_level.c @@ -0,0 +1,84 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include +#include +#include + + +int main(int argc, const char * argv[]) +{ + char html[] = "
text for manipulate
"; + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, html, strlen(html)); + + // print original tree + printf("Original Tree:\n"); + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + printf("Change word: manipulate => test\n"); + + // get text node by index + myhtml_collection_t *collection = myhtml_get_nodes_by_tag_id(tree, NULL, MyHTML_TAG__TEXT, NULL); + + if(collection && collection->list && collection->length) + { + myhtml_tree_node_t *text_node = collection->list[0]; + myhtml_string_t *str = myhtml_node_string(text_node); + + // change data + char *data = myhtml_string_data(str); + + for (size_t i = 0; i < myhtml_string_length(str); i++) + { + if(data[i] == 'm') { + sprintf(&data[i], "test"); + + // set new length + myhtml_string_length_set(str, (i + 4)); + break; + } + } + } + + printf("Changed Tree:\n"); + // print tree + myhtml_tree_print_node_children(tree, myhtml_tree_get_document(tree), stdout, 0); + + // release resources + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + return 0; +} + + + + diff --git a/examples/myhtml/tokenizer_colorize_high_level.c b/examples/myhtml/tokenizer_colorize_high_level.c new file mode 100644 index 0000000..8149d1b --- /dev/null +++ b/examples/myhtml/tokenizer_colorize_high_level.c @@ -0,0 +1,225 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include + +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +void colorize_print(myhtml_incoming_buffer_t *inc_buf, size_t begin, size_t length, const char* color) +{ + if(length) { + inc_buf = myhtml_incoming_buffer_find_by_position(inc_buf, begin); + + size_t between_begin = (begin - myhtml_incoming_buffer_offset(inc_buf)); + const char* between_data = myhtml_incoming_buffer_data(inc_buf); + + printf("%s%.*s\e[0m", color, (int)length, &between_data[between_begin]); + } +} + +size_t colorize_print_attributes(myhtml_tree_t* tree, myhtml_tree_attr_t* attr, myhtml_incoming_buffer_t *inc_buf, size_t last_pos) +{ + while(attr) + { + myhtml_position_t key_pos = myhtml_attribute_key_raw_position(attr); + myhtml_position_t value_pos = myhtml_attribute_value_raw_position(attr); + + if(key_pos.length) + { + /* print */ + if(last_pos < key_pos.begin) + colorize_print(inc_buf, last_pos, (key_pos.begin - last_pos), "\e[31m"); + + /* print
*/ + colorize_print(inc_buf, key_pos.begin, key_pos.length, "\e[33m"); + + /* get/check max position */ + if((key_pos.begin + key_pos.length) > last_pos) + last_pos = key_pos.begin + key_pos.length; + } + else { + /* print */ + if(value_pos.length && last_pos < value_pos.begin) + colorize_print(inc_buf, last_pos, (value_pos.begin - last_pos), "\e[31m"); + } + + if(value_pos.length) + { + /* print
*/ + if(key_pos.length) { + size_t between_begin = key_pos.begin + key_pos.length; + colorize_print(inc_buf, between_begin, (value_pos.begin - between_begin), "\e[31m"); + } + + /* print
*/ + colorize_print(inc_buf, value_pos.begin, value_pos.length, "\e[34m"); + + /* get/check max position */ + if(value_pos.begin + value_pos.length > last_pos) + last_pos = value_pos.begin + value_pos.length; + } + + attr = myhtml_attribute_next(attr); + } + + return last_pos; +} + +void * colorize_callback_before_token_done(myhtml_tree_t* tree, myhtml_token_node_t* token, void* ctx) +{ + myhtml_incoming_buffer_t *inc_buf = myhtml_tree_incoming_buffer_first(tree); + + myhtml_position_t token_pos = myhtml_token_node_raw_pasition(token); + myhtml_position_t token_element_pos = myhtml_token_node_element_pasition(token); + + size_t last_pos = token_pos.begin + token_pos.length; + + switch (myhtml_token_node_tag_id(token)) { + case MyHTML_TAG__DOCTYPE: { + /* print [] */ + colorize_print(inc_buf, last_pos, ((token_element_pos.begin + token_element_pos.length) - last_pos), "\e[37m"); + break; + } + case MyHTML_TAG__TEXT: { + colorize_print(inc_buf, token_pos.begin, token_pos.length, "\e[0m"); + break; + } + case MyHTML_TAG__COMMENT: { + /* print [] */ + colorize_print(inc_buf, last_pos, ((token_element_pos.begin + token_element_pos.length) - last_pos), "\e[32m"); + break; + } + default: { + /* print [<]div> */ + colorize_print(inc_buf, token_element_pos.begin, (token_pos.begin - token_element_pos.begin), "\e[31m"); + + /* print <[div]> */ + colorize_print(inc_buf, token_pos.begin, token_pos.length, "\e[31m"); + + if(myhtml_token_node_attribute_first(token)) + last_pos = colorize_print_attributes(tree, myhtml_token_node_attribute_first(token), inc_buf, last_pos); + + /* print ] */ + colorize_print(inc_buf, last_pos, ((token_element_pos.begin + token_element_pos.length) - last_pos), "\e[31m"); + + break; + } + } + + return ctx; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: tokenizer_colorize_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + myhtml_callback_before_token_done_set(tree, colorize_callback_before_token_done, NULL); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + printf("\n"); + + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + diff --git a/examples/myhtml/tokenizer_colorize_low_level.c b/examples/myhtml/tokenizer_colorize_low_level.c new file mode 100644 index 0000000..e59cb19 --- /dev/null +++ b/examples/myhtml/tokenizer_colorize_low_level.c @@ -0,0 +1,215 @@ +/* + Copyright (C) 2015-2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include +#include + +#include + +struct res_html { + char *html; + size_t size; +}; + +struct res_html load_html_file(const char* filename) +{ + FILE *fh = fopen(filename, "rb"); + if(fh == NULL) { + fprintf(stderr, "Can't open html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(fseek(fh, 0L, SEEK_END) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + long size = ftell(fh); + + if(fseek(fh, 0L, SEEK_SET) != 0) { + fprintf(stderr, "Can't set position (fseek) in file: %s\n", filename); + exit(EXIT_FAILURE); + } + + if(size <= 0) { + fprintf(stderr, "Can't get file size or file is empty: %s\n", filename); + exit(EXIT_FAILURE); + } + + char *html = (char*)malloc(size + 1); + if(html == NULL) { + fprintf(stderr, "Can't allocate mem for html file: %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t nread = fread(html, 1, size, fh); + if (nread != size) { + fprintf(stderr, "could not read %ld bytes (%zu bytes done)\n", size, nread); + exit(EXIT_FAILURE); + } + + fclose(fh); + + struct res_html res = {html, (size_t)size}; + return res; +} + +void colorize_print(myhtml_incoming_buffer_t *inc_buf, size_t begin, size_t length, const char* color) +{ + if(length) { + inc_buf = myhtml_incoming_buffer_find_by_position(inc_buf, begin); + printf("%s%.*s\e[0m", color, (int)length, &inc_buf->data[(begin - inc_buf->offset)]); + } +} + +size_t colorize_print_attributes(myhtml_tree_t* tree, myhtml_tree_attr_t* attr, myhtml_incoming_buffer_t *inc_buf, size_t last_pos) +{ + while(attr) { + if(attr->raw_key_length) + { + /* print */ + if(last_pos < attr->raw_key_begin) + colorize_print(inc_buf, last_pos, (attr->raw_key_begin - last_pos), "\e[31m"); + + /* print
*/ + colorize_print(inc_buf, attr->raw_key_begin, attr->raw_key_length, "\e[33m"); + + /* get/check max position */ + if((attr->raw_key_begin + attr->raw_key_length) > last_pos) + last_pos = attr->raw_key_begin + attr->raw_key_length; + } + else { + /* print */ + if(attr->raw_value_length && last_pos < attr->raw_value_begin) + colorize_print(inc_buf, last_pos, (attr->raw_value_begin - last_pos), "\e[31m"); + } + + if(attr->raw_value_length) + { + /* print
*/ + if(attr->raw_key_length) { + size_t between_begin = attr->raw_key_begin + attr->raw_key_length; + colorize_print(inc_buf, between_begin, (attr->raw_value_begin - between_begin), "\e[31m"); + } + + /* print
*/ + colorize_print(inc_buf, attr->raw_value_begin, attr->raw_value_length, "\e[34m"); + + /* get/check max position */ + if(attr->raw_value_begin + attr->raw_value_length > last_pos) + last_pos = attr->raw_value_begin + attr->raw_value_length; + } + + attr = attr->next; + } + + return last_pos; +} + +void * colorize_callback_before_token_done(myhtml_tree_t* tree, myhtml_token_node_t* token, void* ctx) +{ + myhtml_incoming_buffer_t *inc_buf = tree->incoming_buf_first; + + size_t last_pos = token->raw_begin + token->raw_length; + + switch (token->tag_id) { + case MyHTML_TAG__DOCTYPE: { + /* print [element_begin, (token->raw_begin - token->element_begin), "\e[37m"); + + colorize_print(inc_buf, token->raw_begin, token->raw_length, "\e[37m"); + + /* print [>] */ + colorize_print(inc_buf, last_pos, ((token->element_begin + token->element_length) - last_pos), "\e[37m"); + break; + } + case MyHTML_TAG__TEXT: { + colorize_print(inc_buf, token->raw_begin, token->raw_length, "\e[0m"); + break; + } + case MyHTML_TAG__COMMENT: { + /* print [] */ + colorize_print(inc_buf, last_pos, ((token->element_begin + token->element_length) - last_pos), "\e[32m"); + break; + } + default: { + /* print [<]div> */ + colorize_print(inc_buf, token->element_begin, (token->raw_begin - token->element_begin), "\e[31m"); + + /* print <[div]> */ + colorize_print(inc_buf, token->raw_begin, token->raw_length, "\e[31m"); + + if(token->attr_first) + last_pos = colorize_print_attributes(tree, token->attr_first, inc_buf, last_pos); + + /* print ] */ + colorize_print(inc_buf, last_pos, ((token->element_begin + token->element_length) - last_pos), "\e[31m"); + + break; + } + } + + return ctx; +} + +int main(int argc, const char * argv[]) +{ + const char* path; + + if (argc == 2) { + path = argv[1]; + } + else { + printf("Bad ARGV!\nUse: tokenizer_colorize_high_level \n"); + exit(EXIT_FAILURE); + } + + struct res_html res = load_html_file(path); + + // basic init + myhtml_t* myhtml = myhtml_create(); + myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0); + + // init tree + myhtml_tree_t* tree = myhtml_tree_create(); + myhtml_tree_init(tree, myhtml); + + // set callback + myhtml_callback_before_token_done_set(tree, colorize_callback_before_token_done, NULL); + + // parse html + myhtml_parse(tree, MyHTML_ENCODING_UTF_8, res.html, res.size); + + printf("\n"); + + myhtml_tree_destroy(tree); + myhtml_destroy(myhtml); + + free(res.html); + + return 0; +} + + diff --git a/examples/selectors/selectors_low_level.c b/examples/selectors/selectors_find_nodes_low_level.c similarity index 100% rename from examples/selectors/selectors_low_level.c rename to examples/selectors/selectors_find_nodes_low_level.c diff --git a/include/modest/node/node.h b/include/modest/node/node.h index 4043332..726a3d1 100644 --- a/include/modest/node/node.h +++ b/include/modest/node/node.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #ifdef __cplusplus @@ -40,7 +40,7 @@ struct modest_node { modest_style_raw_declaration_t * raw_declaration[MyCSS_PROPERTY_TYPE_LAST_ENTRY]; #endif /* MODEST_NODE_FULL_RAW */ - modest_layer_t* layer; + modest_render_tree_node_t* render_node; }; modest_node_t * modest_node_create(modest_t* modest); diff --git a/include/modest/render/begin.h b/include/modest/render/begin.h index 58ff5dd..6805d9b 100644 --- a/include/modest/render/begin.h +++ b/include/modest/render/begin.h @@ -22,9 +22,9 @@ #define MODEST_RENDER_BEGIN_H #pragma once -#include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/include/modest/layer/binding.h b/include/modest/render/binding.h similarity index 64% rename from include/modest/layer/binding.h rename to include/modest/render/binding.h index e223186..24a53ce 100644 --- a/include/modest/layer/binding.h +++ b/include/modest/render/binding.h @@ -18,13 +18,16 @@ Author: lex.borisov@gmail.com (Alexander Borisov) */ -#ifndef MODEST_LAYER_BINDING_H -#define MODEST_LAYER_BINDING_H +#ifndef MODEST_RENDER_BINDING_H +#define MODEST_RENDER_BINDING_H #pragma once #include #include #include +#include +#include +#include #include @@ -32,10 +35,12 @@ extern "C" { #endif -modest_layer_t * modest_layer_binding(modest_t* modest, myhtml_tree_t* html_tree); - +modest_render_tree_node_t * modest_render_binding(modest_t* modest, modest_render_tree_t* render_tree, myhtml_tree_t* html_tree); +modest_render_tree_node_t * modest_layer_binding_node(modest_t* modest, modest_render_tree_t* render_tree, + modest_render_tree_node_t* render_root, myhtml_tree_node_t* html_node); + #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* MODEST_LAYER_BINDING_H */ +#endif /* MODEST_RENDER_BINDING_H */ diff --git a/include/modest/render/tree.h b/include/modest/render/tree.h new file mode 100644 index 0000000..3bc5123 --- /dev/null +++ b/include/modest/render/tree.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifndef MODEST_RENDER_TREE_H +#define MODEST_RENDER_TREE_H +#pragma once + +typedef struct modest_render_tree modest_render_tree_t; + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct modest_render_tree { + mcobject_t* mc_nodes; +}; + +modest_render_tree_t * modest_render_tree_create(void); +modest_status_t modest_render_tree_init(modest_render_tree_t* render_tree); +void modest_render_tree_clean_all(modest_render_tree_t* render_tree); +modest_render_tree_t * modest_render_tree_destroy(modest_render_tree_t* render_tree, bool self_destroy); + +void modest_render_tree_serialization(myhtml_tree_t* html_tree, modest_render_tree_t* tree, + modest_render_tree_node_t* scope_node, mycss_callback_serialization_f callback, void* context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_RENDER_TREE_H */ diff --git a/include/modest/render/tree_node.h b/include/modest/render/tree_node.h new file mode 100644 index 0000000..4c39d9d --- /dev/null +++ b/include/modest/render/tree_node.h @@ -0,0 +1,71 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifndef MODEST_RENDER_TREE_NODE_H +#define MODEST_RENDER_TREE_NODE_H +#pragma once + +typedef struct modest_render_tree_node modest_render_tree_node_t; + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum modest_render_tree_node_type { + MODEST_RENDER_TREE_NODE_TYPE_BLOCK = 0, + MODEST_RENDER_TREE_NODE_TYPE_VIEWPORT = 1, + MODEST_RENDER_TREE_NODE_TYPE_ANONYMOUS = 3 +} +typedef modest_render_tree_node_type_t; + +struct modest_render_tree_node { + myhtml_tree_node_t* html_node; + modest_render_tree_node_type_t type; + + /* navigation */ + modest_render_tree_node_t* next; + modest_render_tree_node_t* prev; + modest_render_tree_node_t* child; + modest_render_tree_node_t* child_last; + modest_render_tree_node_t* parent; +}; + +modest_render_tree_node_t * modest_render_tree_node_create_and_init(modest_render_tree_t* render_tree); +void modest_render_tree_node_clean_all(modest_render_tree_node_t* render_node); +modest_render_tree_node_t * modest_render_tree_node_destroy(modest_render_tree_t* render_tree, modest_render_tree_node_t* render_node, bool self_destroy); + +void modest_render_tree_node_append(modest_render_tree_node_t* to, modest_render_tree_node_t* node); +void modest_render_tree_node_remove(modest_render_tree_node_t* node); +void modest_render_tree_node_append_after(modest_render_tree_node_t* target, modest_render_tree_node_t* node); +void modest_render_tree_node_append_before(modest_render_tree_node_t* target, modest_render_tree_node_t* node); + +void modest_render_tree_node_serialization(myhtml_tree_t* html_tree, modest_render_tree_node_t* node, mycss_callback_serialization_f callback, void* context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_RENDER_TREE_NODE_H */ diff --git a/include/myhtml/api.h b/include/myhtml/api.h old mode 100644 new mode 100755 index ad94e84..794b9c7 --- a/include/myhtml/api.h +++ b/include/myhtml/api.h @@ -36,7 +36,7 @@ #define MyHTML_VERSION_MAJOR 1 #define MyHTML_VERSION_MINOR 0 -#define MyHTML_VERSION_PATCH 4 +#define MyHTML_VERSION_PATCH 5 #include #include @@ -577,6 +577,7 @@ typedef myhtml_version_t; // callback functions typedef void* (*myhtml_callback_token_f)(myhtml_tree_t* tree, myhtml_token_node_t* token, void* ctx); typedef void (*myhtml_callback_tree_node_f)(myhtml_tree_t* tree, myhtml_tree_node_t* node, void* ctx); +typedef void (*myhtml_callback_serialize_f)(const char* buffer, size_t size, void* ctx); /*********************************************************************************** * @@ -2714,28 +2715,74 @@ myhtml_strncasecmp(const char* str1, const char* str2, size_t size); ***********************************************************************************/ /** - * Tree fragment serialization - * - * @param[in] myhtml_tree_t* - * @param[in] scope node, myhtml_tree_node_t* - * @param[in] myhtml_string_raw_t* (date to be created if str_raw.data == NULL) - * - * @return true if successful, otherwise false + * Tree fragment serialization + * The same as myhtml_serialization_tree_buffer function */ bool -myhtml_serialization(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, myhtml_string_raw_t* str); +myhtml_serialization(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, + myhtml_string_raw_t* str); /** * Only one tree node serialization + * The same as myhtml_serialization_node_buffer function + */ +bool +myhtml_serialization_node(myhtml_tree_t* tree, myhtml_tree_node_t* node, + myhtml_string_raw_t* str); + +/** + * Serialize tree to an output string * * @param[in] myhtml_tree_t* - * @param[in] myhtml_tree_node_t* - * @param[in] myhtml_string_raw_t* (date to be created if str_raw.data == NULL) + * @param[in] scope node + * @param[in] myhtml_string_raw_t* * * @return true if successful, otherwise false */ bool -myhtml_serialization_node(myhtml_tree_t* tree, myhtml_tree_node_t* node, myhtml_string_raw_t* str); +myhtml_serialization_tree_buffer(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, + myhtml_string_raw_t* str); + +/** + * Serialize node to an output string + * + * @param[in] myhtml_tree_t* + * @param[in] node + * @param[in] myhtml_string_raw_t* + * + * @return true if successful, otherwise false + */ +bool +myhtml_serialization_node_buffer(myhtml_tree_t* tree, myhtml_tree_node_t* node, + myhtml_string_raw_t* str); + +/** + * The serialize function for an entire tree + * + * @param[in] tree the tree to be serialized + * @param[in] scope_node the scope_node + * @param[in] callback function that will be called for all strings that have to be printed + * @param[in] ptr user-supplied pointer + * + * @return true if successful, otherwise false + */ +bool +myhtml_serialization_tree_callback(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, + myhtml_callback_serialize_f callback, void* ptr); + +/** + * The serialize function for a single node + * + * @param[in] tree the tree to be serialized + * @param[in] node the node that is going to be serialized + * @param[in] callback function that will be called for all strings that have to be printed + * @param[in] ptr user-supplied pointer + * + * @return true if successful, otherwise false + */ +bool +myhtml_serialization_node_callback(myhtml_tree_t* tree, myhtml_tree_node_t* node, + myhtml_callback_serialize_f callback, void* ptr); /*********************************************************************************** * diff --git a/include/myhtml/myosi.h b/include/myhtml/myosi.h index 530dd72..4c516a8 100644 --- a/include/myhtml/myosi.h +++ b/include/myhtml/myosi.h @@ -31,7 +31,7 @@ #define MyHTML_VERSION_MAJOR 1 #define MyHTML_VERSION_MINOR 0 -#define MyHTML_VERSION_PATCH 4 +#define MyHTML_VERSION_PATCH 5 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__WINPTHREADS_VERSION) #define IS_OS_WINDOWS diff --git a/source/modest/layer/layout.c b/source/modest/layer/layout.c deleted file mode 100644 index c2af6fd..0000000 --- a/source/modest/layer/layout.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2016 Alexander Borisov - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - Author: lex.borisov@gmail.com (Alexander Borisov) -*/ - -#include "modest/layer/layer.h" - -modest_layout_t * modest_layers_create(void) -{ - return myhtml_calloc(1, sizeof(modest_layout_t)); -} - -modest_status_t modest_layers_init(modest_layout_t* layout) -{ - layout->mc_nodes = mcobject_create(); - if(layout->mc_nodes == NULL) - return MODEST_STATUS_ERROR_MEMORY_ALLOCATION; - - myhtml_status_t myhtml_status = mcobject_init(layout->mc_nodes, 1024, sizeof(modest_layer_t)); - if(myhtml_status) - return MODEST_STATUS_ERROR; - - return MODEST_STATUS_OK; -} - -void modest_layers_clean_all(modest_layout_t* layout) -{ - mcobject_clean(layout->mc_nodes); -} - -modest_layout_t * modest_layers_destroy(modest_layout_t* layout, bool self_destroy) -{ - if(layout == NULL) - return NULL; - - layout->mc_nodes = mcobject_destroy(layout->mc_nodes, true); - - if(self_destroy) { - myhtml_free(layout); - return NULL; - } - - return layout; -} - - diff --git a/source/modest/modest.c b/source/modest/modest.c index d77109c..056228d 100644 --- a/source/modest/modest.c +++ b/source/modest/modest.c @@ -79,15 +79,7 @@ modest_status_t modest_init(modest_t* modest) if(myhtml_status) return MODEST_STATUS_OK; - /* layers */ - modest->layout = modest_layers_create(); - if(modest->layout == NULL) - return MODEST_STATUS_ERROR_MEMORY_ALLOCATION; - - modest_status_t modest_status = modest_layers_init(modest->layout); - if(modest_status) - return MODEST_STATUS_ERROR; - + /* styles tree */ modest->style_avl_tree = myhtml_utils_avl_tree_create(); if(modest->style_avl_tree == NULL) return MODEST_STATUS_ERROR_MEMORY_ALLOCATION; @@ -103,7 +95,6 @@ void modest_clean(modest_t* modest) { mcobject_async_clean(modest->mnode_obj); mcobject_async_clean(modest->mstylesheet_obj); - modest_layers_clean_all(modest->layout); myhtml_utils_avl_tree_clean(modest->style_avl_tree); } @@ -114,7 +105,6 @@ modest_t * modest_destroy(modest_t* modest, bool self_destroy) modest->mnode_obj = mcobject_async_destroy(modest->mnode_obj, true); modest->mstylesheet_obj = mcobject_async_destroy(modest->mstylesheet_obj, true); - modest->layout = modest_layers_destroy(modest->layout, true); modest->style_avl_tree = myhtml_utils_avl_tree_destroy(modest->style_avl_tree, true); if(self_destroy) { diff --git a/source/modest/node/node.h b/source/modest/node/node.h index 00f2e11..3de5b9c 100644 --- a/source/modest/node/node.h +++ b/source/modest/node/node.h @@ -25,7 +25,7 @@ #include "modest/myosi.h" #include "modest/modest.h" #include "modest/style/raw.h" -#include "modest/layer/layer.h" +#include "modest/render/tree_node.h" #include "myhtml/utils/avl_tree.h" #ifdef __cplusplus @@ -40,7 +40,7 @@ struct modest_node { modest_style_raw_declaration_t * raw_declaration[MyCSS_PROPERTY_TYPE_LAST_ENTRY]; #endif /* MODEST_NODE_FULL_RAW */ - modest_layer_t* layer; + modest_render_tree_node_t* render_node; }; modest_node_t * modest_node_create(modest_t* modest); diff --git a/source/modest/render/begin.c b/source/modest/render/begin.c index 1691720..55784c7 100644 --- a/source/modest/render/begin.c +++ b/source/modest/render/begin.c @@ -21,3 +21,5 @@ #include "modest/render/begin.h" + + diff --git a/source/modest/render/begin.h b/source/modest/render/begin.h index 94673d3..53a2b99 100644 --- a/source/modest/render/begin.h +++ b/source/modest/render/begin.h @@ -22,9 +22,9 @@ #define MODEST_RENDER_BEGIN_H #pragma once -#include "modest/myosi.h" #include "modest/modest.h" #include "modest/style/type.h" +#include "modest/render/tree.h" #ifdef __cplusplus extern "C" { diff --git a/source/modest/render/binding.c b/source/modest/render/binding.c new file mode 100644 index 0000000..b767619 --- /dev/null +++ b/source/modest/render/binding.c @@ -0,0 +1,95 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include "modest/render/binding.h" + +modest_render_tree_node_t * modest_render_binding_create_viewport(modest_t* modest, modest_render_tree_t* render_tree) +{ + modest_render_tree_node_t* render_node = modest_render_tree_node_create_and_init(render_tree); + render_node->type = MODEST_RENDER_TREE_NODE_TYPE_VIEWPORT; + + return render_node; +} + +modest_render_tree_node_t * modest_render_binding(modest_t* modest, modest_render_tree_t* render_tree, myhtml_tree_t* html_tree) +{ + myhtml_tree_node_t* html_node = html_tree->node_html; + myhtml_tree_node_t* html_scope = html_node; + + modest_node_t *m_node = html_node->data; + + modest_render_tree_node_t *render_root = modest_render_binding_create_viewport(modest, render_tree); + modest_render_tree_node_t *render_node = render_root; + + while(html_node) { + render_node = modest_layer_binding_node(modest, render_tree, render_node, html_node); + + if(render_node == NULL && html_node->next) { + modest_node_t *m_node = html_node->parent->data; + render_node = m_node->render_node; + + html_node = html_node->next; + } + else if(render_node && html_node->child) + html_node = html_node->child; + else { + while(html_node != html_scope && html_node->next == NULL) { + html_node = html_node->parent; + } + + if(html_node == html_scope) + break; + + modest_node_t *m_node = html_node->parent->data; + render_node = m_node->render_node; + + html_node = html_node->next; + } + } + + return render_root; +} + +modest_render_tree_node_t * modest_layer_binding_node(modest_t* modest, modest_render_tree_t* render_tree, + modest_render_tree_node_t* render_root, myhtml_tree_node_t* html_node) +{ + if(html_node->data == NULL) + return NULL; + + mycss_declaration_entry_t *display = modest_declaration_by_type(modest, html_node, MyCSS_PROPERTY_TYPE_DISPLAY); + + if(display->value_type == MyCSS_PROPERTY_DISPLAY_NONE) + return NULL; + + modest_node_t *m_node = html_node->data; + + if(m_node->render_node == NULL) { + m_node->render_node = modest_render_tree_node_create_and_init(render_tree); + } + + modest_render_tree_node_t* render_node = m_node->render_node; + modest_render_tree_node_append(render_root, render_node); + + render_node->html_node = html_node; + + return render_node; +} + + diff --git a/source/modest/layer/binding.h b/source/modest/render/binding.h similarity index 64% rename from source/modest/layer/binding.h rename to source/modest/render/binding.h index c0b5d00..2f6ad5a 100644 --- a/source/modest/layer/binding.h +++ b/source/modest/render/binding.h @@ -18,13 +18,16 @@ Author: lex.borisov@gmail.com (Alexander Borisov) */ -#ifndef MODEST_LAYER_BINDING_H -#define MODEST_LAYER_BINDING_H +#ifndef MODEST_RENDER_BINDING_H +#define MODEST_RENDER_BINDING_H #pragma once #include "modest/myosi.h" #include "modest/modest.h" #include "modest/node/node.h" +#include "modest/render/tree.h" +#include "modest/render/tree_node.h" +#include "modest/declaration.h" #include "myhtml/tree.h" @@ -32,10 +35,12 @@ extern "C" { #endif -modest_layer_t * modest_layer_binding(modest_t* modest, myhtml_tree_t* html_tree); - +modest_render_tree_node_t * modest_render_binding(modest_t* modest, modest_render_tree_t* render_tree, myhtml_tree_t* html_tree); +modest_render_tree_node_t * modest_layer_binding_node(modest_t* modest, modest_render_tree_t* render_tree, + modest_render_tree_node_t* render_root, myhtml_tree_node_t* html_node); + #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* MODEST_LAYER_BINDING_H */ +#endif /* MODEST_RENDER_BINDING_H */ diff --git a/source/modest/render/tree.c b/source/modest/render/tree.c new file mode 100644 index 0000000..e7cc9d9 --- /dev/null +++ b/source/modest/render/tree.c @@ -0,0 +1,94 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include "modest/render/tree.h" + +modest_render_tree_t * modest_render_tree_create(void) +{ + return myhtml_calloc(1, sizeof(modest_render_tree_t)); +} + +modest_status_t modest_render_tree_init(modest_render_tree_t* render_tree) +{ + render_tree->mc_nodes = mcobject_create(); + if(render_tree->mc_nodes == NULL) + return MODEST_STATUS_ERROR_MEMORY_ALLOCATION; + + myhtml_status_t myhtml_status = mcobject_init(render_tree->mc_nodes, 1024, sizeof(modest_render_tree_node_t)); + if(myhtml_status) + return MODEST_STATUS_ERROR; + + return MODEST_STATUS_OK; +} + +void modest_render_tree_clean_all(modest_render_tree_t* render_tree) +{ + memset(render_tree, 0, sizeof(modest_render_tree_t)); +} + +modest_render_tree_t * modest_render_tree_destroy(modest_render_tree_t* render_tree, bool self_destroy) +{ + if(render_tree == NULL) + return NULL; + + render_tree->mc_nodes = mcobject_destroy(render_tree->mc_nodes, true); + + if(self_destroy) { + myhtml_free(render_tree); + return NULL; + } + + return render_tree; +} + +void modest_render_tree_serialization(myhtml_tree_t* html_tree, modest_render_tree_t* tree, + modest_render_tree_node_t* scope_node, mycss_callback_serialization_f callback, void* context) +{ + modest_render_tree_node_t* node = scope_node; + size_t depth = 0; + + while(node) { + for(size_t i = 0; i < depth; i++) + callback("\t", 1, context); + + modest_render_tree_node_serialization(html_tree, node, callback, context); + callback("\n", 1, context); + + if(node->child) { + depth++; + node = node->child; + } + else { + while(node != scope_node && node->next == NULL) { + depth--; + node = node->parent; + } + + if(node == scope_node) + break; + + node = node->next; + } + } + + +} + + diff --git a/source/modest/render/tree.h b/source/modest/render/tree.h new file mode 100644 index 0000000..1c3966e --- /dev/null +++ b/source/modest/render/tree.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifndef MODEST_RENDER_TREE_H +#define MODEST_RENDER_TREE_H +#pragma once + +typedef struct modest_render_tree modest_render_tree_t; + +#include "modest/modest.h" +#include "myhtml/utils/mcobject.h" +#include "modest/render/tree_node.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct modest_render_tree { + mcobject_t* mc_nodes; +}; + +modest_render_tree_t * modest_render_tree_create(void); +modest_status_t modest_render_tree_init(modest_render_tree_t* render_tree); +void modest_render_tree_clean_all(modest_render_tree_t* render_tree); +modest_render_tree_t * modest_render_tree_destroy(modest_render_tree_t* render_tree, bool self_destroy); + +void modest_render_tree_serialization(myhtml_tree_t* html_tree, modest_render_tree_t* tree, + modest_render_tree_node_t* scope_node, mycss_callback_serialization_f callback, void* context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_RENDER_TREE_H */ diff --git a/source/modest/render/tree_node.c b/source/modest/render/tree_node.c new file mode 100644 index 0000000..37eb736 --- /dev/null +++ b/source/modest/render/tree_node.c @@ -0,0 +1,157 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#include "modest/render/tree_node.h" + +modest_render_tree_node_t * modest_render_tree_node_create_and_init(modest_render_tree_t* render_tree) +{ + void *render_node = mcobject_malloc(render_tree->mc_nodes, NULL); + + if(render_node) { + memset(render_node, 0, sizeof(modest_render_tree_node_t)); + } + + return render_node; +} + +void modest_render_tree_node_clean_all(modest_render_tree_node_t* render_node) +{ + memset(render_node, 0, sizeof(modest_render_tree_node_t)); +} + +modest_render_tree_node_t * modest_render_tree_node_destroy(modest_render_tree_t* render_tree, modest_render_tree_node_t* render_node, bool self_destroy) +{ + if(render_node == NULL) + return NULL; + + if(self_destroy) { + mcobject_free(render_tree->mc_nodes, render_node); + return NULL; + } + + return render_node; +} + +void modest_render_tree_node_append(modest_render_tree_node_t* to, modest_render_tree_node_t* node) +{ + if(to->child_last) { + to->child_last->next = node; + node->prev = to->child_last; + } + else { + to->child = node; + node->prev = NULL; + } + + node->parent = to; + node->next = NULL; + + to->child_last = node; +} + +void modest_render_tree_node_remove(modest_render_tree_node_t* node) +{ + if(node->parent) { + if(node->next == NULL) + node->parent->child_last = node->prev; + else + node->next->prev = node->prev; + + if(node->prev == NULL) + node->parent->child = node->next; + else + node->prev->next = node->next; + } + else { + if(node->next) + node->next->prev = node->prev; + + if(node->prev) + node->prev->next = node->next; + } +} + +void modest_render_tree_node_append_after(modest_render_tree_node_t* target, modest_render_tree_node_t* node) +{ + if(target->next) { + target->next->prev = node; + } + else { + if(target->parent) + target->parent->child_last = node; + } + + node->next = target->next; + node->prev = target; + node->parent = target->parent; + + target->next = node; +} + +void modest_render_tree_node_append_before(modest_render_tree_node_t* target, modest_render_tree_node_t* node) +{ + if(target->prev) { + target->prev->next = node; + } + else { + if(target->parent) + target->parent->child = node; + } + + node->next = target; + node->prev = target->prev; + node->parent = target->parent; + + target->prev = node; +} + +void modest_render_tree_node_serialization(myhtml_tree_t* html_tree, modest_render_tree_node_t* node, mycss_callback_serialization_f callback, void* context) +{ + callback("<", 1, context); + + switch (node->type) { + case MODEST_RENDER_TREE_NODE_TYPE_BLOCK: + callback("block", 5, context); + break; + + case MODEST_RENDER_TREE_NODE_TYPE_VIEWPORT: + callback("viewport", 8, context); + break; + + case MODEST_RENDER_TREE_NODE_TYPE_ANONYMOUS: + callback("anonymous", 9, context); + break; + + default: + break; + } + + if(node->html_node) { + size_t tag_length = 0; + const char *tag_name = myhtml_tag_name_by_id(html_tree, node->html_node->tag_id, &tag_length); + + callback(" ", 1, context); + callback(tag_name, tag_length, context); + } + + callback(">", 1, context); +} + + diff --git a/source/modest/render/tree_node.h b/source/modest/render/tree_node.h new file mode 100644 index 0000000..15593df --- /dev/null +++ b/source/modest/render/tree_node.h @@ -0,0 +1,71 @@ +/* + Copyright (C) 2016 Alexander Borisov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: lex.borisov@gmail.com (Alexander Borisov) +*/ + +#ifndef MODEST_RENDER_TREE_NODE_H +#define MODEST_RENDER_TREE_NODE_H +#pragma once + +typedef struct modest_render_tree_node modest_render_tree_node_t; + +#include "modest/modest.h" +#include "modest/render/tree.h" + +#include "myhtml/tree.h" +#include "myhtml/utils/mcobject.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum modest_render_tree_node_type { + MODEST_RENDER_TREE_NODE_TYPE_BLOCK = 0, + MODEST_RENDER_TREE_NODE_TYPE_VIEWPORT = 1, + MODEST_RENDER_TREE_NODE_TYPE_ANONYMOUS = 3 +} +typedef modest_render_tree_node_type_t; + +struct modest_render_tree_node { + myhtml_tree_node_t* html_node; + modest_render_tree_node_type_t type; + + /* navigation */ + modest_render_tree_node_t* next; + modest_render_tree_node_t* prev; + modest_render_tree_node_t* child; + modest_render_tree_node_t* child_last; + modest_render_tree_node_t* parent; +}; + +modest_render_tree_node_t * modest_render_tree_node_create_and_init(modest_render_tree_t* render_tree); +void modest_render_tree_node_clean_all(modest_render_tree_node_t* render_node); +modest_render_tree_node_t * modest_render_tree_node_destroy(modest_render_tree_t* render_tree, modest_render_tree_node_t* render_node, bool self_destroy); + +void modest_render_tree_node_append(modest_render_tree_node_t* to, modest_render_tree_node_t* node); +void modest_render_tree_node_remove(modest_render_tree_node_t* node); +void modest_render_tree_node_append_after(modest_render_tree_node_t* target, modest_render_tree_node_t* node); +void modest_render_tree_node_append_before(modest_render_tree_node_t* target, modest_render_tree_node_t* node); + +void modest_render_tree_node_serialization(myhtml_tree_t* html_tree, modest_render_tree_node_t* node, mycss_callback_serialization_f callback, void* context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MODEST_RENDER_TREE_NODE_H */ diff --git a/source/myhtml/Makefile b/source/myhtml/Makefile new file mode 100644 index 0000000..f24973c --- /dev/null +++ b/source/myhtml/Makefile @@ -0,0 +1,53 @@ +TARGET := source/myhtml +SRCDIR := source/myhtml + +CC ?= gcc + +LIBPOSTFIX := .so +LIBNAME := myhtml +LIBSTATIC_POSTFIX := _static + +MyHTML_OPTIMIZATION_LEVEL ?= -O2 + +CFLAGS ?= -Wall -Werror +CFLAGS += $(MyHTML_OPTIMIZATION_LEVEL) -fPIC --std=c99 -I.. + +MyHTML_BUILD_WITHOUT_THREADS ?= NO +ifeq ($(MyHTML_BUILD_WITHOUT_THREADS),YES) + $(info Build without POSIX Threads) + CFLAGS += -DMyHTML_BUILD_WITHOUT_THREADS +else + $(info Build with POSIX Threads) + CFLAGS += -pthread +endif + +ifeq ($(OS),Windows_NT) +else + UNAM := $(shell uname -s) + ifeq ($(UNAM),Darwin) + LIBPOSTFIX := .dylib + else + CFLAGS += -D_POSIX_C_SOURCE=199309L + endif +endif + +SRCS := $(wildcard *.c) +SRCS += $(wildcard utils/*.c) +HDRS := $(wildcard *.h) +HDRS += $(wildcard utils/*.h) +OBJS := $(patsubst %.c, %.o, $(SRCS)) + +all: shared static + +shared: $(OBJS) $(HDRS) + $(CC) -shared $(LDFLAGS) $(OBJS) -o lib$(LIBNAME)$(LIBPOSTFIX) + +static: shared + $(AR) crus lib$(LIBNAME)$(LIBSTATIC_POSTFIX).a $(OBJS) + +clean: + rm -rf *.o + rm -rf utils/*.o + rm -rf *lib$(LIBNAME)* + +.PHONY: all clean diff --git a/source/myhtml/api.h b/source/myhtml/api.h old mode 100644 new mode 100755 index ad94e84..794b9c7 --- a/source/myhtml/api.h +++ b/source/myhtml/api.h @@ -36,7 +36,7 @@ #define MyHTML_VERSION_MAJOR 1 #define MyHTML_VERSION_MINOR 0 -#define MyHTML_VERSION_PATCH 4 +#define MyHTML_VERSION_PATCH 5 #include #include @@ -577,6 +577,7 @@ typedef myhtml_version_t; // callback functions typedef void* (*myhtml_callback_token_f)(myhtml_tree_t* tree, myhtml_token_node_t* token, void* ctx); typedef void (*myhtml_callback_tree_node_f)(myhtml_tree_t* tree, myhtml_tree_node_t* node, void* ctx); +typedef void (*myhtml_callback_serialize_f)(const char* buffer, size_t size, void* ctx); /*********************************************************************************** * @@ -2714,28 +2715,74 @@ myhtml_strncasecmp(const char* str1, const char* str2, size_t size); ***********************************************************************************/ /** - * Tree fragment serialization - * - * @param[in] myhtml_tree_t* - * @param[in] scope node, myhtml_tree_node_t* - * @param[in] myhtml_string_raw_t* (date to be created if str_raw.data == NULL) - * - * @return true if successful, otherwise false + * Tree fragment serialization + * The same as myhtml_serialization_tree_buffer function */ bool -myhtml_serialization(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, myhtml_string_raw_t* str); +myhtml_serialization(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, + myhtml_string_raw_t* str); /** * Only one tree node serialization + * The same as myhtml_serialization_node_buffer function + */ +bool +myhtml_serialization_node(myhtml_tree_t* tree, myhtml_tree_node_t* node, + myhtml_string_raw_t* str); + +/** + * Serialize tree to an output string * * @param[in] myhtml_tree_t* - * @param[in] myhtml_tree_node_t* - * @param[in] myhtml_string_raw_t* (date to be created if str_raw.data == NULL) + * @param[in] scope node + * @param[in] myhtml_string_raw_t* * * @return true if successful, otherwise false */ bool -myhtml_serialization_node(myhtml_tree_t* tree, myhtml_tree_node_t* node, myhtml_string_raw_t* str); +myhtml_serialization_tree_buffer(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, + myhtml_string_raw_t* str); + +/** + * Serialize node to an output string + * + * @param[in] myhtml_tree_t* + * @param[in] node + * @param[in] myhtml_string_raw_t* + * + * @return true if successful, otherwise false + */ +bool +myhtml_serialization_node_buffer(myhtml_tree_t* tree, myhtml_tree_node_t* node, + myhtml_string_raw_t* str); + +/** + * The serialize function for an entire tree + * + * @param[in] tree the tree to be serialized + * @param[in] scope_node the scope_node + * @param[in] callback function that will be called for all strings that have to be printed + * @param[in] ptr user-supplied pointer + * + * @return true if successful, otherwise false + */ +bool +myhtml_serialization_tree_callback(myhtml_tree_t* tree, myhtml_tree_node_t* scope_node, + myhtml_callback_serialize_f callback, void* ptr); + +/** + * The serialize function for a single node + * + * @param[in] tree the tree to be serialized + * @param[in] node the node that is going to be serialized + * @param[in] callback function that will be called for all strings that have to be printed + * @param[in] ptr user-supplied pointer + * + * @return true if successful, otherwise false + */ +bool +myhtml_serialization_node_callback(myhtml_tree_t* tree, myhtml_tree_node_t* node, + myhtml_callback_serialize_f callback, void* ptr); /*********************************************************************************** * diff --git a/source/myhtml/myosi.h b/source/myhtml/myosi.h index 530dd72..4c516a8 100644 --- a/source/myhtml/myosi.h +++ b/source/myhtml/myosi.h @@ -31,7 +31,7 @@ #define MyHTML_VERSION_MAJOR 1 #define MyHTML_VERSION_MINOR 0 -#define MyHTML_VERSION_PATCH 4 +#define MyHTML_VERSION_PATCH 5 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__WINPTHREADS_VERSION) #define IS_OS_WINDOWS diff --git a/source/myhtml/serialization.c b/source/myhtml/serialization.c old mode 100644 new mode 100755 index ef76b94..9685cd0 --- a/source/myhtml/serialization.c +++ b/source/myhtml/serialization.c @@ -269,9 +269,15 @@ void myhtml_serialization_append(const char *data, size_t size, myhtml_callback_ notwritten = 0; break; case 0xA0: - if (notwritten) callback(data + i - notwritten, notwritten, ptr); - callback(" ", 6, ptr); - notwritten = 0; + if(i > 0 && (unsigned char)(data[(i - 1)]) == 0xC2) { + if (notwritten) callback(data + i - notwritten, (notwritten - 1), ptr); + callback(" ", 6, ptr); + notwritten = 0; + } + else { + ++notwritten; + } + break; default: ++notwritten; @@ -308,9 +314,15 @@ void myhtml_serialization_append_attr(const char* data, size_t size, myhtml_call notwritten = 0; break; case 0xA0: - if (notwritten) callback(data + i - notwritten, notwritten, ptr); - callback(" ", 6, ptr); - notwritten = 0; + if(i > 0 && (unsigned char)(data[(i - 1)]) == 0xC2) { + if (notwritten) callback(data + i - notwritten, (notwritten - 1), ptr); + callback(" ", 6, ptr); + notwritten = 0; + } + else { + ++notwritten; + } + break; default: ++notwritten;