A faux parser for fdf files
$begingroup$
Introduction
If you know what FDF files are, you can skip this section.
PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:
A field is represented by
/V ()
/T (Field)
where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.
It is possible for there to be nested fields of arbitrary depth. A basic example is
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (root)
Here there are two fields node1
and node2
both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .
s. For instance name of node1
is root.node1
.
The code
The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field
, root.node1
)
This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.
fdfAnnotate = function(fdfLines){
fields = vector(length = length(fdfLines),mode= 'character')
nests = 0
# iterate over every line
for (i in seq_along(fdfLines)){
if(grepl('/T \(',fdfLines[i])){
# /T represents a field or a root name
# take the name
name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
if(grepl('/V',fdfLines[i-1])){
# if the line before the naming line starts with /V
# there is no hierarhcy, just name the line
fields[i-1] = name
} else if(grepl('>>\]',fdfLines[i-1])){
# if the line above the name is >>] the name represents a root
# start reading from the line above
z = i-2
# this keeps track of the nest levels.
# we will be reading the file backwards trying to
# reach to the end of this root
nest = 1
while(nest!=0){
if(grepl('/V',fdfLines[z])){
# if a field is found, append the name of the root to the left
# separated by a "."
fields[z] = paste0(name,'.',fields[z])
} else if(grepl('>>\]',fdfLines[z])){
# if another nest stops, that means we are inside another root
nest = nest + 1
} else if(grepl('/Kids \[',fdfLines[z])){
# every time a root closes reduce the nest. if you reach 0
# it means its over
nest = nest - 1
}
# go back one line in the file.
z = z - 1
}
}
}
}
data.frame(fdfLines,fields,stringsAsFactors = FALSE)
}
Usage
You can use it by doing
fdfLines = readLines([pathToFDFfile])
fdfAnnotate(fdfLines)
Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.
%FDF-1.2
%âãÏÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (node1)
>>
<<
/Kids [
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (child)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (child2)
>>]
/T (hierarchy2)
>>
<<
/V ()
/T (TextField1)
>>
<<
/V ()
/T (TextField2)
>>
<<
/V ()
/T (TextFieldPage2)
>>
<<
/V ()
/T (List Box)
>>
<<
/V ()
/T (TextFieldPage3)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node4)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (hierarchy)
>>
<<
/V ()
/T (betweenHierarch)
>>
<<
/V /Off
/T (RadioGroup)
>>
<<
/V /Off
/T (checkBox)
>>]
>>
>>
endobj
trailer
<<
/Root 1 0 R
>>
%%EOF
This file represents the form fields in this pdf file.
Using my function, the output is:
fdfLines fields
1 %FDF-1.2
2 %âãÏÓ
3 1 0 obj
4 <<
5 /FDF
6 <<
7 /Fields [
8 <<
9 /V () node1
10 /T (node1)
11 >>
12 <<
13 /Kids [
14 <<
15 /Kids [
16 <<
17 /V () hierarchy2.child.node1
18 /T (node1)
19 >>
20 <<
21 /V () hierarchy2.child.node3
22 /T (node3)
23 >>
24 <<
25 /V () hierarchy2.child.node2
26 /T (node2)
27 >>]
28 /T (child)
29 >>
30 <<
31 /Kids [
32 <<
33 /V () hierarchy2.child2.node1
34 /T (node1)
35 >>
36 <<
37 /V () hierarchy2.child2.node2
38 /T (node2)
39 >>]
40 /T (child2)
41 >>]
42 /T (hierarchy2)
43 >>
44 <<
45 /V () TextField1
46 /T (TextField1)
47 >>
48 <<
49 /V () TextField2
50 /T (TextField2)
51 >>
52 <<
53 /V () TextFieldPage2
54 /T (TextFieldPage2)
55 >>
56 <<
57 /V () List Box
58 /T (List Box)
59 >>
60 <<
61 /V () TextFieldPage3
62 /T (TextFieldPage3)
63 >>
64 <<
65 /Kids [
66 <<
67 /V () hierarchy.node1
68 /T (node1)
69 >>
70 <<
71 /V () hierarchy.node4
72 /T (node4)
73 >>
74 <<
75 /V () hierarchy.node3
76 /T (node3)
77 >>
78 <<
79 /V () hierarchy.node2
80 /T (node2)
81 >>]
82 /T (hierarchy)
83 >>
84 <<
85 /V () betweenHierarch
86 /T (betweenHierarch)
87 >>
88 <<
89 /V /Off RadioGroup
90 /T (RadioGroup)
91 >>
92 <<
93 /V /Off checkBox
94 /T (checkBox)
95 >>]
96 >>
97 >>
98 endobj
99 trailer
100
101 <<
102 /Root 1 0 R
103 >>
104 %%EOF
parsing r
New contributor
$endgroup$
add a comment |
$begingroup$
Introduction
If you know what FDF files are, you can skip this section.
PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:
A field is represented by
/V ()
/T (Field)
where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.
It is possible for there to be nested fields of arbitrary depth. A basic example is
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (root)
Here there are two fields node1
and node2
both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .
s. For instance name of node1
is root.node1
.
The code
The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field
, root.node1
)
This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.
fdfAnnotate = function(fdfLines){
fields = vector(length = length(fdfLines),mode= 'character')
nests = 0
# iterate over every line
for (i in seq_along(fdfLines)){
if(grepl('/T \(',fdfLines[i])){
# /T represents a field or a root name
# take the name
name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
if(grepl('/V',fdfLines[i-1])){
# if the line before the naming line starts with /V
# there is no hierarhcy, just name the line
fields[i-1] = name
} else if(grepl('>>\]',fdfLines[i-1])){
# if the line above the name is >>] the name represents a root
# start reading from the line above
z = i-2
# this keeps track of the nest levels.
# we will be reading the file backwards trying to
# reach to the end of this root
nest = 1
while(nest!=0){
if(grepl('/V',fdfLines[z])){
# if a field is found, append the name of the root to the left
# separated by a "."
fields[z] = paste0(name,'.',fields[z])
} else if(grepl('>>\]',fdfLines[z])){
# if another nest stops, that means we are inside another root
nest = nest + 1
} else if(grepl('/Kids \[',fdfLines[z])){
# every time a root closes reduce the nest. if you reach 0
# it means its over
nest = nest - 1
}
# go back one line in the file.
z = z - 1
}
}
}
}
data.frame(fdfLines,fields,stringsAsFactors = FALSE)
}
Usage
You can use it by doing
fdfLines = readLines([pathToFDFfile])
fdfAnnotate(fdfLines)
Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.
%FDF-1.2
%âãÏÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (node1)
>>
<<
/Kids [
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (child)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (child2)
>>]
/T (hierarchy2)
>>
<<
/V ()
/T (TextField1)
>>
<<
/V ()
/T (TextField2)
>>
<<
/V ()
/T (TextFieldPage2)
>>
<<
/V ()
/T (List Box)
>>
<<
/V ()
/T (TextFieldPage3)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node4)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (hierarchy)
>>
<<
/V ()
/T (betweenHierarch)
>>
<<
/V /Off
/T (RadioGroup)
>>
<<
/V /Off
/T (checkBox)
>>]
>>
>>
endobj
trailer
<<
/Root 1 0 R
>>
%%EOF
This file represents the form fields in this pdf file.
Using my function, the output is:
fdfLines fields
1 %FDF-1.2
2 %âãÏÓ
3 1 0 obj
4 <<
5 /FDF
6 <<
7 /Fields [
8 <<
9 /V () node1
10 /T (node1)
11 >>
12 <<
13 /Kids [
14 <<
15 /Kids [
16 <<
17 /V () hierarchy2.child.node1
18 /T (node1)
19 >>
20 <<
21 /V () hierarchy2.child.node3
22 /T (node3)
23 >>
24 <<
25 /V () hierarchy2.child.node2
26 /T (node2)
27 >>]
28 /T (child)
29 >>
30 <<
31 /Kids [
32 <<
33 /V () hierarchy2.child2.node1
34 /T (node1)
35 >>
36 <<
37 /V () hierarchy2.child2.node2
38 /T (node2)
39 >>]
40 /T (child2)
41 >>]
42 /T (hierarchy2)
43 >>
44 <<
45 /V () TextField1
46 /T (TextField1)
47 >>
48 <<
49 /V () TextField2
50 /T (TextField2)
51 >>
52 <<
53 /V () TextFieldPage2
54 /T (TextFieldPage2)
55 >>
56 <<
57 /V () List Box
58 /T (List Box)
59 >>
60 <<
61 /V () TextFieldPage3
62 /T (TextFieldPage3)
63 >>
64 <<
65 /Kids [
66 <<
67 /V () hierarchy.node1
68 /T (node1)
69 >>
70 <<
71 /V () hierarchy.node4
72 /T (node4)
73 >>
74 <<
75 /V () hierarchy.node3
76 /T (node3)
77 >>
78 <<
79 /V () hierarchy.node2
80 /T (node2)
81 >>]
82 /T (hierarchy)
83 >>
84 <<
85 /V () betweenHierarch
86 /T (betweenHierarch)
87 >>
88 <<
89 /V /Off RadioGroup
90 /T (RadioGroup)
91 >>
92 <<
93 /V /Off checkBox
94 /T (checkBox)
95 >>]
96 >>
97 >>
98 endobj
99 trailer
100
101 <<
102 /Root 1 0 R
103 >>
104 %%EOF
parsing r
New contributor
$endgroup$
add a comment |
$begingroup$
Introduction
If you know what FDF files are, you can skip this section.
PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:
A field is represented by
/V ()
/T (Field)
where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.
It is possible for there to be nested fields of arbitrary depth. A basic example is
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (root)
Here there are two fields node1
and node2
both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .
s. For instance name of node1
is root.node1
.
The code
The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field
, root.node1
)
This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.
fdfAnnotate = function(fdfLines){
fields = vector(length = length(fdfLines),mode= 'character')
nests = 0
# iterate over every line
for (i in seq_along(fdfLines)){
if(grepl('/T \(',fdfLines[i])){
# /T represents a field or a root name
# take the name
name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
if(grepl('/V',fdfLines[i-1])){
# if the line before the naming line starts with /V
# there is no hierarhcy, just name the line
fields[i-1] = name
} else if(grepl('>>\]',fdfLines[i-1])){
# if the line above the name is >>] the name represents a root
# start reading from the line above
z = i-2
# this keeps track of the nest levels.
# we will be reading the file backwards trying to
# reach to the end of this root
nest = 1
while(nest!=0){
if(grepl('/V',fdfLines[z])){
# if a field is found, append the name of the root to the left
# separated by a "."
fields[z] = paste0(name,'.',fields[z])
} else if(grepl('>>\]',fdfLines[z])){
# if another nest stops, that means we are inside another root
nest = nest + 1
} else if(grepl('/Kids \[',fdfLines[z])){
# every time a root closes reduce the nest. if you reach 0
# it means its over
nest = nest - 1
}
# go back one line in the file.
z = z - 1
}
}
}
}
data.frame(fdfLines,fields,stringsAsFactors = FALSE)
}
Usage
You can use it by doing
fdfLines = readLines([pathToFDFfile])
fdfAnnotate(fdfLines)
Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.
%FDF-1.2
%âãÏÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (node1)
>>
<<
/Kids [
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (child)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (child2)
>>]
/T (hierarchy2)
>>
<<
/V ()
/T (TextField1)
>>
<<
/V ()
/T (TextField2)
>>
<<
/V ()
/T (TextFieldPage2)
>>
<<
/V ()
/T (List Box)
>>
<<
/V ()
/T (TextFieldPage3)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node4)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (hierarchy)
>>
<<
/V ()
/T (betweenHierarch)
>>
<<
/V /Off
/T (RadioGroup)
>>
<<
/V /Off
/T (checkBox)
>>]
>>
>>
endobj
trailer
<<
/Root 1 0 R
>>
%%EOF
This file represents the form fields in this pdf file.
Using my function, the output is:
fdfLines fields
1 %FDF-1.2
2 %âãÏÓ
3 1 0 obj
4 <<
5 /FDF
6 <<
7 /Fields [
8 <<
9 /V () node1
10 /T (node1)
11 >>
12 <<
13 /Kids [
14 <<
15 /Kids [
16 <<
17 /V () hierarchy2.child.node1
18 /T (node1)
19 >>
20 <<
21 /V () hierarchy2.child.node3
22 /T (node3)
23 >>
24 <<
25 /V () hierarchy2.child.node2
26 /T (node2)
27 >>]
28 /T (child)
29 >>
30 <<
31 /Kids [
32 <<
33 /V () hierarchy2.child2.node1
34 /T (node1)
35 >>
36 <<
37 /V () hierarchy2.child2.node2
38 /T (node2)
39 >>]
40 /T (child2)
41 >>]
42 /T (hierarchy2)
43 >>
44 <<
45 /V () TextField1
46 /T (TextField1)
47 >>
48 <<
49 /V () TextField2
50 /T (TextField2)
51 >>
52 <<
53 /V () TextFieldPage2
54 /T (TextFieldPage2)
55 >>
56 <<
57 /V () List Box
58 /T (List Box)
59 >>
60 <<
61 /V () TextFieldPage3
62 /T (TextFieldPage3)
63 >>
64 <<
65 /Kids [
66 <<
67 /V () hierarchy.node1
68 /T (node1)
69 >>
70 <<
71 /V () hierarchy.node4
72 /T (node4)
73 >>
74 <<
75 /V () hierarchy.node3
76 /T (node3)
77 >>
78 <<
79 /V () hierarchy.node2
80 /T (node2)
81 >>]
82 /T (hierarchy)
83 >>
84 <<
85 /V () betweenHierarch
86 /T (betweenHierarch)
87 >>
88 <<
89 /V /Off RadioGroup
90 /T (RadioGroup)
91 >>
92 <<
93 /V /Off checkBox
94 /T (checkBox)
95 >>]
96 >>
97 >>
98 endobj
99 trailer
100
101 <<
102 /Root 1 0 R
103 >>
104 %%EOF
parsing r
New contributor
$endgroup$
Introduction
If you know what FDF files are, you can skip this section.
PDF files sometimes includes form fields. These fields can be represented as FDF in plain text form, extracted using certain utilities. Important things to note about this file are:
A field is represented by
/V ()
/T (Field)
where "Field" is the field name and whatever is written within the parenthesis next to /V will become the input for the utility that will fill the form.
It is possible for there to be nested fields of arbitrary depth. A basic example is
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (root)
Here there are two fields node1
and node2
both nested under root. When fields are nested, names that are seen by a user are the components of the hierarchy, separated by .
s. For instance name of node1
is root.node1
.
The code
The big picture goal of this is to identify the lines that need to be modified when a user provides a bunch of field names (eg. Field
, root.node1
)
This code reads the FDF file and marks the lines that should be modified to fill a field of a given name. The way I do it involves iterating every line to detect the tree roots and append the name of the roots to every child. Since this will end up in CRAN I want to make sure the approach isn't overly convoluted.
fdfAnnotate = function(fdfLines){
fields = vector(length = length(fdfLines),mode= 'character')
nests = 0
# iterate over every line
for (i in seq_along(fdfLines)){
if(grepl('/T \(',fdfLines[i])){
# /T represents a field or a root name
# take the name
name = stringr::str_extract(fdfLines[i],'(?<=\().*?(?=\))')
if(grepl('/V',fdfLines[i-1])){
# if the line before the naming line starts with /V
# there is no hierarhcy, just name the line
fields[i-1] = name
} else if(grepl('>>\]',fdfLines[i-1])){
# if the line above the name is >>] the name represents a root
# start reading from the line above
z = i-2
# this keeps track of the nest levels.
# we will be reading the file backwards trying to
# reach to the end of this root
nest = 1
while(nest!=0){
if(grepl('/V',fdfLines[z])){
# if a field is found, append the name of the root to the left
# separated by a "."
fields[z] = paste0(name,'.',fields[z])
} else if(grepl('>>\]',fdfLines[z])){
# if another nest stops, that means we are inside another root
nest = nest + 1
} else if(grepl('/Kids \[',fdfLines[z])){
# every time a root closes reduce the nest. if you reach 0
# it means its over
nest = nest - 1
}
# go back one line in the file.
z = z - 1
}
}
}
}
data.frame(fdfLines,fields,stringsAsFactors = FALSE)
}
Usage
You can use it by doing
fdfLines = readLines([pathToFDFfile])
fdfAnnotate(fdfLines)
Below is the FDF file I use for my tests. It includes single and double layered hierarchies as well as a bunch of normal fields.
%FDF-1.2
%âãÏÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (node1)
>>
<<
/Kids [
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (child)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node2)
>>]
/T (child2)
>>]
/T (hierarchy2)
>>
<<
/V ()
/T (TextField1)
>>
<<
/V ()
/T (TextField2)
>>
<<
/V ()
/T (TextFieldPage2)
>>
<<
/V ()
/T (List Box)
>>
<<
/V ()
/T (TextFieldPage3)
>>
<<
/Kids [
<<
/V ()
/T (node1)
>>
<<
/V ()
/T (node4)
>>
<<
/V ()
/T (node3)
>>
<<
/V ()
/T (node2)
>>]
/T (hierarchy)
>>
<<
/V ()
/T (betweenHierarch)
>>
<<
/V /Off
/T (RadioGroup)
>>
<<
/V /Off
/T (checkBox)
>>]
>>
>>
endobj
trailer
<<
/Root 1 0 R
>>
%%EOF
This file represents the form fields in this pdf file.
Using my function, the output is:
fdfLines fields
1 %FDF-1.2
2 %âãÏÓ
3 1 0 obj
4 <<
5 /FDF
6 <<
7 /Fields [
8 <<
9 /V () node1
10 /T (node1)
11 >>
12 <<
13 /Kids [
14 <<
15 /Kids [
16 <<
17 /V () hierarchy2.child.node1
18 /T (node1)
19 >>
20 <<
21 /V () hierarchy2.child.node3
22 /T (node3)
23 >>
24 <<
25 /V () hierarchy2.child.node2
26 /T (node2)
27 >>]
28 /T (child)
29 >>
30 <<
31 /Kids [
32 <<
33 /V () hierarchy2.child2.node1
34 /T (node1)
35 >>
36 <<
37 /V () hierarchy2.child2.node2
38 /T (node2)
39 >>]
40 /T (child2)
41 >>]
42 /T (hierarchy2)
43 >>
44 <<
45 /V () TextField1
46 /T (TextField1)
47 >>
48 <<
49 /V () TextField2
50 /T (TextField2)
51 >>
52 <<
53 /V () TextFieldPage2
54 /T (TextFieldPage2)
55 >>
56 <<
57 /V () List Box
58 /T (List Box)
59 >>
60 <<
61 /V () TextFieldPage3
62 /T (TextFieldPage3)
63 >>
64 <<
65 /Kids [
66 <<
67 /V () hierarchy.node1
68 /T (node1)
69 >>
70 <<
71 /V () hierarchy.node4
72 /T (node4)
73 >>
74 <<
75 /V () hierarchy.node3
76 /T (node3)
77 >>
78 <<
79 /V () hierarchy.node2
80 /T (node2)
81 >>]
82 /T (hierarchy)
83 >>
84 <<
85 /V () betweenHierarch
86 /T (betweenHierarch)
87 >>
88 <<
89 /V /Off RadioGroup
90 /T (RadioGroup)
91 >>
92 <<
93 /V /Off checkBox
94 /T (checkBox)
95 >>]
96 >>
97 >>
98 endobj
99 trailer
100
101 <<
102 /Root 1 0 R
103 >>
104 %%EOF
parsing r
parsing r
New contributor
New contributor
New contributor
asked 9 mins ago
OganMOganM
1012
1012
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
OganM is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212118%2fa-faux-parser-for-fdf-files%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
OganM is a new contributor. Be nice, and check out our Code of Conduct.
OganM is a new contributor. Be nice, and check out our Code of Conduct.
OganM is a new contributor. Be nice, and check out our Code of Conduct.
OganM is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212118%2fa-faux-parser-for-fdf-files%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown