commonmarker 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of commonmarker might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/commonmarker/cmark/CMakeLists.txt +3 -3
- data/ext/commonmarker/cmark/Makefile +2 -3
- data/ext/commonmarker/cmark/README.md +1 -1
- data/ext/commonmarker/cmark/api_test/main.c +15 -0
- data/ext/commonmarker/cmark/appveyor.yml +4 -2
- data/ext/commonmarker/cmark/build/CMakeCache.txt +86 -14
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CMakeCCompiler.cmake +9 -5
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CMakeCXXCompiler.cmake +9 -5
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2/CMakeDetermineCompilerABI_CXX.bin → 3.5.1/CMakeDetermineCompilerABI_C.bin} +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2/CMakeDetermineCompilerABI_C.bin → 3.5.1/CMakeDetermineCompilerABI_CXX.bin} +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CMakeSystem.cmake +4 -4
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CompilerIdC/CMakeCCompilerId.c +39 -3
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CompilerIdC/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CompilerIdCXX/CMakeCXXCompilerId.cpp +38 -3
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.3.2 → 3.5.1}/CompilerIdCXX/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +6 -6
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +171 -167
- data/ext/commonmarker/cmark/build/CMakeFiles/Makefile.cmake +107 -104
- data/ext/commonmarker/cmark/build/CMakeFiles/Makefile2 +42 -42
- data/ext/commonmarker/cmark/build/CMakeFiles/TargetDirectories.txt +36 -1
- data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.c +1 -1
- data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.cxx +1 -1
- data/ext/commonmarker/cmark/build/Makefile +23 -23
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/DependInfo.cmake +3 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/build.make +13 -13
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/flags.make +7 -3
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/link.txt +1 -1
- data/ext/commonmarker/cmark/build/api_test/Makefile +10 -10
- data/ext/commonmarker/cmark/build/man/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- data/ext/commonmarker/cmark/build/man/Makefile +10 -10
- data/ext/commonmarker/cmark/build/src/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/DependInfo.cmake +3 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/build.make +63 -63
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/flags.make +4 -2
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/DependInfo.cmake +4 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/build.make +83 -83
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/cmake_clean.cmake +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/flags.make +4 -2
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/link.txt +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/DependInfo.cmake +3 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/blocks.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/buffer.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/build.make +60 -60
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark_ctype.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/commonmark.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.internal +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.make +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/flags.make +4 -2
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_href_e.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_e.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/html.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/inlines.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/latex.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/link.txt +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/man.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/node.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/references.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/render.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/scanners.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/utf8.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/xml.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/Makefile +82 -82
- data/ext/commonmarker/cmark/build/src/cmake_install.cmake +2 -2
- data/ext/commonmarker/cmark/build/src/cmark_version.h +2 -2
- data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
- data/ext/commonmarker/cmark/build/src/libcmark.pc +1 -1
- data/ext/commonmarker/cmark/build/testdir/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- data/ext/commonmarker/cmark/build/testdir/CTestTestfile.cmake +1 -0
- data/ext/commonmarker/cmark/build/testdir/Makefile +10 -10
- data/ext/commonmarker/cmark/changelog.txt +72 -0
- data/ext/commonmarker/cmark/man/CMakeLists.txt +5 -3
- data/ext/commonmarker/cmark/man/man1/cmark.1 +2 -2
- data/ext/commonmarker/cmark/man/man3/cmark.3 +10 -10
- data/ext/commonmarker/cmark/src/CMakeLists.txt +2 -2
- data/ext/commonmarker/cmark/src/blocks.c +407 -245
- data/ext/commonmarker/cmark/src/buffer.c +3 -2
- data/ext/commonmarker/cmark/src/cmark.h +3 -3
- data/ext/commonmarker/cmark/src/commonmark.c +5 -5
- data/ext/commonmarker/cmark/src/html.c +3 -3
- data/ext/commonmarker/cmark/src/inlines.c +11 -11
- data/ext/commonmarker/cmark/src/latex.c +2 -2
- data/ext/commonmarker/cmark/src/main.c +2 -1
- data/ext/commonmarker/cmark/src/man.c +1 -1
- data/ext/commonmarker/cmark/src/node.c +2 -2
- data/ext/commonmarker/cmark/src/parser.h +2 -0
- data/ext/commonmarker/cmark/src/render.c +2 -2
- data/ext/commonmarker/cmark/src/scanners.c +2431 -2620
- data/ext/commonmarker/cmark/src/xml.c +3 -2
- data/ext/commonmarker/cmark/test/CMakeLists.txt +7 -0
- data/ext/commonmarker/cmark/test/regression.txt +34 -0
- data/ext/commonmarker/cmark/test/spec.txt +49 -6
- data/ext/commonmarker/cmark/test/spec_tests.py +1 -1
- data/ext/commonmarker/cmark/tools/appveyor-build.bat +13 -0
- data/lib/commonmarker/version.rb +1 -1
- metadata +13 -11
@@ -43,11 +43,11 @@ endif()
|
|
43
43
|
|
44
44
|
if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")
|
45
45
|
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY FILES
|
46
|
-
"/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/src/libcmark.0.
|
46
|
+
"/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/src/libcmark.0.25.2.dylib"
|
47
47
|
"/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/src/libcmark.dylib"
|
48
48
|
)
|
49
49
|
foreach(file
|
50
|
-
"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libcmark.0.
|
50
|
+
"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libcmark.0.25.2.dylib"
|
51
51
|
"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libcmark.dylib"
|
52
52
|
)
|
53
53
|
if(EXISTS "${file}" AND
|
Binary file
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# CMAKE generated file: DO NOT EDIT!
|
2
|
-
# Generated by "Unix Makefiles" Generator, CMake Version 3.
|
2
|
+
# Generated by "Unix Makefiles" Generator, CMake Version 3.5
|
3
3
|
|
4
4
|
# Relative path conversion top directories.
|
5
5
|
set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark")
|
@@ -11,3 +11,4 @@ add_test(pathological_tests_library "/usr/local/bin/python3" "/Users/gjtorikian/
|
|
11
11
|
add_test(spectest_executable "/usr/local/bin/python3" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/spec_tests.py" "--no-normalize" "--spec" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/spec.txt" "--program" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/testdir/../src/cmark")
|
12
12
|
add_test(smartpuncttest_executable "/usr/local/bin/python3" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/spec_tests.py" "--no-normalize" "--spec" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/smart_punct.txt" "--program" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/testdir/../src/cmark --smart")
|
13
13
|
add_test(roundtriptest_executable "/usr/local/bin/python3" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/spec_tests.py" "--no-normalize" "--spec" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/spec.txt" "--program" " /Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/testdir/../src/cmark")
|
14
|
+
add_test(regressiontest_executable "/usr/local/bin/python3" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/spec_tests.py" "--no-normalize" "--spec" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/test/regression.txt" "--program" "/Users/gjtorikian/Development/commonmarker/ext/commonmarker/cmark/build/testdir/../src/cmark")
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# CMAKE generated file: DO NOT EDIT!
|
2
|
-
# Generated by "Unix Makefiles" Generator, CMake Version 3.
|
2
|
+
# Generated by "Unix Makefiles" Generator, CMake Version 3.5
|
3
3
|
|
4
4
|
# Default target executed when no arguments are given to make.
|
5
5
|
default_target: all
|
@@ -39,10 +39,10 @@ cmake_force:
|
|
39
39
|
SHELL = /bin/sh
|
40
40
|
|
41
41
|
# The CMake executable.
|
42
|
-
CMAKE_COMMAND = /usr/local/Cellar/cmake/3.
|
42
|
+
CMAKE_COMMAND = /usr/local/Cellar/cmake/3.5.1/bin/cmake
|
43
43
|
|
44
44
|
# The command to remove a file.
|
45
|
-
RM = /usr/local/Cellar/cmake/3.
|
45
|
+
RM = /usr/local/Cellar/cmake/3.5.1/bin/cmake -E remove -f
|
46
46
|
|
47
47
|
# Escaping for special characters.
|
48
48
|
EQUALS = =
|
@@ -59,7 +59,7 @@ CMAKE_BINARY_DIR = /Users/gjtorikian/Development/commonmarker/ext/commonmarker/c
|
|
59
59
|
# Special rule for the target test
|
60
60
|
test:
|
61
61
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..."
|
62
|
-
/usr/local/Cellar/cmake/3.
|
62
|
+
/usr/local/Cellar/cmake/3.5.1/bin/ctest --force-new-ctest-process $(ARGS)
|
63
63
|
.PHONY : test
|
64
64
|
|
65
65
|
# Special rule for the target test
|
@@ -70,7 +70,7 @@ test/fast: test
|
|
70
70
|
# Special rule for the target install/local
|
71
71
|
install/local: preinstall
|
72
72
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
|
73
|
-
/usr/local/Cellar/cmake/3.
|
73
|
+
/usr/local/Cellar/cmake/3.5.1/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
|
74
74
|
.PHONY : install/local
|
75
75
|
|
76
76
|
# Special rule for the target install/local
|
@@ -81,7 +81,7 @@ install/local/fast: install/local
|
|
81
81
|
# Special rule for the target edit_cache
|
82
82
|
edit_cache:
|
83
83
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
|
84
|
-
/usr/local/Cellar/cmake/3.
|
84
|
+
/usr/local/Cellar/cmake/3.5.1/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
85
85
|
.PHONY : edit_cache
|
86
86
|
|
87
87
|
# Special rule for the target edit_cache
|
@@ -92,7 +92,7 @@ edit_cache/fast: edit_cache
|
|
92
92
|
# Special rule for the target rebuild_cache
|
93
93
|
rebuild_cache:
|
94
94
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
|
95
|
-
/usr/local/Cellar/cmake/3.
|
95
|
+
/usr/local/Cellar/cmake/3.5.1/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
96
96
|
.PHONY : rebuild_cache
|
97
97
|
|
98
98
|
# Special rule for the target rebuild_cache
|
@@ -113,19 +113,19 @@ list_install_components/fast: list_install_components
|
|
113
113
|
# Special rule for the target install
|
114
114
|
install: preinstall
|
115
115
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
116
|
-
/usr/local/Cellar/cmake/3.
|
116
|
+
/usr/local/Cellar/cmake/3.5.1/bin/cmake -P cmake_install.cmake
|
117
117
|
.PHONY : install
|
118
118
|
|
119
119
|
# Special rule for the target install
|
120
120
|
install/fast: preinstall/fast
|
121
121
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
122
|
-
/usr/local/Cellar/cmake/3.
|
122
|
+
/usr/local/Cellar/cmake/3.5.1/bin/cmake -P cmake_install.cmake
|
123
123
|
.PHONY : install/fast
|
124
124
|
|
125
125
|
# Special rule for the target install/strip
|
126
126
|
install/strip: preinstall
|
127
127
|
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
|
128
|
-
/usr/local/Cellar/cmake/3.
|
128
|
+
/usr/local/Cellar/cmake/3.5.1/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
|
129
129
|
.PHONY : install/strip
|
130
130
|
|
131
131
|
# Special rule for the target install/strip
|
@@ -1,3 +1,75 @@
|
|
1
|
+
[0.25.2]
|
2
|
+
|
3
|
+
* Open files in binary mode (#113, Nick Wellnhofer). Now that cmark
|
4
|
+
supports different line endings, files must be openend in binary mode
|
5
|
+
on Windows.
|
6
|
+
* Reset `partially_consumed_tab` on every new line (#114, Nick Wellnhofer).
|
7
|
+
* Handle buffer split across a CRLF line ending (#117). Adds an internal
|
8
|
+
field to the parser struct to keep track of `last_buffer_ended_with_cr`.
|
9
|
+
Added test.
|
10
|
+
|
11
|
+
[0.25.1]
|
12
|
+
|
13
|
+
* Release with no code changes. cmark version was mistakenly set to
|
14
|
+
0.25.1 in the 0.25.0 release (#112), so this release just
|
15
|
+
ensures that this will cause no confusion later.
|
16
|
+
|
17
|
+
[0.25.0]
|
18
|
+
|
19
|
+
* Fixed tabs in indentation (#101). This patch fixes S_advance_offset
|
20
|
+
so that it doesn't gobble a tab character when advancing less than the
|
21
|
+
width of a tab.
|
22
|
+
* Added partially_consumed_tab to parser. This keeps track of when we
|
23
|
+
have gotten partway through a tab when consuming initial indentation.
|
24
|
+
* Simplified add_line (only need parser parameter).
|
25
|
+
* Properly handle partially consumed tab. E.g. in
|
26
|
+
|
27
|
+
- foo
|
28
|
+
|
29
|
+
<TAB><TAB>bar
|
30
|
+
|
31
|
+
we should consume two spaces from the second tab, including two spaces
|
32
|
+
in the code block.
|
33
|
+
* Properly handle tabs with blockquotes and fenced blocks.
|
34
|
+
* Fixed handling of tabs in lists.
|
35
|
+
* Clarified logic in S_advance_offset.
|
36
|
+
* Use an assertion to check for in-range html_block_type.
|
37
|
+
It's a programming error if the type is out of range.
|
38
|
+
* Refactored S_processLines to make the logic easier to
|
39
|
+
understand, and added documentation (Mathieu Duponchelle).
|
40
|
+
* Removed unnecessary check for empty string_content.
|
41
|
+
* Factored out contains_inlines.
|
42
|
+
* Moved the cmake minimum version to top line of CMakeLists.txt
|
43
|
+
(tinysun212).
|
44
|
+
* Fix ctype(3) usage on NetBSD (Kamil Rytarowski). We need to cast value
|
45
|
+
passed to isspace(3) to unsigned char to explicitly prevent possibly
|
46
|
+
undefined behavior.
|
47
|
+
* Compile in plain C mode with MSVC 12.0 or newer (Nick Wellnhofer).
|
48
|
+
Under MSVC, we used to compile in C++ mode to get some C99 features
|
49
|
+
like mixing declarations and code. With newer MSVC versions, it's
|
50
|
+
possible to build in plain C mode.
|
51
|
+
* Switched from "inline" to "CMARK_INLINE" (Nick Wellnhofer).
|
52
|
+
Newer MSVC versions support enough of C99 to be able to compile cmark
|
53
|
+
in plain C mode. Only the "inline" keyword is still unsupported.
|
54
|
+
We have to use "__inline" instead.
|
55
|
+
* Added include guards to config.h
|
56
|
+
* config.h.in - added compatibility snprintf, vsnprintf for MSVC.
|
57
|
+
* Replaced sprintf with snprintf (Marco Benelli).
|
58
|
+
* config.h: include stdio.h for _vscprintf etc.
|
59
|
+
* Include starg.h when needed in config.h.
|
60
|
+
* Removed an unnecessary C99-ism in buffer.c. This helps compiling on
|
61
|
+
systems like luarocks that don't have all the cmake configuration
|
62
|
+
goodness (thanks to carlmartus).
|
63
|
+
* Don't use variable length arrays (Nick Wellnhofer).
|
64
|
+
They're not supported by MSVC.
|
65
|
+
* Test with multiple MSVC versions under Appveyor (Nick Wellnhofer).
|
66
|
+
* Fix installation dir of man-pages on NetBSD (Kamil Rytarowski).
|
67
|
+
* Fixed typo in cmark.h comments (Chris Eidhof).
|
68
|
+
* Clarify in man page that cmark_node_free frees a node's children too.
|
69
|
+
* Fixed documentation of --width in man page.
|
70
|
+
* Require re2c >= 1.14.2 (#102).
|
71
|
+
* Generated scanners.c with more recent re2c.
|
72
|
+
|
1
73
|
[0.24.1]
|
2
74
|
|
3
75
|
* Commonmark renderer:
|
@@ -1,8 +1,10 @@
|
|
1
1
|
if (NOT MSVC)
|
2
|
+
|
3
|
+
include(GNUInstallDirs)
|
4
|
+
|
2
5
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1
|
3
|
-
DESTINATION
|
6
|
+
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
4
7
|
|
5
8
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man3/cmark.3
|
6
|
-
DESTINATION
|
9
|
+
DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
|
7
10
|
endif(NOT MSVC)
|
8
|
-
|
@@ -1,4 +1,4 @@
|
|
1
|
-
.TH "cmark" "1" "
|
1
|
+
.TH "cmark" "1" "March 24, 2016" "LOCAL" "General Commands Manual"
|
2
2
|
.SH "NAME"
|
3
3
|
\fBcmark\fR
|
4
4
|
\- convert CommonMark formatted text to HTML
|
@@ -23,7 +23,7 @@ Specify output format (\f[C]html\f[], \f[C]man\f[], \f[C]xml\f[],
|
|
23
23
|
.B \-\-width \f[I]WIDTH\f[]
|
24
24
|
Specify a column width to which to wrap the output. For no wrapping, use
|
25
25
|
the value 0 (the default). This option currently only affects the
|
26
|
-
commonmark
|
26
|
+
commonmark, latex, and man renderers.
|
27
27
|
.TP 12n
|
28
28
|
.B \-\-sourcepos
|
29
29
|
Include source position attribute.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
.TH cmark 3 "
|
1
|
+
.TH cmark 3 "March 24, 2016" "LOCAL" "Library Functions Manual"
|
2
2
|
.SH
|
3
3
|
NAME
|
4
4
|
.PP
|
@@ -14,7 +14,7 @@ Simple Interface
|
|
14
14
|
|
15
15
|
.PP
|
16
16
|
Convert \f[I]text\f[] (assumed to be a UTF\-8 encoded string with length
|
17
|
-
\f[I]len\f[] from CommonMark Markdown to HTML, returning a
|
17
|
+
\f[I]len\f[]) from CommonMark Markdown to HTML, returning a
|
18
18
|
null\-terminated, UTF\-8\-encoded string.
|
19
19
|
|
20
20
|
.SS
|
@@ -109,7 +109,7 @@ to assign.
|
|
109
109
|
\fIvoid\f[] \fBcmark_node_free\f[](\fIcmark_node *node\f[])
|
110
110
|
|
111
111
|
.PP
|
112
|
-
Frees the memory allocated for a node.
|
112
|
+
Frees the memory allocated for a node and any children.
|
113
113
|
|
114
114
|
.SS
|
115
115
|
Tree Traversal
|
@@ -363,8 +363,8 @@ otherwise 0.
|
|
363
363
|
\fIint\f[] \fBcmark_node_set_list_start\f[](\fIcmark_node *node\f[], \fIint start\f[])
|
364
364
|
|
365
365
|
.PP
|
366
|
-
Sets starting number of \f[I]node\f[], if it is an ordered list.
|
367
|
-
1 on success, 0 on failure.
|
366
|
+
Sets starting number of \f[I]node\f[], if it is an ordered list.
|
367
|
+
Returns 1 on success, 0 on failure.
|
368
368
|
|
369
369
|
.PP
|
370
370
|
\fIint\f[] \fBcmark_node_get_list_tight\f[](\fIcmark_node *node\f[])
|
@@ -389,8 +389,8 @@ Returns the info string from a fenced code block.
|
|
389
389
|
\fIint\f[] \fBcmark_node_set_fence_info\f[](\fIcmark_node *node\f[], \fIconst char *info\f[])
|
390
390
|
|
391
391
|
.PP
|
392
|
-
Sets the info string in a fenced code block, returning 1 on success
|
393
|
-
0 on failure.
|
392
|
+
Sets the info string in a fenced code block, returning 1 on success
|
393
|
+
and 0 on failure.
|
394
394
|
|
395
395
|
.PP
|
396
396
|
\fIconst char *\f[] \fBcmark_node_get_url\f[](\fIcmark_node *node\f[])
|
@@ -517,8 +517,8 @@ Returns 1 on success, 0 on failure.
|
|
517
517
|
\fIint\f[] \fBcmark_node_append_child\f[](\fIcmark_node *node\f[], \fIcmark_node *child\f[])
|
518
518
|
|
519
519
|
.PP
|
520
|
-
Adds \f[I]child\f[] to the end of the children of \f[I]node\f[].
|
521
|
-
1 on success, 0 on failure.
|
520
|
+
Adds \f[I]child\f[] to the end of the children of \f[I]node\f[].
|
521
|
+
Returns 1 on success, 0 on failure.
|
522
522
|
|
523
523
|
.PP
|
524
524
|
\fIvoid\f[] \fBcmark_consolidate_text_nodes\f[](\fIcmark_node *root\f[])
|
@@ -543,7 +543,7 @@ Streaming interface:
|
|
543
543
|
.nf
|
544
544
|
\f[C]
|
545
545
|
cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT);
|
546
|
-
FILE *fp = fopen("myfile.md", "
|
546
|
+
FILE *fp = fopen("myfile.md", "rb");
|
547
547
|
while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
|
548
548
|
cmark_parser_feed(parser, buffer, bytes);
|
549
549
|
if (bytes < sizeof(buffer)) {
|
@@ -169,8 +169,8 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|
169
169
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=c99 -pedantic")
|
170
170
|
endif()
|
171
171
|
|
172
|
-
# Compile as C++ under MSVC
|
173
|
-
if(MSVC)
|
172
|
+
# Compile as C++ under MSVC older than 12.0
|
173
|
+
if(MSVC AND MSVC_VERSION LESS 1800)
|
174
174
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /TP")
|
175
175
|
endif()
|
176
176
|
|
@@ -1,3 +1,10 @@
|
|
1
|
+
/**
|
2
|
+
* Block parsing implementation.
|
3
|
+
*
|
4
|
+
* For a high-level overview of the block parsing process,
|
5
|
+
* see http://spec.commonmark.org/0.24/#phase-1-block-structure
|
6
|
+
*/
|
7
|
+
|
1
8
|
#include <stdlib.h>
|
2
9
|
#include <assert.h>
|
3
10
|
#include <stdio.h>
|
@@ -17,12 +24,20 @@
|
|
17
24
|
#define CODE_INDENT 4
|
18
25
|
#define TAB_STOP 4
|
19
26
|
|
27
|
+
#ifndef MIN
|
28
|
+
#define MIN(x, y) ((x < y) ? x : y)
|
29
|
+
#endif
|
30
|
+
|
20
31
|
#define peek_at(i, n) (i)->data[n]
|
21
32
|
|
22
|
-
static
|
33
|
+
static CMARK_INLINE bool S_is_line_end_char(char c) {
|
23
34
|
return (c == '\n' || c == '\r');
|
24
35
|
}
|
25
36
|
|
37
|
+
static CMARK_INLINE bool S_is_space_or_tab(char c) {
|
38
|
+
return (c == ' ' || c == '\t');
|
39
|
+
}
|
40
|
+
|
26
41
|
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
|
27
42
|
size_t len, bool eof);
|
28
43
|
|
@@ -70,10 +85,12 @@ cmark_parser *cmark_parser_new(int options) {
|
|
70
85
|
parser->first_nonspace_column = 0;
|
71
86
|
parser->indent = 0;
|
72
87
|
parser->blank = false;
|
88
|
+
parser->partially_consumed_tab = false;
|
73
89
|
parser->curline = line;
|
74
90
|
parser->last_line_length = 0;
|
75
91
|
parser->linebuf = buf;
|
76
92
|
parser->options = options;
|
93
|
+
parser->last_buffer_ended_with_cr = false;
|
77
94
|
|
78
95
|
return parser;
|
79
96
|
}
|
@@ -110,7 +127,7 @@ static bool is_blank(cmark_strbuf *s, bufsize_t offset) {
|
|
110
127
|
return true;
|
111
128
|
}
|
112
129
|
|
113
|
-
static
|
130
|
+
static CMARK_INLINE bool can_contain(cmark_node_type parent_type,
|
114
131
|
cmark_node_type child_type) {
|
115
132
|
return (parent_type == CMARK_NODE_DOCUMENT ||
|
116
133
|
parent_type == CMARK_NODE_BLOCK_QUOTE ||
|
@@ -118,15 +135,32 @@ static inline bool can_contain(cmark_node_type parent_type,
|
|
118
135
|
(parent_type == CMARK_NODE_LIST && child_type == CMARK_NODE_ITEM));
|
119
136
|
}
|
120
137
|
|
121
|
-
static
|
138
|
+
static CMARK_INLINE bool accepts_lines(cmark_node_type block_type) {
|
122
139
|
return (block_type == CMARK_NODE_PARAGRAPH ||
|
123
140
|
block_type == CMARK_NODE_HEADING ||
|
124
141
|
block_type == CMARK_NODE_CODE_BLOCK);
|
125
142
|
}
|
126
143
|
|
127
|
-
static
|
144
|
+
static CMARK_INLINE bool contains_inlines(cmark_node_type block_type) {
|
145
|
+
return (block_type == CMARK_NODE_PARAGRAPH ||
|
146
|
+
block_type == CMARK_NODE_HEADING);
|
147
|
+
}
|
148
|
+
|
149
|
+
static void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) {
|
150
|
+
int chars_to_tab;
|
151
|
+
int i;
|
128
152
|
assert(node->open);
|
129
|
-
|
153
|
+
if (parser->partially_consumed_tab) {
|
154
|
+
parser->offset += 1; // skip over tab
|
155
|
+
// add space characters:
|
156
|
+
chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
|
157
|
+
for (i = 0; i < chars_to_tab; i++) {
|
158
|
+
cmark_strbuf_putc(&node->string_content, ' ');
|
159
|
+
}
|
160
|
+
}
|
161
|
+
cmark_strbuf_put(&node->string_content,
|
162
|
+
ch->data + parser->offset,
|
163
|
+
ch->len - parser->offset);
|
130
164
|
}
|
131
165
|
|
132
166
|
static void remove_trailing_blank_lines(cmark_strbuf *ln) {
|
@@ -336,8 +370,7 @@ static void process_inlines(cmark_node *root, cmark_reference_map *refmap,
|
|
336
370
|
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
|
337
371
|
cur = cmark_iter_get_node(iter);
|
338
372
|
if (ev_type == CMARK_EVENT_ENTER) {
|
339
|
-
if (cur->type
|
340
|
-
cur->type == CMARK_NODE_HEADING) {
|
373
|
+
if (contains_inlines(cur->type)) {
|
341
374
|
cmark_parse_inlines(cur, refmap, options);
|
342
375
|
}
|
343
376
|
}
|
@@ -474,6 +507,11 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
|
|
474
507
|
const unsigned char *end = buffer + len;
|
475
508
|
static const uint8_t repl[] = {239, 191, 189};
|
476
509
|
|
510
|
+
if (parser->last_buffer_ended_with_cr && *buffer == '\n') {
|
511
|
+
// skip NL if last buffer ended with CR ; see #117
|
512
|
+
buffer++;
|
513
|
+
}
|
514
|
+
parser->last_buffer_ended_with_cr = false;
|
477
515
|
while (buffer < end) {
|
478
516
|
const unsigned char *eol;
|
479
517
|
bufsize_t chunk_len;
|
@@ -514,8 +552,11 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
|
|
514
552
|
|
515
553
|
buffer += chunk_len;
|
516
554
|
// skip over line ending characters:
|
517
|
-
if (buffer < end && *buffer == '\r')
|
555
|
+
if (buffer < end && *buffer == '\r') {
|
518
556
|
buffer++;
|
557
|
+
if (buffer == end)
|
558
|
+
parser->last_buffer_ended_with_cr = true;
|
559
|
+
}
|
519
560
|
if (buffer < end && *buffer == '\n')
|
520
561
|
buffer++;
|
521
562
|
}
|
@@ -532,13 +573,15 @@ static void chop_trailing_hashtags(cmark_chunk *ch) {
|
|
532
573
|
n--;
|
533
574
|
|
534
575
|
// Check for a space before the final #s:
|
535
|
-
if (n != orig_n && n >= 0 &&
|
536
|
-
(peek_at(ch, n) == ' ' || peek_at(ch, n) == '\t')) {
|
576
|
+
if (n != orig_n && n >= 0 && S_is_space_or_tab(peek_at(ch, n))) {
|
537
577
|
ch->len = n;
|
538
578
|
cmark_chunk_rtrim(ch);
|
539
579
|
}
|
540
580
|
}
|
541
581
|
|
582
|
+
// Find first nonspace character from current offset, setting
|
583
|
+
// parser->first_nonspace, parser->first_nonspace_column,
|
584
|
+
// parser->indent, and parser->blank. Does not advance parser->offset.
|
542
585
|
static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
|
543
586
|
char c;
|
544
587
|
int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
|
@@ -566,17 +609,37 @@ static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
|
|
566
609
|
parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));
|
567
610
|
}
|
568
611
|
|
612
|
+
// Advance parser->offset and parser->column. parser->offset is the
|
613
|
+
// byte position in input; parser->column is a virtual column number
|
614
|
+
// that takes into account tabs. (Multibyte characters are not taken
|
615
|
+
// into account, because the Markdown line prefixes we are interested in
|
616
|
+
// analyzing are entirely ASCII.) The count parameter indicates
|
617
|
+
// how far to advance the offset. If columns is true, then count
|
618
|
+
// indicates a number of columns; otherwise, a number of bytes.
|
619
|
+
// If advancing a certain number of columns partially consumes
|
620
|
+
// a tab character, parser->partially_consumed_tab is set to true.
|
569
621
|
static void S_advance_offset(cmark_parser *parser, cmark_chunk *input,
|
570
622
|
bufsize_t count, bool columns) {
|
571
623
|
char c;
|
572
624
|
int chars_to_tab;
|
625
|
+
int chars_to_advance;
|
573
626
|
while (count > 0 && (c = peek_at(input, parser->offset))) {
|
574
627
|
if (c == '\t') {
|
575
628
|
chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
|
576
|
-
|
577
|
-
|
578
|
-
|
629
|
+
if (columns) {
|
630
|
+
parser->partially_consumed_tab = chars_to_tab > count;
|
631
|
+
chars_to_advance = MIN(count, chars_to_tab);
|
632
|
+
parser->column += chars_to_advance;
|
633
|
+
parser->offset += (parser->partially_consumed_tab ? 0 : 1);
|
634
|
+
count -= chars_to_advance;
|
635
|
+
} else {
|
636
|
+
parser->partially_consumed_tab = false;
|
637
|
+
parser->column += chars_to_tab;
|
638
|
+
parser->offset += 1;
|
639
|
+
count -= 1;
|
640
|
+
}
|
579
641
|
} else {
|
642
|
+
parser->partially_consumed_tab = false;
|
580
643
|
parser->offset += 1;
|
581
644
|
parser->column += 1; // assume ascii; block starts are ascii
|
582
645
|
count -= 1;
|
@@ -584,263 +647,314 @@ static void S_advance_offset(cmark_parser *parser, cmark_chunk *input,
|
|
584
647
|
}
|
585
648
|
}
|
586
649
|
|
587
|
-
static
|
588
|
-
|
589
|
-
|
650
|
+
static bool S_last_child_is_open(cmark_node *container) {
|
651
|
+
return container->last_child && container->last_child->open;
|
652
|
+
}
|
653
|
+
|
654
|
+
static bool parse_block_quote_prefix(cmark_parser *parser,
|
655
|
+
cmark_chunk *input)
|
656
|
+
{
|
657
|
+
bool res = false;
|
590
658
|
bufsize_t matched = 0;
|
591
|
-
int lev = 0;
|
592
|
-
int i;
|
593
|
-
cmark_list *data = NULL;
|
594
|
-
bool all_matched = true;
|
595
|
-
cmark_node *container;
|
596
|
-
bool indented;
|
597
|
-
cmark_chunk input;
|
598
|
-
bool maybe_lazy;
|
599
659
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
cmark_strbuf_put(parser->curline, buffer, bytes);
|
604
|
-
}
|
605
|
-
// ensure line ends with a newline:
|
606
|
-
if (bytes == 0 || !S_is_line_end_char(parser->curline->ptr[bytes - 1])) {
|
607
|
-
cmark_strbuf_putc(parser->curline, '\n');
|
608
|
-
}
|
609
|
-
parser->offset = 0;
|
610
|
-
parser->column = 0;
|
611
|
-
parser->blank = false;
|
660
|
+
matched =
|
661
|
+
parser->indent <= 3 && peek_at(input, parser->first_nonspace) == '>';
|
662
|
+
if (matched) {
|
612
663
|
|
613
|
-
|
614
|
-
input.len = parser->curline->size;
|
664
|
+
S_advance_offset(parser, input, parser->indent + 1, true);
|
615
665
|
|
616
|
-
|
617
|
-
|
666
|
+
if (S_is_space_or_tab(peek_at(input, parser->offset))) {
|
667
|
+
S_advance_offset(parser, input, 1, true);
|
668
|
+
}
|
618
669
|
|
619
|
-
|
670
|
+
res = true;
|
671
|
+
}
|
672
|
+
return res;
|
673
|
+
}
|
620
674
|
|
621
|
-
|
622
|
-
|
675
|
+
static bool parse_node_item_prefix(cmark_parser *parser,
|
676
|
+
cmark_chunk *input,
|
677
|
+
cmark_node *container)
|
678
|
+
{
|
679
|
+
bool res = false;
|
680
|
+
|
681
|
+
if (parser->indent >=
|
682
|
+
container->as.list.marker_offset + container->as.list.padding) {
|
683
|
+
S_advance_offset(parser, input, container->as.list.marker_offset +
|
684
|
+
container->as.list.padding,
|
685
|
+
true);
|
686
|
+
res = true;
|
687
|
+
} else if (parser->blank && container->first_child != NULL) {
|
688
|
+
// if container->first_child is NULL, then the opening line
|
689
|
+
// of the list item was blank after the list marker; in this
|
690
|
+
// case, we are done with the list item.
|
691
|
+
S_advance_offset(parser, input,
|
692
|
+
parser->first_nonspace - parser->offset, false);
|
693
|
+
res = true;
|
694
|
+
}
|
695
|
+
return res;
|
696
|
+
}
|
623
697
|
|
624
|
-
|
625
|
-
|
698
|
+
static bool parse_code_block_prefix(cmark_parser *parser,
|
699
|
+
cmark_chunk *input,
|
700
|
+
cmark_node *container,
|
701
|
+
bool *should_continue)
|
702
|
+
{
|
703
|
+
bool res = false;
|
704
|
+
|
705
|
+
if (!container->as.code.fenced) { // indented
|
706
|
+
if (parser->indent >= CODE_INDENT) {
|
707
|
+
S_advance_offset(parser, input, CODE_INDENT, true);
|
708
|
+
res = true;
|
709
|
+
} else if (parser->blank) {
|
710
|
+
S_advance_offset(parser, input,
|
711
|
+
parser->first_nonspace - parser->offset, false);
|
712
|
+
res = true;
|
713
|
+
}
|
714
|
+
} else { // fenced
|
715
|
+
bufsize_t matched = 0;
|
626
716
|
|
627
|
-
|
717
|
+
if (parser->indent <= 3 && (peek_at(input, parser->first_nonspace) ==
|
718
|
+
container->as.code.fence_char)) {
|
719
|
+
matched = scan_close_code_fence(input, parser->first_nonspace);
|
720
|
+
}
|
628
721
|
|
629
|
-
if (container->
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
}
|
722
|
+
if (matched >= container->as.code.fence_length) {
|
723
|
+
// closing fence - and since we're at
|
724
|
+
// the end of a line, we can stop processing it:
|
725
|
+
*should_continue = false;
|
726
|
+
S_advance_offset(parser, input, matched, false);
|
727
|
+
parser->current = finalize(parser, container);
|
728
|
+
} else {
|
729
|
+
// skip opt. spaces of fence parser->offset
|
730
|
+
int i = container->as.code.fence_offset;
|
639
731
|
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
S_advance_offset(parser, &input, container->as.list.marker_offset +
|
644
|
-
container->as.list.padding,
|
645
|
-
true);
|
646
|
-
} else if (parser->blank && container->first_child != NULL) {
|
647
|
-
// if container->first_child is NULL, then the opening line
|
648
|
-
// of the list item was blank after the list marker; in this
|
649
|
-
// case, we are done with the list item.
|
650
|
-
S_advance_offset(parser, &input,
|
651
|
-
parser->first_nonspace - parser->offset, false);
|
652
|
-
} else {
|
653
|
-
all_matched = false;
|
732
|
+
while (i > 0 && S_is_space_or_tab(peek_at(input, parser->offset))) {
|
733
|
+
S_advance_offset(parser, input, 1, true);
|
734
|
+
i--;
|
654
735
|
}
|
736
|
+
res = true;
|
737
|
+
}
|
738
|
+
}
|
655
739
|
|
656
|
-
|
740
|
+
return res;
|
741
|
+
}
|
657
742
|
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
goto finished;
|
680
|
-
} else {
|
681
|
-
// skip opt. spaces of fence parser->offset
|
682
|
-
i = container->as.code.fence_offset;
|
683
|
-
while (i > 0 && peek_at(&input, parser->offset) == ' ') {
|
684
|
-
S_advance_offset(parser, &input, 1, false);
|
685
|
-
i--;
|
686
|
-
}
|
687
|
-
}
|
688
|
-
}
|
689
|
-
} else if (container->type == CMARK_NODE_HEADING) {
|
743
|
+
static bool parse_html_block_prefix(cmark_parser *parser,
|
744
|
+
cmark_node *container)
|
745
|
+
{
|
746
|
+
bool res = false;
|
747
|
+
int html_block_type = container->as.html_block_type;
|
748
|
+
|
749
|
+
assert(html_block_type >= 1 && html_block_type <= 7);
|
750
|
+
switch (html_block_type) {
|
751
|
+
case 1:
|
752
|
+
case 2:
|
753
|
+
case 3:
|
754
|
+
case 4:
|
755
|
+
case 5:
|
756
|
+
// these types of blocks can accept blanks
|
757
|
+
res = true;
|
758
|
+
break;
|
759
|
+
case 6:
|
760
|
+
case 7:
|
761
|
+
res = !parser->blank;
|
762
|
+
break;
|
763
|
+
}
|
690
764
|
|
691
|
-
|
692
|
-
|
765
|
+
return res;
|
766
|
+
}
|
693
767
|
|
694
|
-
|
768
|
+
/**
|
769
|
+
* For each containing node, try to parse the associated line start.
|
770
|
+
*
|
771
|
+
* Will not close unmatched blocks, as we may have a lazy continuation
|
772
|
+
* line -> http://spec.commonmark.org/0.24/#lazy-continuation-line
|
773
|
+
*
|
774
|
+
* Returns: The last matching node, or NULL
|
775
|
+
*/
|
776
|
+
static cmark_node *check_open_blocks(cmark_parser *parser,
|
777
|
+
cmark_chunk *input,
|
778
|
+
bool *all_matched)
|
779
|
+
{
|
780
|
+
bool should_continue = true;
|
781
|
+
*all_matched = false;
|
782
|
+
cmark_node *container = parser->root;
|
783
|
+
cmark_node_type cont_type;
|
784
|
+
|
785
|
+
while (S_last_child_is_open(container)) {
|
786
|
+
container = container->last_child;
|
787
|
+
cont_type = container->type;
|
695
788
|
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
case
|
700
|
-
|
701
|
-
|
702
|
-
// these types of blocks can accept blanks
|
789
|
+
S_find_first_nonspace(parser, input);
|
790
|
+
|
791
|
+
switch (cont_type) {
|
792
|
+
case CMARK_NODE_BLOCK_QUOTE:
|
793
|
+
if (!parse_block_quote_prefix(parser, input))
|
794
|
+
goto done;
|
703
795
|
break;
|
704
|
-
case
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
796
|
+
case CMARK_NODE_ITEM:
|
797
|
+
if (!parse_node_item_prefix(parser, input, container))
|
798
|
+
goto done;
|
799
|
+
break;
|
800
|
+
case CMARK_NODE_CODE_BLOCK:
|
801
|
+
if (!parse_code_block_prefix(parser, input, container, &should_continue))
|
802
|
+
goto done;
|
803
|
+
break;
|
804
|
+
case CMARK_NODE_HEADING:
|
805
|
+
// a heading can never contain more than one line
|
806
|
+
goto done;
|
807
|
+
case CMARK_NODE_HTML_BLOCK:
|
808
|
+
if (!parse_html_block_prefix(parser, container))
|
809
|
+
goto done;
|
810
|
+
break;
|
811
|
+
case CMARK_NODE_PARAGRAPH:
|
812
|
+
if (parser->blank)
|
813
|
+
goto done;
|
709
814
|
break;
|
710
815
|
default:
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
}
|
816
|
+
break;
|
817
|
+
}
|
818
|
+
}
|
715
819
|
|
716
|
-
|
820
|
+
*all_matched = true;
|
717
821
|
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
822
|
+
done:
|
823
|
+
if (!*all_matched) {
|
824
|
+
container = container->parent; // back up to last matching node
|
825
|
+
}
|
722
826
|
|
723
|
-
|
724
|
-
|
725
|
-
break;
|
726
|
-
}
|
827
|
+
if (!should_continue) {
|
828
|
+
container = NULL;
|
727
829
|
}
|
728
830
|
|
729
|
-
|
831
|
+
return container;
|
832
|
+
}
|
730
833
|
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
834
|
+
static void open_new_blocks(cmark_parser *parser,
|
835
|
+
cmark_node **container,
|
836
|
+
cmark_chunk *input,
|
837
|
+
bool all_matched)
|
838
|
+
{
|
839
|
+
bool indented;
|
840
|
+
cmark_list *data = NULL;
|
841
|
+
bool maybe_lazy = parser->current->type == CMARK_NODE_PARAGRAPH;
|
842
|
+
cmark_node_type cont_type = (*container)->type;
|
843
|
+
bufsize_t matched = 0;
|
844
|
+
int lev = 0;
|
845
|
+
bool save_partially_consumed_tab;
|
846
|
+
int save_offset;
|
847
|
+
int save_column;
|
735
848
|
|
736
|
-
|
737
|
-
|
738
|
-
while (container->type != CMARK_NODE_CODE_BLOCK &&
|
739
|
-
container->type != CMARK_NODE_HTML_BLOCK) {
|
849
|
+
while (cont_type != CMARK_NODE_CODE_BLOCK &&
|
850
|
+
cont_type != CMARK_NODE_HTML_BLOCK) {
|
740
851
|
|
741
|
-
S_find_first_nonspace(parser,
|
852
|
+
S_find_first_nonspace(parser, input);
|
742
853
|
indented = parser->indent >= CODE_INDENT;
|
743
854
|
|
744
|
-
if (!indented && peek_at(
|
855
|
+
if (!indented && peek_at(input, parser->first_nonspace) == '>') {
|
745
856
|
|
746
|
-
S_advance_offset(parser,
|
857
|
+
S_advance_offset(parser, input,
|
747
858
|
parser->first_nonspace + 1 - parser->offset, false);
|
748
859
|
// optional following character
|
749
|
-
if (peek_at(
|
750
|
-
S_advance_offset(parser,
|
751
|
-
|
860
|
+
if (S_is_space_or_tab(peek_at(input, parser->offset))) {
|
861
|
+
S_advance_offset(parser, input, 1, true);
|
862
|
+
}
|
863
|
+
*container = add_child(parser, *container, CMARK_NODE_BLOCK_QUOTE,
|
752
864
|
parser->offset + 1);
|
753
865
|
|
754
866
|
} else if (!indented && (matched = scan_atx_heading_start(
|
755
|
-
|
867
|
+
input, parser->first_nonspace))) {
|
868
|
+
bufsize_t hashpos;
|
869
|
+
int level = 0;
|
756
870
|
|
757
|
-
S_advance_offset(parser,
|
871
|
+
S_advance_offset(parser, input,
|
758
872
|
parser->first_nonspace + matched - parser->offset,
|
759
873
|
false);
|
760
|
-
container =
|
761
|
-
add_child(parser, container, CMARK_NODE_HEADING, parser->offset + 1);
|
874
|
+
*container =
|
875
|
+
add_child(parser, *container, CMARK_NODE_HEADING, parser->offset + 1);
|
762
876
|
|
763
|
-
|
764
|
-
cmark_chunk_strchr(&input, '#', parser->first_nonspace);
|
765
|
-
int level = 0;
|
877
|
+
hashpos = cmark_chunk_strchr(input, '#', parser->first_nonspace);
|
766
878
|
|
767
|
-
while (peek_at(
|
879
|
+
while (peek_at(input, hashpos) == '#') {
|
768
880
|
level++;
|
769
881
|
hashpos++;
|
770
882
|
}
|
771
|
-
container->as.heading.level = level;
|
772
|
-
container->as.heading.setext = false;
|
773
883
|
|
774
|
-
|
775
|
-
|
884
|
+
(*container)->as.heading.level = level;
|
885
|
+
(*container)->as.heading.setext = false;
|
776
886
|
|
777
|
-
|
887
|
+
} else if (!indented && (matched = scan_open_code_fence(
|
888
|
+
input, parser->first_nonspace))) {
|
889
|
+
*container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,
|
778
890
|
parser->first_nonspace + 1);
|
779
|
-
container->as.code.fenced = true;
|
780
|
-
container->as.code.fence_char = peek_at(
|
781
|
-
container->as.code.fence_length = matched;
|
782
|
-
container->as.code.fence_offset =
|
891
|
+
(*container)->as.code.fenced = true;
|
892
|
+
(*container)->as.code.fence_char = peek_at(input, parser->first_nonspace);
|
893
|
+
(*container)->as.code.fence_length = matched;
|
894
|
+
(*container)->as.code.fence_offset =
|
783
895
|
(int8_t)(parser->first_nonspace - parser->offset);
|
784
|
-
container->as.code.info = cmark_chunk_literal("");
|
785
|
-
S_advance_offset(parser,
|
896
|
+
(*container)->as.code.info = cmark_chunk_literal("");
|
897
|
+
S_advance_offset(parser, input,
|
786
898
|
parser->first_nonspace + matched - parser->offset,
|
787
899
|
false);
|
788
900
|
|
789
901
|
} else if (!indented && ((matched = scan_html_block_start(
|
790
|
-
|
791
|
-
(
|
902
|
+
input, parser->first_nonspace)) ||
|
903
|
+
(cont_type != CMARK_NODE_PARAGRAPH &&
|
792
904
|
(matched = scan_html_block_start_7(
|
793
|
-
|
794
|
-
|
795
|
-
container = add_child(parser, container, CMARK_NODE_HTML_BLOCK,
|
905
|
+
input, parser->first_nonspace))))) {
|
906
|
+
*container = add_child(parser, *container, CMARK_NODE_HTML_BLOCK,
|
796
907
|
parser->first_nonspace + 1);
|
797
|
-
container->as.html_block_type = matched;
|
908
|
+
(*container)->as.html_block_type = matched;
|
798
909
|
// note, we don't adjust parser->offset because the tag is part of the
|
799
910
|
// text
|
800
|
-
|
801
|
-
} else if (!indented && container->type == CMARK_NODE_PARAGRAPH &&
|
911
|
+
} else if (!indented && cont_type == CMARK_NODE_PARAGRAPH &&
|
802
912
|
(lev =
|
803
|
-
scan_setext_heading_line(
|
804
|
-
|
805
|
-
container->
|
806
|
-
container->as.heading.
|
807
|
-
|
808
|
-
S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);
|
809
|
-
|
913
|
+
scan_setext_heading_line(input, parser->first_nonspace))) {
|
914
|
+
(*container)->type = CMARK_NODE_HEADING;
|
915
|
+
(*container)->as.heading.level = lev;
|
916
|
+
(*container)->as.heading.setext = true;
|
917
|
+
S_advance_offset(parser, input, input->len - 1 - parser->offset, false);
|
810
918
|
} else if (!indented &&
|
811
|
-
!(
|
919
|
+
!(cont_type == CMARK_NODE_PARAGRAPH && !all_matched) &&
|
812
920
|
(matched =
|
813
|
-
scan_thematic_break(
|
814
|
-
|
921
|
+
scan_thematic_break(input, parser->first_nonspace))) {
|
815
922
|
// it's only now that we know the line is not part of a setext heading:
|
816
|
-
container = add_child(parser, container, CMARK_NODE_THEMATIC_BREAK,
|
923
|
+
*container = add_child(parser, *container, CMARK_NODE_THEMATIC_BREAK,
|
817
924
|
parser->first_nonspace + 1);
|
818
|
-
S_advance_offset(parser,
|
819
|
-
|
925
|
+
S_advance_offset(parser, input, input->len - 1 - parser->offset, false);
|
820
926
|
} else if ((matched =
|
821
|
-
parse_list_marker(
|
822
|
-
(!indented ||
|
927
|
+
parse_list_marker(input, parser->first_nonspace, &data)) &&
|
928
|
+
(!indented || cont_type == CMARK_NODE_LIST)) {
|
823
929
|
// Note that we can have new list items starting with >= 4
|
824
930
|
// spaces indent, as long as the list container is still open.
|
931
|
+
int i = 0;
|
825
932
|
|
826
933
|
// compute padding:
|
827
|
-
S_advance_offset(parser,
|
934
|
+
S_advance_offset(parser, input,
|
828
935
|
parser->first_nonspace + matched - parser->offset,
|
829
936
|
false);
|
830
|
-
|
831
|
-
|
832
|
-
|
937
|
+
|
938
|
+
save_partially_consumed_tab = parser->partially_consumed_tab;
|
939
|
+
save_offset = parser->offset;
|
940
|
+
save_column = parser->column;
|
941
|
+
|
942
|
+
while (parser->column - save_column <= 5 &&
|
943
|
+
S_is_space_or_tab(peek_at(input, parser->offset))) {
|
944
|
+
S_advance_offset(parser, input, 1, true);
|
833
945
|
}
|
834
|
-
|
835
|
-
|
836
|
-
|
946
|
+
|
947
|
+
i = parser->column - save_column;
|
948
|
+
if (i >= 5 || i < 1) {
|
837
949
|
data->padding = matched + 1;
|
950
|
+
parser->offset = save_offset;
|
951
|
+
parser->column = save_column;
|
952
|
+
parser->partially_consumed_tab = save_partially_consumed_tab;
|
838
953
|
if (i > 0) {
|
839
|
-
S_advance_offset(parser,
|
954
|
+
S_advance_offset(parser, input, 1, true);
|
840
955
|
}
|
841
956
|
} else {
|
842
957
|
data->padding = matched + i;
|
843
|
-
S_advance_offset(parser, &input, i, true);
|
844
958
|
}
|
845
959
|
|
846
960
|
// check container; if it's a list, see if this list item
|
@@ -848,50 +962,57 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
|
|
848
962
|
|
849
963
|
data->marker_offset = parser->indent;
|
850
964
|
|
851
|
-
if (
|
852
|
-
!lists_match(&container->as.list, data)) {
|
853
|
-
container = add_child(parser, container, CMARK_NODE_LIST,
|
965
|
+
if (cont_type != CMARK_NODE_LIST ||
|
966
|
+
!lists_match(&((*container)->as.list), data)) {
|
967
|
+
*container = add_child(parser, *container, CMARK_NODE_LIST,
|
854
968
|
parser->first_nonspace + 1);
|
855
969
|
|
856
|
-
memcpy(&container->as.list, data, sizeof(*data));
|
970
|
+
memcpy(&((*container)->as.list), data, sizeof(*data));
|
857
971
|
}
|
858
972
|
|
859
973
|
// add the list item
|
860
|
-
container = add_child(parser, container, CMARK_NODE_ITEM,
|
974
|
+
*container = add_child(parser, *container, CMARK_NODE_ITEM,
|
861
975
|
parser->first_nonspace + 1);
|
862
976
|
/* TODO: static */
|
863
|
-
memcpy(&container->as.list, data, sizeof(*data));
|
977
|
+
memcpy(&((*container)->as.list), data, sizeof(*data));
|
864
978
|
free(data);
|
865
|
-
|
866
979
|
} else if (indented && !maybe_lazy && !parser->blank) {
|
867
|
-
S_advance_offset(parser,
|
868
|
-
container = add_child(parser, container, CMARK_NODE_CODE_BLOCK,
|
980
|
+
S_advance_offset(parser, input, CODE_INDENT, true);
|
981
|
+
*container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,
|
869
982
|
parser->offset + 1);
|
870
|
-
container->as.code.fenced = false;
|
871
|
-
container->as.code.fence_char = 0;
|
872
|
-
container->as.code.fence_length = 0;
|
873
|
-
container->as.code.fence_offset = 0;
|
874
|
-
container->as.code.info = cmark_chunk_literal("");
|
983
|
+
(*container)->as.code.fenced = false;
|
984
|
+
(*container)->as.code.fence_char = 0;
|
985
|
+
(*container)->as.code.fence_length = 0;
|
986
|
+
(*container)->as.code.fence_offset = 0;
|
987
|
+
(*container)->as.code.info = cmark_chunk_literal("");
|
875
988
|
|
876
989
|
} else {
|
877
990
|
break;
|
878
991
|
}
|
879
992
|
|
880
|
-
if (accepts_lines(container->type)) {
|
993
|
+
if (accepts_lines((*container)->type)) {
|
881
994
|
// if it's a line container, it can't contain other containers
|
882
995
|
break;
|
883
996
|
}
|
997
|
+
|
998
|
+
cont_type = (*container)->type;
|
884
999
|
maybe_lazy = false;
|
885
1000
|
}
|
1001
|
+
}
|
886
1002
|
|
1003
|
+
static void add_text_to_container (cmark_parser *parser,
|
1004
|
+
cmark_node *container,
|
1005
|
+
cmark_node *last_matched_container,
|
1006
|
+
cmark_chunk *input)
|
1007
|
+
{
|
1008
|
+
cmark_node *tmp;
|
887
1009
|
// what remains at parser->offset is a text line. add the text to the
|
888
1010
|
// appropriate container.
|
889
1011
|
|
890
|
-
S_find_first_nonspace(parser,
|
1012
|
+
S_find_first_nonspace(parser, input);
|
891
1013
|
|
892
|
-
if (parser->blank && container->last_child)
|
1014
|
+
if (parser->blank && container->last_child)
|
893
1015
|
container->last_child->last_line_blank = true;
|
894
|
-
}
|
895
1016
|
|
896
1017
|
// block quote lines are never blank as they start with >
|
897
1018
|
// and we don't count blanks in fenced code for purposes of tight/loose
|
@@ -906,61 +1027,61 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
|
|
906
1027
|
!(container->type == CMARK_NODE_ITEM && container->first_child == NULL &&
|
907
1028
|
container->start_line == parser->line_number));
|
908
1029
|
|
909
|
-
|
910
|
-
while (
|
911
|
-
|
912
|
-
|
1030
|
+
tmp = container;
|
1031
|
+
while (tmp->parent) {
|
1032
|
+
tmp->parent->last_line_blank = false;
|
1033
|
+
tmp = tmp->parent;
|
913
1034
|
}
|
914
1035
|
|
1036
|
+
// If the last line processed belonged to a paragraph node,
|
1037
|
+
// and we didn't match all of the line prefixes for the open containers,
|
1038
|
+
// and we didn't start any new containers,
|
1039
|
+
// and the line isn't blank,
|
1040
|
+
// then treat this as a "lazy continuation line" and add it to
|
1041
|
+
// the open paragraph.
|
915
1042
|
if (parser->current != last_matched_container &&
|
916
|
-
container == last_matched_container &&
|
917
|
-
parser->
|
918
|
-
|
919
|
-
|
920
|
-
add_line(parser->current, &input, parser->offset);
|
921
|
-
|
1043
|
+
container == last_matched_container &&
|
1044
|
+
!parser->blank &&
|
1045
|
+
parser->current->type == CMARK_NODE_PARAGRAPH) {
|
1046
|
+
add_line(parser->current, input, parser);
|
922
1047
|
} else { // not a lazy continuation
|
923
|
-
|
924
|
-
// finalize any blocks that were not matched and set cur to container:
|
1048
|
+
// Finalize any blocks that were not matched and set cur to container:
|
925
1049
|
while (parser->current != last_matched_container) {
|
926
1050
|
parser->current = finalize(parser, parser->current);
|
927
1051
|
assert(parser->current != NULL);
|
928
1052
|
}
|
929
1053
|
|
930
1054
|
if (container->type == CMARK_NODE_CODE_BLOCK) {
|
931
|
-
|
932
|
-
add_line(container, &input, parser->offset);
|
933
|
-
|
1055
|
+
add_line(container, input, parser);
|
934
1056
|
} else if (container->type == CMARK_NODE_HTML_BLOCK) {
|
935
|
-
|
936
|
-
add_line(container, &input, parser->offset);
|
1057
|
+
add_line(container, input, parser);
|
937
1058
|
|
938
1059
|
int matches_end_condition;
|
939
1060
|
switch (container->as.html_block_type) {
|
940
1061
|
case 1:
|
941
1062
|
// </script>, </style>, </pre>
|
942
1063
|
matches_end_condition =
|
943
|
-
scan_html_block_end_1(
|
1064
|
+
scan_html_block_end_1(input, parser->first_nonspace);
|
944
1065
|
break;
|
945
1066
|
case 2:
|
946
1067
|
// -->
|
947
1068
|
matches_end_condition =
|
948
|
-
scan_html_block_end_2(
|
1069
|
+
scan_html_block_end_2(input, parser->first_nonspace);
|
949
1070
|
break;
|
950
1071
|
case 3:
|
951
1072
|
// ?>
|
952
1073
|
matches_end_condition =
|
953
|
-
scan_html_block_end_3(
|
1074
|
+
scan_html_block_end_3(input, parser->first_nonspace);
|
954
1075
|
break;
|
955
1076
|
case 4:
|
956
1077
|
// >
|
957
1078
|
matches_end_condition =
|
958
|
-
scan_html_block_end_4(
|
1079
|
+
scan_html_block_end_4(input, parser->first_nonspace);
|
959
1080
|
break;
|
960
1081
|
case 5:
|
961
1082
|
// ]]>
|
962
1083
|
matches_end_condition =
|
963
|
-
scan_html_block_end_5(
|
1084
|
+
scan_html_block_end_5(input, parser->first_nonspace);
|
964
1085
|
break;
|
965
1086
|
default:
|
966
1087
|
matches_end_condition = 0;
|
@@ -971,28 +1092,69 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
|
|
971
1092
|
container = finalize(parser, container);
|
972
1093
|
assert(parser->current != NULL);
|
973
1094
|
}
|
974
|
-
|
975
1095
|
} else if (parser->blank) {
|
976
|
-
|
977
1096
|
// ??? do nothing
|
978
|
-
|
979
1097
|
} else if (accepts_lines(container->type)) {
|
980
|
-
|
981
1098
|
if (container->type == CMARK_NODE_HEADING &&
|
982
1099
|
container->as.heading.setext == false) {
|
983
|
-
chop_trailing_hashtags(
|
1100
|
+
chop_trailing_hashtags(input);
|
984
1101
|
}
|
985
|
-
|
986
|
-
|
1102
|
+
S_advance_offset(parser, input, parser->first_nonspace - parser->offset, false);
|
1103
|
+
add_line(container, input, parser);
|
987
1104
|
} else {
|
988
1105
|
// create paragraph container for line
|
989
1106
|
container = add_child(parser, container, CMARK_NODE_PARAGRAPH,
|
990
1107
|
parser->first_nonspace + 1);
|
991
|
-
|
1108
|
+
S_advance_offset(parser, input, parser->first_nonspace - parser->offset, false);
|
1109
|
+
add_line(container, input, parser);
|
992
1110
|
}
|
993
1111
|
|
994
1112
|
parser->current = container;
|
995
1113
|
}
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */
|
1117
|
+
static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
|
1118
|
+
bufsize_t bytes) {
|
1119
|
+
cmark_node *last_matched_container;
|
1120
|
+
bool all_matched = true;
|
1121
|
+
cmark_node *container;
|
1122
|
+
cmark_chunk input;
|
1123
|
+
|
1124
|
+
if (parser->options & CMARK_OPT_VALIDATE_UTF8)
|
1125
|
+
cmark_utf8proc_check(parser->curline, buffer, bytes);
|
1126
|
+
else
|
1127
|
+
cmark_strbuf_put(parser->curline, buffer, bytes);
|
1128
|
+
|
1129
|
+
// ensure line ends with a newline:
|
1130
|
+
if (bytes == 0 || !S_is_line_end_char(parser->curline->ptr[bytes - 1]))
|
1131
|
+
cmark_strbuf_putc(parser->curline, '\n');
|
1132
|
+
|
1133
|
+
parser->offset = 0;
|
1134
|
+
parser->column = 0;
|
1135
|
+
parser->blank = false;
|
1136
|
+
parser->partially_consumed_tab = false;
|
1137
|
+
|
1138
|
+
input.data = parser->curline->ptr;
|
1139
|
+
input.len = parser->curline->size;
|
1140
|
+
|
1141
|
+
parser->line_number++;
|
1142
|
+
|
1143
|
+
last_matched_container = check_open_blocks(parser, &input, &all_matched);
|
1144
|
+
|
1145
|
+
if (!last_matched_container)
|
1146
|
+
goto finished;
|
1147
|
+
|
1148
|
+
container = last_matched_container;
|
1149
|
+
|
1150
|
+
// check to see if we've hit 2nd blank line, break out of list:
|
1151
|
+
if (parser->blank && container->last_line_blank)
|
1152
|
+
break_out_of_lists(parser, &container);
|
1153
|
+
|
1154
|
+
open_new_blocks(parser, &container, &input, all_matched);
|
1155
|
+
|
1156
|
+
add_text_to_container(parser, container, last_matched_container, &input);
|
1157
|
+
|
996
1158
|
finished:
|
997
1159
|
parser->last_line_length = input.len;
|
998
1160
|
if (parser->last_line_length &&
|